// Native surface multithreaded present test. // Multiple user threads present one process-private surface to catch mapping and scratch-buffer races. #include #include #include #include #define SURFACE_W 96u #define SURFACE_H 64u #define THREAD_COUNT 4u #define ITERATIONS 32u typedef struct WORKER_STATE { uint32_t Index; uint32_t Surface; uint8_t* Base; uint32_t Pitch; uint32_t Status; uint32_t IterationsDone; } WORKER_STATE; static WORKER_STATE gWorkers[THREAD_COUNT]; static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); } static void print_u64(uint64_t v) { char buf[32]; int i = 0; if (v == 0) { print("0"); return; } while (v && i < (int)sizeof(buf)) { buf[i++] = (char)('0' + (v % 10)); v /= 10; } while (i--) { char c = buf[i]; SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) }; SysWriteConsole(&req); } } static void exit_now(int code) { while (true) SysExitProcess(code); } static void fail(const char* msg) { print("surface_multithread_present: "); print(msg); print("\n"); exit_now(1); } static void fail_status(const char* what, uint32_t status) { print("surface_multithread_present: "); print(what); print(" failed status="); print_u64(status); print("\n"); exit_now(1); } static void worker_main(uintptr_t arg) { WORKER_STATE* st = (WORKER_STATE*)arg; if (!st) SysExitThread(1); uint32_t bandHeight = SURFACE_H / THREAD_COUNT; uint32_t y0 = st->Index * bandHeight; uint32_t h = bandHeight; if (st->Index == THREAD_COUNT - 1) h = SURFACE_H - y0; for (uint32_t iter = 0; iter < ITERATIONS; ++iter) { for (uint32_t y = 0; y < h; ++y) { uint32_t* row = (uint32_t*)(st->Base + (size_t)(y0 + y) * st->Pitch); for (uint32_t x = 0; x < SURFACE_W; ++x) row[x] = 0x00010101u * ((st->Index + 1u) * 32u + (iter & 31u)); } DISPLAY_RECT rect = { 0, (int32_t)y0, (int32_t)SURFACE_W, (int32_t)h }; uint32_t s = SysPresentSurface(st->Surface, &rect, 1); if (s != NTLSTATUS_SUCCESS) { st->Status = s; SysExitThread(1); } st->IterationsDone++; SysYield(); } st->Status = NTLSTATUS_SUCCESS; SysExitThread(0); } int main(void) { print("surface_multithread_present: start\n"); uint32_t surface = 0; SYS_CREATE_SURFACE_REQUEST req; memset(&req, 0, sizeof(req)); req.Size = sizeof(req); req.Width = SURFACE_W; req.Height = SURFACE_H; req.Format = SYS_SURFACE_FORMAT_XRGB8888; req.Flags = SYS_SURFACE_FLAG_NONE; req.HandleOut = &surface; uint32_t s = SysCreateSurface(&req); if (s != NTLSTATUS_SUCCESS) fail_status("create surface", s); void* base = 0; uint32_t pitch = 0; s = SysMapSurface(surface, &base, &pitch); if (s != NTLSTATUS_SUCCESS) fail_status("map surface", s); if (!base || pitch < SURFACE_W * sizeof(uint32_t)) fail("invalid mapping"); uint32_t handles[THREAD_COUNT]; uint32_t tids[THREAD_COUNT]; memset(handles, 0, sizeof(handles)); memset(tids, 0, sizeof(tids)); memset(gWorkers, 0, sizeof(gWorkers)); for (uint32_t i = 0; i < THREAD_COUNT; ++i) { gWorkers[i].Index = i; gWorkers[i].Surface = surface; gWorkers[i].Base = (uint8_t*)base; gWorkers[i].Pitch = pitch; gWorkers[i].Status = NTLSTATUS_PENDING; SYS_CREATE_THREAD_REQUEST req = { (uintptr_t)worker_main, (uintptr_t)&gWorkers[i], 1, 0, &handles[i], &tids[i] }; s = SysCreateThread(&req); if (s != NTLSTATUS_SUCCESS) fail_status("create thread", s); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { s = SysWait(handles[i], SYS_WAIT_FLAG_NONE); if (s != NTLSTATUS_SUCCESS) fail_status("wait thread", s); SysCloseHandle(handles[i]); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { if (gWorkers[i].Status != NTLSTATUS_SUCCESS) { print("surface_multithread_present: worker "); print_u64(i); print(" status="); print_u64(gWorkers[i].Status); print(" iterations="); print_u64(gWorkers[i].IterationsDone); print("\n"); exit_now(1); } if (gWorkers[i].IterationsDone != ITERATIONS) fail("worker iteration count mismatch"); } SysCloseHandle(surface); print("surface_multithread_present: PASS\n"); exit_now(0); return 0; }