use floating job for playback wait
This commit is contained in:
parent
0ce5a1ed87
commit
e02858fd21
@ -2605,7 +2605,7 @@ struct gp_swapchain *gp_swapchain_alloc(struct sys_window *window, struct v2i32
|
|||||||
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
||||||
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
|
struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT];
|
||||||
|
|
||||||
struct swapchain *swapchain = NULL;
|
struct swapchain *swapchain = 0;
|
||||||
{
|
{
|
||||||
struct snc_lock lock = snc_lock_e(&G.swapchains_mutex);
|
struct snc_lock lock = snc_lock_e(&G.swapchains_mutex);
|
||||||
if (G.first_free_swapchain) {
|
if (G.first_free_swapchain) {
|
||||||
|
|||||||
@ -20,12 +20,9 @@
|
|||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <uuids.h>
|
#include <uuids.h>
|
||||||
#include <avrt.h>
|
|
||||||
#include <Audioclient.h>
|
#include <Audioclient.h>
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
|
||||||
#pragma comment(lib, "avrt")
|
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e);
|
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e);
|
||||||
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6);
|
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6);
|
||||||
DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2);
|
DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2);
|
||||||
@ -43,8 +40,8 @@ GLOBAL struct {
|
|||||||
HANDLE event;
|
HANDLE event;
|
||||||
IAudioRenderClient *playback;
|
IAudioRenderClient *playback;
|
||||||
WAVEFORMATEX *buffer_format;
|
WAVEFORMATEX *buffer_format;
|
||||||
struct sys_thread *playback_scheduler_thread;
|
|
||||||
u32 buffer_frames;
|
u32 buffer_frames;
|
||||||
|
struct snc_counter playback_job_counter;
|
||||||
} G = ZI, DEBUG_ALIAS(G, G_playback_wasapi);
|
} G = ZI, DEBUG_ALIAS(G, G_playback_wasapi);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -53,14 +50,15 @@ GLOBAL struct {
|
|||||||
|
|
||||||
INTERNAL void wasapi_initialize(void);
|
INTERNAL void wasapi_initialize(void);
|
||||||
INTERNAL SYS_EXIT_FUNC(playback_shutdown);
|
INTERNAL SYS_EXIT_FUNC(playback_shutdown);
|
||||||
INTERNAL SYS_THREAD_DEF(playback_scheduler_entry, _);
|
INTERNAL SYS_JOB_DEF(playback_job, _);
|
||||||
|
|
||||||
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr)
|
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr)
|
||||||
{
|
{
|
||||||
(UNUSED)mixer_sr;
|
(UNUSED)mixer_sr;
|
||||||
|
|
||||||
wasapi_initialize();
|
wasapi_initialize();
|
||||||
G.playback_scheduler_thread = sys_thread_alloc(playback_scheduler_entry, 0, LIT("Playback scheduler thread"), PROF_THREAD_GROUP_SCHEDULER);
|
/* Start playback job */
|
||||||
|
sys_run(1, playback_job, 0, SYS_POOL_AUDIO, SYS_PRIORITY_HIGH, &G.playback_job_counter);
|
||||||
sys_on_exit(&playback_shutdown);
|
sys_on_exit(&playback_shutdown);
|
||||||
|
|
||||||
return (struct playback_startup_receipt) { 0 };
|
return (struct playback_startup_receipt) { 0 };
|
||||||
@ -70,7 +68,7 @@ INTERNAL SYS_EXIT_FUNC(playback_shutdown)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
atomic32_fetch_set(&G.shutdown, 1);
|
atomic32_fetch_set(&G.shutdown, 1);
|
||||||
sys_thread_wait_release(G.playback_scheduler_thread);
|
snc_counter_wait(&G.playback_job_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -223,41 +221,34 @@ INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, struct mixed_pcm_f
|
|||||||
* Playback thread entry
|
* Playback thread entry
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL SYS_JOB_DEF(playback_mix_job, _)
|
INTERNAL SYS_JOB_DEF(playback_wait_job, _)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
WaitForSingleObject(G.event, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL SYS_JOB_DEF(playback_job, _)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
(UNUSED)_;
|
(UNUSED)_;
|
||||||
|
|
||||||
|
/* FIXME: If playback fails at any point and mixer stops advancing, we
|
||||||
|
* need to halt mixer to prevent memory leak when sounds are played. */
|
||||||
|
/* TODO: Signal counter that running job wiats on, rather than scheduling job manually */
|
||||||
|
while (!atomic32_fetch(&G.shutdown)) {
|
||||||
struct arena_temp scratch = scratch_begin_no_conflict();
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
{
|
{
|
||||||
|
__profn("Wasapi wait");
|
||||||
|
struct snc_counter counter = ZI;
|
||||||
|
sys_run(1, playback_wait_job, 0, SYS_POOL_FLOATING, SYS_PRIORITY_INHERIT, &counter);
|
||||||
|
snc_counter_wait(&counter);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
__profn("Fill sample buffer");
|
||||||
struct wasapi_buffer wspbuf = wasapi_update_begin();
|
struct wasapi_buffer wspbuf = wasapi_update_begin();
|
||||||
struct mixed_pcm_f32 pcm = mixer_update(scratch.arena, wspbuf.frames_count);
|
struct mixed_pcm_f32 pcm = mixer_update(scratch.arena, wspbuf.frames_count);
|
||||||
wasapi_update_end(&wspbuf, pcm);
|
wasapi_update_end(&wspbuf, pcm);
|
||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL SYS_THREAD_DEF(playback_scheduler_entry, _)
|
|
||||||
{
|
|
||||||
(UNUSED)_;
|
|
||||||
/* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */
|
|
||||||
DWORD task = 0;
|
|
||||||
HANDLE mmc_handle = AvSetMmThreadCharacteristicsW(L"Pro Audio", &task);
|
|
||||||
ASSERT(mmc_handle);
|
|
||||||
(UNUSED)mmc_handle;
|
|
||||||
|
|
||||||
/* FIXME: If playback fails at any point and mixer stops advancing, we
|
|
||||||
* need to halt mixer to prevent memory leak when sounds are played. */
|
|
||||||
/* TODO: Signal counter that running job wiats on, rather than scheduling job manually */
|
|
||||||
while (!atomic32_fetch(&G.shutdown)) {
|
|
||||||
{
|
|
||||||
__profn("Wasapi wait");
|
|
||||||
WaitForSingleObject(G.event, INFINITE);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
__profn("Run mix job & wait");
|
|
||||||
struct snc_counter counter = ZI;
|
|
||||||
sys_run(1, playback_mix_job, 0, SYS_POOL_DEDICATED, SYS_PRIORITY_CRITICAL, &counter);
|
|
||||||
snc_counter_wait(&counter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/sys.h
22
src/sys.h
@ -58,17 +58,14 @@ void sys_make_current_job_unyielding(void);
|
|||||||
enum sys_pool {
|
enum sys_pool {
|
||||||
SYS_POOL_INHERIT = -1,
|
SYS_POOL_INHERIT = -1,
|
||||||
|
|
||||||
/* This pool contains workers that rougly map to dedicated performance cores on the CPU.
|
/* The floating pool contains a large number of lower priority threads that have affinity over the entire CPU.
|
||||||
* Time critical jobs should be pushed here. */
|
* Other pools should push jobs that only block and do no work here so that they can yield on the blocking job rather than blocking themselves. */
|
||||||
SYS_POOL_DEDICATED = 0,
|
SYS_POOL_FLOATING = 0,
|
||||||
|
|
||||||
/* This pool contains workers that that will not interfere with the dedicated pool.
|
|
||||||
* Asynchronous jobs (e.g. as asset streaming) should be pushed here. */
|
|
||||||
SYS_POOL_BACKGROUND = 1,
|
SYS_POOL_BACKGROUND = 1,
|
||||||
|
SYS_POOL_AUDIO = 2,
|
||||||
/* This pool contains a large number of floating low priority worker threads with the intent that these threads will only block and do no actual work.
|
SYS_POOL_USER = 3,
|
||||||
* Blocking operations (e.g. opening a file) should be isolated to jobs that get pushed to this pool. They can then be yielded on by jobs in other pools that actually do work. */
|
SYS_POOL_SIM = 4,
|
||||||
SYS_POOL_FLOATING = 2,
|
|
||||||
|
|
||||||
NUM_SYS_POOLS
|
NUM_SYS_POOLS
|
||||||
};
|
};
|
||||||
@ -76,10 +73,9 @@ enum sys_pool {
|
|||||||
/* Job execution order within a pool is based on priority. */
|
/* Job execution order within a pool is based on priority. */
|
||||||
enum sys_priority {
|
enum sys_priority {
|
||||||
SYS_PRIORITY_INHERIT = -1,
|
SYS_PRIORITY_INHERIT = -1,
|
||||||
SYS_PRIORITY_CRITICAL = 0,
|
SYS_PRIORITY_HIGH = 0,
|
||||||
SYS_PRIORITY_HIGH = 1,
|
SYS_PRIORITY_NORMAL = 1,
|
||||||
SYS_PRIORITY_NORMAL = 2,
|
SYS_PRIORITY_LOW = 2,
|
||||||
SYS_PRIORITY_LOW = 3,
|
|
||||||
|
|
||||||
NUM_SYS_PRIORITIES
|
NUM_SYS_PRIORITIES
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
# include <fileapi.h>
|
# include <fileapi.h>
|
||||||
# include <dwmapi.h>
|
# include <dwmapi.h>
|
||||||
# include <bcrypt.h>
|
# include <bcrypt.h>
|
||||||
|
# include <avrt.h>
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
#pragma comment(lib, "kernel32")
|
#pragma comment(lib, "kernel32")
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#pragma comment(lib, "dwmapi")
|
#pragma comment(lib, "dwmapi")
|
||||||
#pragma comment(lib, "bcrypt")
|
#pragma comment(lib, "bcrypt")
|
||||||
#pragma comment(lib, "synchronization")
|
#pragma comment(lib, "synchronization")
|
||||||
|
#pragma comment(lib, "avrt")
|
||||||
|
|
||||||
#define SYS_WINDOW_EVENT_LISTENERS_MAX 512
|
#define SYS_WINDOW_EVENT_LISTENERS_MAX 512
|
||||||
#define WINDOW_CLASS_NAME L"power_play_window_class"
|
#define WINDOW_CLASS_NAME L"power_play_window_class"
|
||||||
@ -248,6 +250,7 @@ struct alignas(64) job_pool {
|
|||||||
i32 num_worker_threads;
|
i32 num_worker_threads;
|
||||||
i32 thread_priority;
|
i32 thread_priority;
|
||||||
u64 thread_affinity_mask;
|
u64 thread_affinity_mask;
|
||||||
|
char *thread_mm_characteristics;
|
||||||
struct arena *worker_threads_arena;
|
struct arena *worker_threads_arena;
|
||||||
struct sys_thread **worker_threads;
|
struct sys_thread **worker_threads;
|
||||||
struct worker_ctx *worker_contexts;
|
struct worker_ctx *worker_contexts;
|
||||||
@ -782,10 +785,11 @@ INTERNAL struct fiber *fiber_alloc(struct job_pool *pool)
|
|||||||
return fiber;
|
return fiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void fiber_release(struct job_pool *pool, struct fiber *fiber, i16 fiber_id)
|
INTERNAL void fiber_release(struct job_pool *pool, struct fiber *fiber)
|
||||||
{
|
{
|
||||||
tm_lock(&pool->free_fibers_lock);
|
tm_lock(&pool->free_fibers_lock);
|
||||||
{
|
{
|
||||||
|
i16 fiber_id = fiber->id;
|
||||||
fiber->parent_id = pool->first_free_fiber_id;
|
fiber->parent_id = pool->first_free_fiber_id;
|
||||||
pool->first_free_fiber_id = fiber_id;
|
pool->first_free_fiber_id = fiber_id;
|
||||||
}
|
}
|
||||||
@ -876,7 +880,7 @@ INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber)
|
|||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
SwitchToFiber(parent_fiber->addr);
|
SwitchToFiber(parent_fiber->addr);
|
||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS + MEBI(fiber->job_pool) + fiber->id + 1);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + fiber->id + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,7 +899,7 @@ INTERNAL void job_fiber_entry(void *id_ptr)
|
|||||||
{
|
{
|
||||||
i16 id = (i32)(i64)id_ptr;
|
i16 id = (i32)(i64)id_ptr;
|
||||||
struct fiber *fiber = fiber_from_id(id);
|
struct fiber *fiber = fiber_from_id(id);
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS + MEBI(fiber->job_pool) + fiber->id + 1);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + fiber->id + 1);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Run job */
|
/* Run job */
|
||||||
{
|
{
|
||||||
@ -947,6 +951,14 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
ASSERT(success);
|
ASSERT(success);
|
||||||
(UNUSED)success;
|
(UNUSED)success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pool->thread_mm_characteristics) {
|
||||||
|
/* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */
|
||||||
|
DWORD task = 0;
|
||||||
|
HANDLE mmc_handle = AvSetMmThreadCharacteristicsA(pool->thread_mm_characteristics, &task);
|
||||||
|
ASSERT(mmc_handle);
|
||||||
|
(UNUSED)mmc_handle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 worker_fiber_id = sys_current_fiber_id();
|
i32 worker_fiber_id = sys_current_fiber_id();
|
||||||
@ -1016,7 +1028,7 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
/* Use resumed fiber if present */
|
/* Use resumed fiber if present */
|
||||||
if (job_fiber_id > 0) {
|
if (job_fiber_id > 0) {
|
||||||
if (job_fiber) {
|
if (job_fiber) {
|
||||||
fiber_release(pool, job_fiber, job_fiber->id);
|
fiber_release(pool, job_fiber);
|
||||||
}
|
}
|
||||||
job_fiber = fiber_from_id(job_fiber_id);
|
job_fiber = fiber_from_id(job_fiber_id);
|
||||||
}
|
}
|
||||||
@ -1028,7 +1040,8 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
}
|
}
|
||||||
job_fiber_id = job_fiber->id;
|
job_fiber_id = job_fiber->id;
|
||||||
{
|
{
|
||||||
__profnc("Run fiber", RGB32_F(0.25, 0.75, 0));
|
//__profnc("Run fiber", RGB32_F(0.25, 0.75, 0));
|
||||||
|
__profnc("Run fiber", RGB32_F(1, 1, 1));
|
||||||
__profvalue(job_fiber->id);
|
__profvalue(job_fiber->id);
|
||||||
struct yield_param yield = ZI;
|
struct yield_param yield = ZI;
|
||||||
job_fiber->parent_id = worker_fiber_id;
|
job_fiber->parent_id = worker_fiber_id;
|
||||||
@ -1219,9 +1232,6 @@ INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _)
|
|||||||
b32 success = SetThreadPriority(GetCurrentThread(), priority);
|
b32 success = SetThreadPriority(GetCurrentThread(), priority);
|
||||||
(UNUSED)success;
|
(UNUSED)success;
|
||||||
ASSERT(success);
|
ASSERT(success);
|
||||||
|
|
||||||
success = SetThreadAffinityMask(GetCurrentThread(), (1 << 14)) != 0;
|
|
||||||
ASSERT(success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create high resolution timer */
|
/* Create high resolution timer */
|
||||||
@ -1297,32 +1307,48 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
|
|||||||
for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) {
|
for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) {
|
||||||
struct job_pool *pool = &G.job_pools[pool_kind];
|
struct job_pool *pool = &G.job_pools[pool_kind];
|
||||||
struct string name_fmt = ZI;
|
struct string name_fmt = ZI;
|
||||||
i32 prof_group = PROF_THREAD_GROUP_FIBERS + MEBI(pool_kind);
|
i32 prof_group = PROF_THREAD_GROUP_FIBERS - MEBI(pool_kind);
|
||||||
switch (pool_kind) {
|
switch (pool_kind) {
|
||||||
default: ASSERT(0); break;
|
default: ASSERT(0); break;
|
||||||
|
|
||||||
case SYS_POOL_DEDICATED:
|
case SYS_POOL_SIM:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Dedicated worker #%F");
|
name_fmt = LIT("Sim worker #%F");
|
||||||
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFULL;
|
pool->thread_affinity_mask = 0x000000000000000Full;
|
||||||
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
pool->num_worker_threads = 4;
|
pool->num_worker_threads = 4;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case SYS_POOL_USER:
|
||||||
|
{
|
||||||
|
name_fmt = LIT("User worker #%F");
|
||||||
|
pool->thread_affinity_mask = 0x00000000000000F0ull;
|
||||||
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
|
pool->num_worker_threads = 4;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case SYS_POOL_AUDIO:
|
||||||
|
{
|
||||||
|
name_fmt = LIT("Audio worker #%F");
|
||||||
|
pool->thread_affinity_mask = 0x0000000000000300ull;
|
||||||
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
|
pool->thread_mm_characteristics = "Pro Audio";
|
||||||
|
pool->num_worker_threads = 2;
|
||||||
|
} break;
|
||||||
|
|
||||||
case SYS_POOL_BACKGROUND:
|
case SYS_POOL_BACKGROUND:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Background worker #%F");
|
name_fmt = LIT("Background worker #%F");
|
||||||
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFULL;
|
pool->thread_affinity_mask = 0x0000000000003000ull;
|
||||||
pool->thread_priority = 0;
|
pool->num_worker_threads = 2;
|
||||||
pool->num_worker_threads = 4;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SYS_POOL_FLOATING:
|
case SYS_POOL_FLOATING:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Floating worker #%F");
|
name_fmt = LIT("Floating worker #%F");
|
||||||
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFULL;
|
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFull;
|
||||||
pool->thread_priority = 0;
|
pool->thread_priority = 0;
|
||||||
pool->num_worker_threads = 4;
|
pool->num_worker_threads = 32;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
pool->worker_threads_arena = arena_alloc(GIBI(64));
|
pool->worker_threads_arena = arena_alloc(GIBI(64));
|
||||||
@ -2299,7 +2325,7 @@ INTERNAL SYS_THREAD_DEF(window_present_thread_entry_point, arg)
|
|||||||
struct sys_window_present_job_sig sig = ZI;
|
struct sys_window_present_job_sig sig = ZI;
|
||||||
sig.window = (struct sys_window *)window;
|
sig.window = (struct sys_window *)window;
|
||||||
sig.events = events;
|
sig.events = events;
|
||||||
sys_run(1, window->present_job, &sig, SYS_POOL_DEDICATED, SYS_PRIORITY_HIGH, &counter);
|
sys_run(1, window->present_job, &sig, SYS_POOL_USER, SYS_PRIORITY_HIGH, &counter);
|
||||||
snc_counter_wait(&counter);
|
snc_counter_wait(&counter);
|
||||||
}
|
}
|
||||||
arena_reset(events_arena);
|
arena_reset(events_arena);
|
||||||
|
|||||||
@ -243,7 +243,7 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
|
|||||||
log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG);
|
log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
/* Start sim job */
|
/* Start sim job */
|
||||||
sys_run(1, local_sim_job, 0, SYS_POOL_DEDICATED, SYS_PRIORITY_HIGH, &G.shutdown_job_counters);
|
sys_run(1, local_sim_job, 0, SYS_POOL_SIM, SYS_PRIORITY_HIGH, &G.shutdown_job_counters);
|
||||||
sys_on_exit(&user_shutdown);
|
sys_on_exit(&user_shutdown);
|
||||||
|
|
||||||
G.window = sys_window_alloc(user_update_job);
|
G.window = sys_window_alloc(user_update_job);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user