add a realtime scheduler class and priority-inheritance mutexes with timeouts and abandonment, add an HDA audio driver and a SYS_AUDIO_* syscall family, flesh out kernel32 with Win32 threads, events, mutexes, critical sections, and condition variables, add SYS_RESUME_THREAD for suspended thread creation, add KeInitializeMemoryTypes to reprogram MTRRs and install a canonical PAT for WB/WC/UC control, rework the display pipeline with a pitched present path and console output flush, bring back disk.vhd with mtools since vvfat fucking sucks, harden AHCI with serialized cache flush, USB mass storage with SCSI sense-data decoding, and xHCI with cleaner DMA teardown, fix the last stray for(;;) in HalStopProcessor to while(true), pile on smoke tests for audio, win32 sync primitives, and thread suspend, implement AHCI timeout, kill readahead since it was desperetaly trying to murder me, fix doom sound x2.
This commit is contained in:
1 parent
8b254f84f4
commit
4add6789ba
177 files changed
+22565
-3070
No files matched your search
@@ -0,0 +1,147 @@
|
||||
// Win32 recursive mutex smoke test for Bink worker teardown.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef DWORD (__stdcall *THREAD_START_ROUTINE)(void* parameter);
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define INFINITE 0xFFFFFFFFu
|
||||
#define WAIT_OBJECT_0 0u
|
||||
#define WAIT_TIMEOUT 0x00000102u
|
||||
#define WAIT_FAILED 0xFFFFFFFFu
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)(intptr_t)-1)
|
||||
|
||||
__declspec(dllimport) HANDLE CreateMutexA(void* attributes, BOOL initialOwner, const char* name);
|
||||
__declspec(dllimport) BOOL ReleaseMutex(HANDLE mutex);
|
||||
__declspec(dllimport) HANDLE CreateThread(void* attributes,
|
||||
size_t stackSize,
|
||||
THREAD_START_ROUTINE startRoutine,
|
||||
void* parameter,
|
||||
DWORD creationFlags,
|
||||
DWORD* threadId);
|
||||
__declspec(dllimport) DWORD WaitForSingleObject(HANDLE handle, DWORD milliseconds);
|
||||
__declspec(dllimport) BOOL CloseHandle(HANDLE handle);
|
||||
__declspec(dllimport) DWORD GetLastError(void);
|
||||
|
||||
static HANDLE gMutex;
|
||||
static DWORD gWorkerWait;
|
||||
static DWORD gWorkerError;
|
||||
static BOOL gWorkerRelease;
|
||||
|
||||
// Writes one test message to the native console.
|
||||
static void print(const char* text) {
|
||||
SYS_WRITE_CONSOLE_REQUEST request = { SysSvFromCstr(text) };
|
||||
(void)SysWriteConsole(&request);
|
||||
}
|
||||
|
||||
// Terminates the test after one contract failure.
|
||||
static void fail(const char* message) {
|
||||
print("win32_mutex_smoke: ");
|
||||
print(message);
|
||||
print("\n");
|
||||
while (true) (void)SysExitProcess(1);
|
||||
}
|
||||
|
||||
// Writes one fixed-width hexadecimal value to the native console.
|
||||
static void print_hex32(DWORD value) {
|
||||
static const char digits[] = "0123456789ABCDEF";
|
||||
char text[] = "0x00000000";
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
text[9 - i] = digits[value & 0xFu];
|
||||
value >>= 4;
|
||||
}
|
||||
print(text);
|
||||
}
|
||||
|
||||
// Reports a failed worker wait with both Win32 result channels.
|
||||
static void fail_worker_wait(const char* message) {
|
||||
print("win32_mutex_smoke: ");
|
||||
print(message);
|
||||
print(" result=");
|
||||
print_hex32(gWorkerWait);
|
||||
print(" error=");
|
||||
print_hex32(gWorkerError);
|
||||
print("\n");
|
||||
while (true) (void)SysExitProcess(1);
|
||||
}
|
||||
|
||||
// Attempts one wait and releases the mutex only after successful acquisition.
|
||||
static DWORD __stdcall mutex_worker(void* parameter) {
|
||||
DWORD timeout = (DWORD)(uintptr_t)parameter;
|
||||
gWorkerWait = WaitForSingleObject(gMutex, timeout);
|
||||
gWorkerError = gWorkerWait == WAIT_FAILED ? GetLastError() : 0;
|
||||
if (gWorkerWait == WAIT_OBJECT_0)
|
||||
gWorkerRelease = ReleaseMutex(gMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs one worker and waits for its normal return.
|
||||
static void run_worker(DWORD timeout) {
|
||||
gWorkerWait = 0xFFFFFFFFu;
|
||||
gWorkerError = 0;
|
||||
gWorkerRelease = FALSE;
|
||||
HANDLE worker = CreateThread(NULL, 0, mutex_worker,
|
||||
(void*)(uintptr_t)timeout, 0, NULL);
|
||||
if (!worker || worker == INVALID_HANDLE_VALUE)
|
||||
fail("CreateThread failed");
|
||||
if (WaitForSingleObject(worker, 5000u) != WAIT_OBJECT_0)
|
||||
fail("worker did not return");
|
||||
if (!CloseHandle(worker))
|
||||
fail("worker CloseHandle failed");
|
||||
}
|
||||
|
||||
// Verifies recursive ownership, non-owner safety, and final release transfer.
|
||||
int main(void) {
|
||||
print("win32_mutex_smoke: begin\n");
|
||||
gMutex = CreateMutexA(NULL, FALSE, NULL);
|
||||
if (!gMutex || gMutex == INVALID_HANDLE_VALUE)
|
||||
fail("CreateMutexA failed");
|
||||
|
||||
if (WaitForSingleObject(gMutex, INFINITE) != WAIT_OBJECT_0 ||
|
||||
WaitForSingleObject(gMutex, INFINITE) != WAIT_OBJECT_0)
|
||||
fail("recursive acquisition failed");
|
||||
|
||||
run_worker(25u);
|
||||
if (gWorkerWait == WAIT_FAILED)
|
||||
fail_worker_wait("doubly-owned finite wait failed");
|
||||
if (gWorkerWait != WAIT_TIMEOUT || gWorkerRelease)
|
||||
fail("worker acquired doubly-owned mutex");
|
||||
|
||||
if (!ReleaseMutex(gMutex))
|
||||
fail("first recursive release failed");
|
||||
run_worker(25u);
|
||||
if (gWorkerWait == WAIT_FAILED)
|
||||
fail_worker_wait("singly-owned finite wait failed");
|
||||
if (gWorkerWait != WAIT_TIMEOUT || gWorkerRelease)
|
||||
fail("worker acquired singly-owned mutex");
|
||||
|
||||
if (!ReleaseMutex(gMutex))
|
||||
fail("final recursive release failed");
|
||||
run_worker(1000u);
|
||||
if (gWorkerWait == WAIT_FAILED)
|
||||
fail_worker_wait("released finite wait failed");
|
||||
if (gWorkerWait != WAIT_OBJECT_0 || !gWorkerRelease)
|
||||
fail("worker did not acquire released mutex");
|
||||
|
||||
if (!CloseHandle(gMutex))
|
||||
fail("mutex CloseHandle failed");
|
||||
|
||||
gMutex = CreateMutexA(NULL, TRUE, NULL);
|
||||
if (!gMutex || gMutex == INVALID_HANDLE_VALUE)
|
||||
fail("initial-owner mutex failed");
|
||||
if (WaitForSingleObject(gMutex, INFINITE) != WAIT_OBJECT_0)
|
||||
fail("initial-owner recursion failed");
|
||||
if (!ReleaseMutex(gMutex) || !ReleaseMutex(gMutex))
|
||||
fail("initial-owner release failed");
|
||||
if (!CloseHandle(gMutex))
|
||||
fail("initial-owner close failed");
|
||||
|
||||
print("win32_mutex_smoke: PASS\n");
|
||||
while (true) (void)SysExitProcess(0);
|
||||
}
|
||||
Reference in new issue
Block a user