Skip to content

Commit

Permalink
explicit atomic load and stores
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Sep 11, 2023
1 parent b3a5fb2 commit 2b1a698
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 32 deletions.
27 changes: 14 additions & 13 deletions src/event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1466,20 +1466,21 @@ 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) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

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
}
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/misc/memory_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 8 additions & 8 deletions src/misc/ts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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;
}
}
Expand All @@ -66,16 +66,16 @@ 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;
}

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);
}
Expand Down
5 changes: 3 additions & 2 deletions src/mouse_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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);
}
6 changes: 3 additions & 3 deletions src/process_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");

Expand Down
10 changes: 5 additions & 5 deletions src/workspace.m
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit 2b1a698

Please sign in to comment.