add page cache with read-ahead and dirty writeback, file-backed and anonymous mmap with CoW, VAD-based virtual memory replacing the old user region model, PFN database with eviction and reclaim, file identity for cross-open section sharing, FAT32 path cache and per-file cluster chain cache, serial.sys for COM1 keyboard input, xHCI MSI with INTx and polled fallback, PciEnableMsiAuto, waitable input queue, KeWaitForAnyEvent, per-process thread info syscall, expanded kernel stats (PFN/PTE/VAD/file-cache/disk), pool allocation tags, async I/O user buffer locking, file flush on close, add docs.md.
This commit is contained in:
1 parent
61ec2442eb
commit
2c4a68a75f
114 files changed
+18069
-2620
No files matched your search
@@ -72,12 +72,27 @@ extern int errno; // defined in posix_fd.c; single global in v1
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
// mmap() protection and mapping flags.
|
||||
#define PROT_NONE 0x0
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define PROT_EXEC 0x4
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FAILED ((void*)(intptr_t)-1)
|
||||
#define MS_SYNC 0x04
|
||||
#define MS_ASYNC 0x01
|
||||
#define MS_INVALIDATE 0x02
|
||||
|
||||
// Scalar types.
|
||||
typedef int32_t pid_t;
|
||||
typedef int32_t off_t;
|
||||
typedef uint32_t mode_t;
|
||||
typedef int64_t ssize_t;
|
||||
|
||||
__declspec(dllexport) void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
__declspec(dllexport) int munmap(void* addr, size_t length);
|
||||
__declspec(dllexport) int msync(void* addr, size_t length, int flags);
|
||||
|
||||
// Sockets.
|
||||
typedef uint16_t sa_family_t;
|
||||
@@ -188,7 +203,7 @@ __declspec(dllexport) int getaddrinfo(const char* node, const char* service, con
|
||||
__declspec(dllexport) void freeaddrinfo(struct addrinfo* res);
|
||||
|
||||
// pthread types.
|
||||
typedef struct { uint32_t Tid; } pthread_t;
|
||||
typedef struct { uint32_t Handle; uint32_t Tid; } pthread_t;
|
||||
typedef struct { uint32_t Handle; } pthread_mutex_t;
|
||||
typedef void* pthread_attr_t; // unused in v1
|
||||
typedef void* pthread_mutexattr_t;
|
||||
|
||||
@@ -81,7 +81,8 @@ __declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) {
|
||||
return (ssize_t)count;
|
||||
case FD_FILE: {
|
||||
size_t got = 0;
|
||||
uint32_t s = SysReadFile(e->KHandle, buf, count, &got);
|
||||
SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(e->KHandle, buf, count, &got);
|
||||
uint32_t s = SysReadFile(&req);
|
||||
if (s != 0 && got == 0) { errno = PosixStatusToErrno(s); return -1; }
|
||||
return (ssize_t)got;
|
||||
}
|
||||
@@ -115,7 +116,8 @@ __declspec(dllexport) ssize_t write(int fd, const void* buf, size_t count) {
|
||||
return (ssize_t)count;
|
||||
case FD_FILE: {
|
||||
size_t written = 0;
|
||||
uint32_t s = SysWriteFile(e->KHandle, buf, count, &written);
|
||||
SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(e->KHandle, buf, count, &written);
|
||||
uint32_t s = SysWriteFile(&req);
|
||||
if (s != 0 && written == 0) { errno = PosixStatusToErrno(s); return -1; }
|
||||
return (ssize_t)written;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
// POSIX compatibility support for mmap-style file mappings.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include "posix.h"
|
||||
#include "posix_fd.h"
|
||||
|
||||
static uint32_t PosixProtToSysMapAccess(int prot, int flags) {
|
||||
uint32_t access = 0;
|
||||
if (prot & PROT_EXEC) access |= SYS_MAP_ACCESS_EXECUTE;
|
||||
if (prot & PROT_WRITE) {
|
||||
access |= (flags & MAP_SHARED) ? SYS_MAP_ACCESS_WRITE : SYS_MAP_ACCESS_COPY;
|
||||
} else if (flags & MAP_PRIVATE) {
|
||||
access |= SYS_MAP_ACCESS_COPY;
|
||||
}
|
||||
if (prot & PROT_READ) access |= SYS_MAP_ACCESS_READ;
|
||||
if (!access) access = SYS_MAP_ACCESS_READ;
|
||||
return access;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void* mmap(void* addr, size_t length, int prot,
|
||||
int flags, int fd, off_t offset) {
|
||||
if (addr || length == 0 || offset < 0 || ((uint64_t)offset & 0xFFFu)) {
|
||||
errno = EINVAL;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
if (!(flags & MAP_PRIVATE) && !(flags & MAP_SHARED)) {
|
||||
errno = EINVAL;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
FD_ENTRY* e = FdGet(pid, fd);
|
||||
if (!e) return MAP_FAILED;
|
||||
if (e->Type != FD_FILE) {
|
||||
errno = EBADF;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
uint64_t maxSize = (uint64_t)offset + (uint64_t)length;
|
||||
if (maxSize < (uint64_t)offset) {
|
||||
errno = EINVAL;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
uint32_t protect = (prot & PROT_WRITE) ? SYS_VM_READWRITE : SYS_VM_READ;
|
||||
if (prot & PROT_EXEC)
|
||||
protect = (prot & PROT_WRITE) ? SYS_VM_EXECUTE_READWRITE : SYS_VM_EXECUTE_READ;
|
||||
|
||||
uint32_t mapping = 0;
|
||||
uint32_t s = SysCreateFileMapping(e->KHandle, protect, SYS_MAP_FLAG_NONE,
|
||||
maxSize, &mapping);
|
||||
if (s != SYS_STATUS_SUCCESS) {
|
||||
errno = PosixStatusToErrno(s);
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
void* base = (void*)0;
|
||||
s = SysMapFile(mapping, (uint64_t)offset, length,
|
||||
PosixProtToSysMapAccess(prot, flags),
|
||||
SYS_MAP_FLAG_NONE, &base);
|
||||
SysCloseHandle(mapping);
|
||||
if (s != SYS_STATUS_SUCCESS) {
|
||||
errno = PosixStatusToErrno(s);
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
__declspec(dllexport) int munmap(void* addr, size_t length) {
|
||||
(void)length;
|
||||
if (!addr) { errno = EINVAL; return -1; }
|
||||
uint32_t s = SysFreeVm(addr);
|
||||
if (s != SYS_STATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
__declspec(dllexport) int msync(void* addr, size_t length, int flags) {
|
||||
(void)addr;
|
||||
(void)length;
|
||||
(void)flags;
|
||||
return 0;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ __declspec(dllexport) pid_t waitpid(pid_t pid, int* status, int options) {
|
||||
uint32_t handle = ProcTableFind(pid);
|
||||
if (!handle) { errno = ESRCH; return -1; }
|
||||
|
||||
SysWaitForProcess(handle);
|
||||
SysWait(handle, SYS_WAIT_FLAG_NONE);
|
||||
|
||||
int exitCode = 0;
|
||||
SysGetProcessExitCode(handle, &exitCode);
|
||||
|
||||
@@ -84,28 +84,41 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
tr->Pid = pid;
|
||||
|
||||
uint32_t tid = 0;
|
||||
uint32_t s = SysCreateThread((uint64_t)PthreadTrampoline,
|
||||
(uint64_t)tr, 1, &tid);
|
||||
uint32_t handle = 0;
|
||||
SYS_CREATE_THREAD_REQUEST req = {
|
||||
(uintptr_t)PthreadTrampoline,
|
||||
(uintptr_t)tr,
|
||||
1,
|
||||
0,
|
||||
&handle,
|
||||
&tid
|
||||
};
|
||||
uint32_t s = SysCreateThread(&req);
|
||||
if (s != 0) {
|
||||
free(tr);
|
||||
return EAGAIN;
|
||||
}
|
||||
// The trampoline allocates the retval slot itself after it knows its real
|
||||
// TID, avoiding the creator/new-thread race.
|
||||
if (t) t->Tid = tid;
|
||||
if (t) {
|
||||
t->Handle = handle;
|
||||
t->Tid = tid;
|
||||
} else {
|
||||
SysCloseHandle(handle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the pthread join operation.
|
||||
__declspec(dllexport) int pthread_join(pthread_t t, void** retval) {
|
||||
uint32_t pid = SysGetCurrentPid();
|
||||
uint32_t s = SysWaitThread(t.Tid);
|
||||
// STATUS_NOT_FOUND (0x22) means already dead - treat as success.
|
||||
if (s != 0 && s != 0x0022) return ESRCH;
|
||||
uint32_t s = SysWait(t.Handle, SYS_WAIT_FLAG_NONE);
|
||||
if (s != 0) return ESRCH;
|
||||
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, t.Tid);
|
||||
if (retval) *retval = slot ? slot->RetVal : (void*)0;
|
||||
if (slot) slot->Used = false;
|
||||
SysCloseHandle(t.Handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,7 +151,7 @@ __declspec(dllexport) int pthread_mutex_destroy(pthread_mutex_t* m) {
|
||||
|
||||
// Implements the pthread mutex lock operation.
|
||||
__declspec(dllexport) int pthread_mutex_lock(pthread_mutex_t* m) {
|
||||
uint32_t s = SysAcquireMutex(m->Handle);
|
||||
uint32_t s = SysWait(m->Handle, SYS_WAIT_FLAG_NONE);
|
||||
return s == 0 ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user