fiber testing
This commit is contained in:
parent
d7f0cb2d5e
commit
f26339ffc3
1
build.c
1
build.c
@ -843,6 +843,7 @@ void OnBuild(StringList cli_args)
|
|||||||
StringBeginsWith(name, Lit("ttf_"))) {
|
StringBeginsWith(name, Lit("ttf_"))) {
|
||||||
if (PlatformWindows) {
|
if (PlatformWindows) {
|
||||||
ignore = !(StringEqual(name, Lit("sys_win32.c")) ||
|
ignore = !(StringEqual(name, Lit("sys_win32.c")) ||
|
||||||
|
StringEqual(name, Lit("sys_win32-old.c")) ||
|
||||||
StringEqual(name, Lit("sock_win32.c")) ||
|
StringEqual(name, Lit("sock_win32.c")) ||
|
||||||
StringEqual(name, Lit("gp_dx12.c")) ||
|
StringEqual(name, Lit("gp_dx12.c")) ||
|
||||||
StringEqual(name, Lit("playback_wasapi.c")) ||
|
StringEqual(name, Lit("playback_wasapi.c")) ||
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#define ARENA_HEADER_SIZE 256
|
#define ARENA_HEADER_SIZE 256
|
||||||
#define ARENA_BLOCK_SIZE 4096
|
#define ARENA_BLOCK_SIZE 16384
|
||||||
|
|
||||||
#define arena_push(a, type) ((type *)arena_push_bytes((a), sizeof(type), alignof(type)))
|
#define arena_push(a, type) ((type *)arena_push_bytes((a), sizeof(type), alignof(type)))
|
||||||
#define arena_push_no_zero(a, type) ((type *)arena_push_bytes_no_zero((a), sizeof(type), alignof(type)))
|
#define arena_push_no_zero(a, type) ((type *)arena_push_bytes_no_zero((a), sizeof(type), alignof(type)))
|
||||||
|
|||||||
@ -80,7 +80,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define DX12_TEST 1
|
|
||||||
|
|
||||||
|
|
||||||
|
#define FIBERS_TEST 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#if DX12_TEST
|
|
||||||
|
|
||||||
#include "gp.h"
|
#include "gp.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
@ -2924,27 +2922,3 @@ INTERNAL SYS_THREAD_DEF(evictor_thread_entry_point, arg)
|
|||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -10,11 +10,12 @@
|
|||||||
#define PROFILING_SYSTEM_TRACE 0
|
#define PROFILING_SYSTEM_TRACE 0
|
||||||
#define PROFILING_CAPTURE_FRAME_IMAGE 0
|
#define PROFILING_CAPTURE_FRAME_IMAGE 0
|
||||||
#define PROFILING_LOCKS 0
|
#define PROFILING_LOCKS 0
|
||||||
#define PROFILING_D3D 1
|
#define PROFILING_D3D 0
|
||||||
#define PROFILING_CMD_WSTR L"tracy-profiler.exe -a 127.0.0.1"
|
#define PROFILING_CMD_WSTR L"tracy-profiler.exe -a 127.0.0.1"
|
||||||
|
|
||||||
/* Tracy defines */
|
/* Tracy defines */
|
||||||
#define TRACY_ENABLE
|
#define TRACY_ENABLE
|
||||||
|
#define TRACY_FIBERS
|
||||||
#if !PROFILING_SYSTEM_TRACE
|
#if !PROFILING_SYSTEM_TRACE
|
||||||
# define TRACY_NO_CALLSTACK
|
# define TRACY_NO_CALLSTACK
|
||||||
# define TRACY_NO_SYSTEM_TRACING
|
# define TRACY_NO_SYSTEM_TRACING
|
||||||
@ -133,4 +134,12 @@ INLINE void __prof_dx12_zone_cleanup_func(TracyCD3D12ZoneCtx *ctx) { ___tracy_d3
|
|||||||
# define __profframeimage(image, width, height, offset, flipped)
|
# define __profframeimage(image, width, height, offset, flipped)
|
||||||
#endif /* PROFILING_CAPTURE_FRAME_IMAGE */
|
#endif /* PROFILING_CAPTURE_FRAME_IMAGE */
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
# define __prof_fiber_enter(fiber_name) ___tracy_fiber_enter(fiber_name)
|
||||||
|
# define __prof_fiber_leave ___tracy_fiber_leave()
|
||||||
|
#else
|
||||||
|
# define __prof_fiber_enter(fiber_name)
|
||||||
|
# define __prof_fiber_leave
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2598
src/sys_win32-old.c
Normal file
2598
src/sys_win32-old.c
Normal file
File diff suppressed because it is too large
Load Diff
305
src/sys_win32.c
305
src/sys_win32.c
@ -1,3 +1,5 @@
|
|||||||
|
#if FIBERS_TEST
|
||||||
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
@ -2336,6 +2338,301 @@ b32 sys_run_command(struct string cmd)
|
|||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Testing
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
#define FIBER_STACK_SIZE MEGABYTE(4)
|
||||||
|
|
||||||
|
#define TJOB_DEF(name, arg) void name(void *arg)
|
||||||
|
typedef TJOB_DEF(tjob_func, arg);
|
||||||
|
|
||||||
|
enum fiber_yield_reason {
|
||||||
|
FIBER_YIELD_REASON_NONE,
|
||||||
|
|
||||||
|
FIBER_YIELD_REASON_SLEEP,
|
||||||
|
|
||||||
|
FIBER_YIELD_REASON_DONE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fiber {
|
||||||
|
const char *name;
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
struct tjob *current_job;
|
||||||
|
|
||||||
|
enum fiber_yield_reason yield_reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tjob {
|
||||||
|
tjob_func *func;
|
||||||
|
void *arg;
|
||||||
|
|
||||||
|
struct tjob *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLOBAL struct {
|
||||||
|
void *runner_fiber_addr;
|
||||||
|
struct fiber f1;
|
||||||
|
|
||||||
|
struct arena *arena;
|
||||||
|
b32 shutdown;
|
||||||
|
struct atomic_i32 lock;
|
||||||
|
struct tjob *first_free_job;
|
||||||
|
struct tjob *first_job;
|
||||||
|
struct tjob *last_job;
|
||||||
|
} g_test;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INTERNAL void atomic_lock(void)
|
||||||
|
{
|
||||||
|
while (atomic_i32_eval_compare_exchange(&g_test.lock, 0, 1) != 0) {
|
||||||
|
ix_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void atomic_unlock(void)
|
||||||
|
{
|
||||||
|
atomic_i32_eval_exchange(&g_test.lock, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void push_job(tjob_func *func, void *arg)
|
||||||
|
{
|
||||||
|
atomic_lock();
|
||||||
|
{
|
||||||
|
struct tjob *job = NULL;
|
||||||
|
if (g_test.first_free_job) {
|
||||||
|
job = g_test.first_free_job;
|
||||||
|
g_test.first_free_job = job->next;
|
||||||
|
} else {
|
||||||
|
job = arena_push_no_zero(g_test.arena, struct tjob);
|
||||||
|
}
|
||||||
|
*job = (struct tjob) { .func = func, .arg = arg };
|
||||||
|
if (g_test.last_job) {
|
||||||
|
g_test.last_job->next = job;
|
||||||
|
} else {
|
||||||
|
g_test.first_job = job;
|
||||||
|
}
|
||||||
|
g_test.last_job = job;
|
||||||
|
}
|
||||||
|
atomic_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INTERNAL void yield(struct fiber *fiber, enum fiber_yield_reason reason)
|
||||||
|
{
|
||||||
|
fiber->yield_reason = reason;
|
||||||
|
__prof_fiber_leave;
|
||||||
|
SwitchToFiber(g_test.runner_fiber_addr);
|
||||||
|
__prof_fiber_enter(fiber->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL TJOB_DEF(test_job, arg)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct fiber *fiber = arg;
|
||||||
|
(UNUSED)fiber;
|
||||||
|
(UNUSED)yield;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
Sleep(50);
|
||||||
|
yield(fiber, FIBER_YIELD_REASON_SLEEP);
|
||||||
|
Sleep(50);
|
||||||
|
#else
|
||||||
|
Sleep(50);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INTERNAL void fiber_proc(void *vfiber)
|
||||||
|
{
|
||||||
|
DEBUGBREAKABLE;
|
||||||
|
struct fiber *fiber = vfiber;
|
||||||
|
(UNUSED)fiber;
|
||||||
|
while (true) {
|
||||||
|
__prof_fiber_enter(fiber->name);
|
||||||
|
{
|
||||||
|
fiber->yield_reason = FIBER_YIELD_REASON_NONE;
|
||||||
|
fiber->current_job->func(fiber->current_job->arg);
|
||||||
|
fiber->yield_reason = FIBER_YIELD_REASON_DONE;
|
||||||
|
}
|
||||||
|
__prof_fiber_leave;
|
||||||
|
SwitchToFiber(g_test.runner_fiber_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct runner_thread_param {
|
||||||
|
i32 id;
|
||||||
|
};
|
||||||
|
|
||||||
|
INTERNAL DWORD WINAPI runner_thread_proc(LPVOID tparam)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct runner_thread_param *param = tparam;
|
||||||
|
struct arena *arena = arena_alloc(GIGABYTE(64));
|
||||||
|
|
||||||
|
/* Set thread name */
|
||||||
|
{
|
||||||
|
struct string id_str = string_from_int(arena, param->id, 10, 1);
|
||||||
|
struct string name = string_format(arena, LIT("Runner thread %F"), FMT_STR(id_str));
|
||||||
|
wchar_t *name_wstr = wstr_from_string(arena, name);
|
||||||
|
SetThreadDescription(GetCurrentThread(), name_wstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_test.runner_fiber_addr = ConvertThreadToFiber(NULL);
|
||||||
|
g_test.f1.name = "Fiber 1";
|
||||||
|
g_test.f1.addr = CreateFiber(FIBER_STACK_SIZE, fiber_proc, &g_test.f1);
|
||||||
|
|
||||||
|
b32 shutdown = false;
|
||||||
|
while (!shutdown) {
|
||||||
|
Sleep(100);
|
||||||
|
struct arena_temp temp = arena_temp_begin(arena);
|
||||||
|
|
||||||
|
atomic_lock();
|
||||||
|
shutdown = g_test.shutdown;
|
||||||
|
if (!shutdown && g_test.first_job) {
|
||||||
|
/* Pull job */
|
||||||
|
struct tjob local_job = ZI;
|
||||||
|
{
|
||||||
|
struct tjob *job = g_test.first_job;
|
||||||
|
local_job = *job;
|
||||||
|
struct tjob *next = job->next;
|
||||||
|
g_test.first_job = next;
|
||||||
|
if (!next) {
|
||||||
|
g_test.last_job = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Run job */
|
||||||
|
atomic_unlock();
|
||||||
|
{
|
||||||
|
__profscope(Run job);
|
||||||
|
struct fiber *fiber = &g_test.f1;
|
||||||
|
fiber->current_job = &local_job;
|
||||||
|
fiber->yield_reason = FIBER_YIELD_REASON_NONE;
|
||||||
|
b32 done = false;
|
||||||
|
while (!done) {
|
||||||
|
SwitchToFiber(fiber->addr);
|
||||||
|
enum fiber_yield_reason yield_reason = fiber->yield_reason;
|
||||||
|
switch (yield_reason) {
|
||||||
|
default: break;
|
||||||
|
|
||||||
|
case FIBER_YIELD_REASON_SLEEP:
|
||||||
|
{
|
||||||
|
__profscope(Sleep);
|
||||||
|
Sleep(100);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FIBER_YIELD_REASON_DONE:
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atomic_lock();
|
||||||
|
}
|
||||||
|
atomic_unlock();
|
||||||
|
arena_temp_end(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_release(arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void test_main(struct string cmdline)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
(UNUSED)cmdline;
|
||||||
|
struct arena *arena = arena_alloc(GIGABYTE(64));
|
||||||
|
{
|
||||||
|
g_test.arena = arena_alloc(GIGABYTE(64));
|
||||||
|
|
||||||
|
Sleep(1000);
|
||||||
|
for (u32 i = 0; i < 50; ++i) {
|
||||||
|
push_job(test_job, &g_test.f1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 num_runners = NUM_RUNNERS;
|
||||||
|
HANDLE *runner_thread_handles = arena_push_array(arena, HANDLE, num_runners);
|
||||||
|
struct runner_thread_param *tparams = arena_push_array(arena, struct runner_thread_param, num_runners);
|
||||||
|
for (u32 i = 0; i < num_runners; ++i) {
|
||||||
|
struct runner_thread_param *tparam = &tparams[i];
|
||||||
|
tparam->id = i;
|
||||||
|
runner_thread_handles[i] = CreateThread(NULL, MEGABYTE(1), runner_thread_proc, tparam, 0, NULL);
|
||||||
|
//SetThreadDescription(GetCurrentThread(), t->thread_name_wstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sys_thread *runner_thread = sys_thread_alloc(runner_thread_entry_point, NULL, LIT("Runner thread"));
|
||||||
|
Sleep(5000);
|
||||||
|
|
||||||
|
{
|
||||||
|
atomic_lock();
|
||||||
|
g_test.shutdown = true;
|
||||||
|
atomic_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < num_runners; ++i) {
|
||||||
|
HANDLE handle = runner_thread_handles[i];
|
||||||
|
DWORD wait_res = WaitForSingleObject(handle, INFINITE);
|
||||||
|
if (wait_res == WAIT_OBJECT_0) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arena_release(arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Entry point
|
* Entry point
|
||||||
@ -2346,7 +2643,12 @@ INTERNAL SYS_THREAD_DEF(win32_app_thread_entry_point, arg)
|
|||||||
(UNUSED)arg;
|
(UNUSED)arg;
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
struct string cmdline_args = string_from_wstr(scratch.arena, G.cmdline_args_wstr, ARRAY_COUNT(G.cmdline_args_wstr));
|
struct string cmdline_args = string_from_wstr(scratch.arena, G.cmdline_args_wstr, ARRAY_COUNT(G.cmdline_args_wstr));
|
||||||
|
#if 0
|
||||||
|
(UNUSED)test_main;
|
||||||
app_entry_point(cmdline_args);
|
app_entry_point(cmdline_args);
|
||||||
|
#else
|
||||||
|
test_main(cmdline_args);
|
||||||
|
#endif
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2592,3 +2894,6 @@ void __stdcall wWinMainCRTStartup(void)
|
|||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
#endif /* !CRTLIB */
|
#endif /* !CRTLIB */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user