From 2b1a698df9bc885ef4287b006597353dc3aca82a Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Tue, 12 Sep 2023 00:52:12 +0200 Subject: [PATCH] explicit atomic load and stores --- src/event_loop.c | 27 ++++++++++++++------------- src/misc/memory_pool.h | 2 +- src/misc/ts.h | 16 ++++++++-------- src/mouse_handler.c | 5 +++-- src/process_manager.c | 6 +++--- src/workspace.m | 10 +++++----- 6 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/event_loop.c b/src/event_loop.c index 2c72def0..12e0cf69 100644 --- a/src/event_loop.c +++ b/src/event_loop.c @@ -45,7 +45,7 @@ static EVENT_HANDLER(APPLICATION_LAUNCHED) { struct process *process = context; - if (process->terminated) { + if (__atomic_load_n(&process->terminated, __ATOMIC_RELAXED)) { debug("%s: %s (%d) terminated during launch\n", __FUNCTION__, process->name, process->pid); window_manager_remove_lost_front_switched_event(&g_window_manager, process->pid); return; @@ -471,7 +471,7 @@ static EVENT_HANDLER(WINDOW_DESTROYED) { struct window *window = context; debug("%s: %s %d\n", __FUNCTION__, window->application->name, window->id); - assert(!window->id_ptr); + assert(!__atomic_load_n(&window->id_ptr, __ATOMIC_RELAXED)); border_destroy(window); struct view *view = window_manager_find_managed_window(&g_window_manager, window); @@ -1466,7 +1466,7 @@ static EVENT_HANDLER(DAEMON_MESSAGE) static void *event_loop_run(void *context) { - struct event *head; + struct event *head, *next; struct event_loop *event_loop = context; while (event_loop->is_running) { @@ -1474,12 +1474,13 @@ static void *event_loop_run(void *context) for (;;) { do { - head = event_loop->head; - if (!head->next) goto empty; - } while (!__sync_bool_compare_and_swap(&event_loop->head, head, head->next)); + head = __atomic_load_n(&event_loop->head, __ATOMIC_RELAXED); + next = __atomic_load_n(&head->next, __ATOMIC_RELAXED); + if (!next) goto empty; + } while (!__sync_bool_compare_and_swap(&event_loop->head, head, next)); - switch (head->next->type) { -#define EVENT_TYPE_ENTRY(value) case value: EVENT_HANDLER_##value(head->next->context, head->next->param1); break; + switch (__atomic_load_n(&next->type, __ATOMIC_RELAXED)) { +#define EVENT_TYPE_ENTRY(value) case value: EVENT_HANDLER_##value(__atomic_load_n(&next->context, __ATOMIC_RELAXED), __atomic_load_n(&next->param1, __ATOMIC_RELAXED)); break; EVENT_TYPE_LIST #undef EVENT_TYPE_ENTRY } @@ -1502,14 +1503,14 @@ void event_loop_post(struct event_loop *event_loop, enum event_type type, void * struct event *tail, *new_tail; new_tail = memory_pool_push(&event_loop->pool, sizeof(struct event)); - new_tail->type = type; - new_tail->param1 = param1; - new_tail->context = context; - new_tail->next = NULL; + __atomic_store_n(&new_tail->type, type, __ATOMIC_RELEASE); + __atomic_store_n(&new_tail->param1, param1, __ATOMIC_RELEASE); + __atomic_store_n(&new_tail->context, context, __ATOMIC_RELEASE); + __atomic_store_n(&new_tail->next, NULL, __ATOMIC_RELEASE); __asm__ __volatile__ ("" ::: "memory"); do { - tail = event_loop->tail; + tail = __atomic_load_n(&event_loop->tail, __ATOMIC_RELAXED); success = __sync_bool_compare_and_swap(&tail->next, NULL, new_tail); } while (!success); __sync_bool_compare_and_swap(&event_loop->tail, tail, new_tail); diff --git a/src/misc/memory_pool.h b/src/misc/memory_pool.h index f066e6ee..34c011cc 100644 --- a/src/misc/memory_pool.h +++ b/src/misc/memory_pool.h @@ -29,7 +29,7 @@ bool memory_pool_init(struct memory_pool *pool, uint64_t size) void *memory_pool_push(struct memory_pool *pool, uint64_t size) { for (;;) { - uint64_t used = pool->used; + uint64_t used = __atomic_load_n(&pool->used, __ATOMIC_RELAXED); uint64_t new_used = used + size; if (new_used < pool->size) { diff --git a/src/misc/ts.h b/src/misc/ts.h index c3551e26..d9cd0964 100644 --- a/src/misc/ts.h +++ b/src/misc/ts.h @@ -25,10 +25,10 @@ bool ts_init(uint64_t size) return result; } -static inline void ts_assert_within_bounds(void) +static inline void ts_assert_within_bounds(uint64_t size) { - if (g_temp_storage.used > g_temp_storage.size) { - fprintf(stderr, "fatal error: temporary_storage exceeded amount of allocated memory. requested %lld, but allocated size is %lld\n", g_temp_storage.used, g_temp_storage.size); + if (size > g_temp_storage.size) { + fprintf(stderr, "fatal error: temporary_storage exceeded amount of allocated memory. requested %lld, but allocated size is %lld\n", size, g_temp_storage.size); exit(EXIT_FAILURE); } } @@ -52,12 +52,12 @@ static inline uint64_t ts_align(uint64_t used, uint64_t align) static inline void *ts_alloc_aligned(uint64_t alignment, uint64_t size) { for (;;) { - uint64_t used = g_temp_storage.used; + uint64_t used = __atomic_load_n(&g_temp_storage.used, __ATOMIC_RELAXED); uint64_t aligned = ts_align(used, alignment); uint64_t new_used = aligned + size; if (__sync_bool_compare_and_swap(&g_temp_storage.used, used, new_used)) { - ts_assert_within_bounds(); + ts_assert_within_bounds(new_used); return g_temp_storage.memory + aligned; } } @@ -66,7 +66,7 @@ static inline void *ts_alloc_aligned(uint64_t alignment, uint64_t size) static inline void *ts_alloc_unaligned(uint64_t size) { uint64_t used = __sync_fetch_and_add(&g_temp_storage.used, size); - ts_assert_within_bounds(); + ts_assert_within_bounds(used+size); return g_temp_storage.memory + used; } @@ -74,8 +74,8 @@ static inline void *ts_expand(void *ptr, uint64_t old_size, uint64_t increment) { if (ptr) { assert(ptr == g_temp_storage.memory + g_temp_storage.used - old_size); - __sync_fetch_and_add(&g_temp_storage.used, increment); - ts_assert_within_bounds(); + uint64_t used = __sync_fetch_and_add(&g_temp_storage.used, increment); + ts_assert_within_bounds(used+increment); } else { ptr = ts_alloc_unaligned(increment); } diff --git a/src/mouse_handler.c b/src/mouse_handler.c index a30a3727..cbc1663f 100644 --- a/src/mouse_handler.c +++ b/src/mouse_handler.c @@ -23,7 +23,8 @@ static MOUSE_HANDLER(mouse_handler) switch (type) { case kCGEventTapDisabledByTimeout: case kCGEventTapDisabledByUserInput: { - if (mouse_state->handle) CGEventTapEnable(mouse_state->handle, true); + CFMachPortRef handle = __atomic_load_n(&mouse_state->handle, __ATOMIC_RELAXED); + if (handle) CGEventTapEnable(handle, true); } break; case kCGEventLeftMouseDown: case kCGEventRightMouseDown: { @@ -288,5 +289,5 @@ void mouse_handler_end(struct mouse_state *mouse_state) CFRunLoopRemoveSource(CFRunLoopGetMain(), mouse_state->runloop_source, kCFRunLoopCommonModes); CFRelease(mouse_state->runloop_source); CFRelease(mouse_state->handle); - mouse_state->handle = NULL; + __atomic_store_n(&mouse_state->handle, NULL, __ATOMIC_RELEASE); } diff --git a/src/process_manager.c b/src/process_manager.c index 8b147401..d6da9a81 100644 --- a/src/process_manager.c +++ b/src/process_manager.c @@ -61,8 +61,8 @@ struct process *process_create(ProcessSerialNumber psn) process->psn = psn; GetProcessPID(&process->psn, &process->pid); process->name = process_name; - process->terminated = false; - process->ns_application = workspace_application_create_running_ns_application(process); + __atomic_store_n(&process->terminated, false, __ATOMIC_RELEASE); + __atomic_store_n(&process->ns_application, workspace_application_create_running_ns_application(process), __ATOMIC_RELEASE); return process; } @@ -105,7 +105,7 @@ static PROCESS_EVENT_HANDLER(process_handler) struct process *process = process_manager_find_process(pm, &psn); if (!process) return noErr; - process->terminated = true; + __atomic_store_n(&process->terminated, true, __ATOMIC_RELEASE); process_manager_remove_process(pm, &psn); __asm__ __volatile__ ("" ::: "memory"); diff --git a/src/workspace.m b/src/workspace.m index 0d5d8ad5..17336992 100644 --- a/src/workspace.m +++ b/src/workspace.m @@ -21,7 +21,7 @@ bool workspace_event_handler_begin(void **context) void workspace_application_destroy_running_ns_application(void *ws_context, struct process *process) { - NSRunningApplication *application = process->ns_application; + NSRunningApplication *application = __atomic_load_n(&process->ns_application, __ATOMIC_RELAXED); if (application) { if ([application observationInfo]) { @@ -57,7 +57,7 @@ void workspace_application_destroy_running_ns_application(void *ws_context, stru void workspace_application_observe_finished_launching(void *context, struct process *process) { - NSRunningApplication *application = process->ns_application; + NSRunningApplication *application = __atomic_load_n(&process->ns_application, __ATOMIC_RELAXED); if (application) { [application addObserver:context forKeyPath:@"finishedLaunching" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew context:process]; } else { @@ -67,7 +67,7 @@ void workspace_application_observe_finished_launching(void *context, struct proc void workspace_application_observe_activation_policy(void *context, struct process *process) { - NSRunningApplication *application = process->ns_application; + NSRunningApplication *application = __atomic_load_n(&process->ns_application, __ATOMIC_RELAXED); if (application) { [application addObserver:context forKeyPath:@"activationPolicy" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew context:process]; } else { @@ -77,7 +77,7 @@ void workspace_application_observe_activation_policy(void *context, struct proce bool workspace_application_is_observable(struct process *process) { - NSRunningApplication *application = process->ns_application; + NSRunningApplication *application = __atomic_load_n(&process->ns_application, __ATOMIC_RELAXED); if (application) { return [application activationPolicy] != NSApplicationActivationPolicyProhibited; } else { @@ -87,7 +87,7 @@ bool workspace_application_is_observable(struct process *process) bool workspace_application_is_finished_launching(struct process *process) { - NSRunningApplication *application = process->ns_application; + NSRunningApplication *application = __atomic_load_n(&process->ns_application, __ATOMIC_RELAXED); if (application) { return [application isFinishedLaunching] == YES; } else {