align & pad snc structs to cache line

This commit is contained in:
jacob 2025-07-10 11:43:24 -05:00
parent f1f54fe519
commit 915a9272e4
3 changed files with 30 additions and 34 deletions

View File

@ -4,8 +4,7 @@
#include "memory.h" #include "memory.h"
#include "intrinsics.h" #include "intrinsics.h"
//#define DEFAULT_MUTEX_SPIN 4000 #define DEFAULT_MUTEX_SPIN 4000
#define DEFAULT_MUTEX_SPIN 0
/* ========================== * /* ========================== *
* Mutex * Mutex

View File

@ -10,7 +10,7 @@ struct snc_lock {
b32 exclusive; b32 exclusive;
}; };
struct snc_mutex { struct alignas(64) snc_mutex {
/* Bit 31 = Exclusive lock is held /* Bit 31 = Exclusive lock is held
* Bit 30 = Exclusive lock is pending * Bit 30 = Exclusive lock is pending
* Bit 0-30 = Shared locks count * Bit 0-30 = Shared locks count
@ -19,8 +19,13 @@ struct snc_mutex {
#if RTC #if RTC
struct atomic_i32 exclusive_fiber_id; struct atomic_i32 exclusive_fiber_id;
u8 _pad[56];
#else
u8 _pad[60];
#endif #endif
}; };
STATIC_ASSERT(sizeof(struct snc_mutex) == 64); /* Padding validation */
STATIC_ASSERT(alignof(struct snc_mutex) == 64); /* Prevent false sharing */
struct snc_lock snc_lock_spin_e(struct snc_mutex *m, i32 spin); struct snc_lock snc_lock_spin_e(struct snc_mutex *m, i32 spin);
struct snc_lock snc_lock_spin_s(struct snc_mutex *m, i32 spin); struct snc_lock snc_lock_spin_s(struct snc_mutex *m, i32 spin);
@ -40,9 +45,12 @@ void snc_unlock(struct snc_lock *lock);
* Condition variable * Condition variable
* ========================== */ * ========================== */
struct snc_cv { struct alignas(64) snc_cv {
struct atomic_u64 wake_gen; struct atomic_u64 wake_gen;
u8 _pad[56];
}; };
STATIC_ASSERT(sizeof(struct snc_cv) == 64); /* Padding validation */
STATIC_ASSERT(alignof(struct snc_cv) == 64); /* Prevent false sharing */
void snc_cv_wait(struct snc_cv *cv, struct snc_lock *lock); void snc_cv_wait(struct snc_cv *cv, struct snc_lock *lock);
void snc_cv_wait_time(struct snc_cv *cv, struct snc_lock *l, i64 timeout_ns); void snc_cv_wait_time(struct snc_cv *cv, struct snc_lock *l, i64 timeout_ns);
@ -56,9 +64,13 @@ void snc_cv_broadcast(struct snc_cv *cv);
* Counter * Counter
* ========================== */ * ========================== */
struct snc_counter { struct alignas(64) snc_counter {
struct atomic_i64 v; struct atomic_i64 v;
u8 _pad[56];
}; };
STATIC_ASSERT(sizeof(struct snc_counter) == 64); /* Padding validation */
STATIC_ASSERT(alignof(struct snc_counter) == 64); /* Prevent false sharing */
void snc_counter_add(struct snc_counter *counter, i64 x); void snc_counter_add(struct snc_counter *counter, i64 x);
void snc_counter_wait(struct snc_counter *counter); void snc_counter_wait(struct snc_counter *counter);

View File

@ -217,7 +217,6 @@ STATIC_ASSERT(sizeof(struct fiber) == 128); /* Padding validation (increase if
STATIC_ASSERT(alignof(struct fiber) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct fiber) == 64); /* Avoid false sharing */
STATIC_ASSERT(SYS_MAX_FIBERS < I16_MAX); /* Max fibers should fit in fiber id */ STATIC_ASSERT(SYS_MAX_FIBERS < I16_MAX); /* Max fibers should fit in fiber id */
struct alignas(64) worker_ctx { struct alignas(64) worker_ctx {
i32 id; i32 id;
}; };
@ -322,7 +321,7 @@ GLOBAL struct {
struct job_queue job_queues[NUM_JOB_QUEUE_KINDS]; struct job_queue job_queues[NUM_JOB_QUEUE_KINDS];
/* Workers */ /* Workers */
struct atomic_i64 workers_wake_gen; /* TODO: Prevent false sharing */ struct atomic_i32 workers_shutdown;
struct atomic_i64 num_jobs_in_queue; /* TODO: Prevent false sharing */ struct atomic_i64 num_jobs_in_queue; /* TODO: Prevent false sharing */
struct snc_mutex workers_wake_mutex; struct snc_mutex workers_wake_mutex;
struct snc_cv workers_wake_cv; struct snc_cv workers_wake_cv;
@ -593,11 +592,8 @@ void sys_wake_all(void *addr)
struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex); struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex);
{ {
atomic_i64_fetch_add(&G.num_jobs_in_queue, num_waiters); atomic_i64_fetch_add(&G.num_jobs_in_queue, num_waiters);
if (atomic_i64_fetch(&G.workers_wake_gen) >= 0) {
atomic_i64_fetch_add(&G.workers_wake_gen, 1);
snc_cv_broadcast(&G.workers_wake_cv); snc_cv_broadcast(&G.workers_wake_cv);
} }
}
snc_unlock(&lock); snc_unlock(&lock);
} }
@ -762,11 +758,8 @@ void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_priority priorit
struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex); struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex);
{ {
atomic_i64_fetch_add(&G.num_jobs_in_queue, count); atomic_i64_fetch_add(&G.num_jobs_in_queue, count);
if (atomic_i64_fetch(&G.workers_wake_gen) >= 0) {
atomic_i64_fetch_add(&G.workers_wake_gen, 1);
snc_cv_broadcast(&G.workers_wake_cv); snc_cv_broadcast(&G.workers_wake_cv);
} }
}
snc_unlock(&lock); snc_unlock(&lock);
} }
@ -874,8 +867,8 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
} }
struct fiber *job_fiber = NULL; struct fiber *job_fiber = NULL;
i64 last_seen_wake_gen = 0; b32 shutdown = false;
while (last_seen_wake_gen >= 0) { while (!shutdown) {
/* Pull job from queue */ /* Pull job from queue */
enum sys_priority job_priority = 0; enum sys_priority job_priority = 0;
i16 job_fiber_id = 0; i16 job_fiber_id = 0;
@ -1116,16 +1109,11 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
/* Wait */ /* Wait */
struct snc_lock wake_lock = snc_lock_s(&G.workers_wake_mutex); struct snc_lock wake_lock = snc_lock_s(&G.workers_wake_mutex);
{ {
if (atomic_i64_fetch(&G.num_jobs_in_queue) <= 0) { shutdown = atomic_i32_fetch(&G.workers_shutdown);
i64 new_wake_gen = atomic_i64_fetch(&G.workers_wake_gen); while (atomic_i64_fetch(&G.num_jobs_in_queue) <= 0 && !shutdown) {
while (new_wake_gen == last_seen_wake_gen) {
__profnc("Wait for job", RGB32_F(0.75, 0.75, 0)); __profnc("Wait for job", RGB32_F(0.75, 0.75, 0));
snc_cv_wait(&G.workers_wake_cv, &wake_lock); snc_cv_wait(&G.workers_wake_cv, &wake_lock);
new_wake_gen = atomic_i64_fetch(&G.workers_wake_gen); shutdown = atomic_i32_fetch(&G.workers_shutdown);
}
last_seen_wake_gen = new_wake_gen;
} else {
last_seen_wake_gen = atomic_i64_fetch(&G.workers_wake_gen);
} }
} }
snc_unlock(&wake_lock); snc_unlock(&wake_lock);
@ -1643,7 +1631,7 @@ INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _)
sys_panic(LIT("Failed to create high resolution timer")); sys_panic(LIT("Failed to create high resolution timer"));
} }
/* Create ring buffer of scheduler cycles initialized to default value */ /* Create rolling buffer of scheduler cycles initialized to default value */
i32 periods_index = 0; i32 periods_index = 0;
i64 periods[NUM_ROLLING_SCHEDULER_PERIODS] = ZI; i64 periods[NUM_ROLLING_SCHEDULER_PERIODS] = ZI;
for (i32 i = 0; i < (i32)countof(periods); ++i) { for (i32 i = 0; i < (i32)countof(periods); ++i) {
@ -1651,7 +1639,7 @@ INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _)
} }
i64 last_cycle_ns = 0; i64 last_cycle_ns = 0;
while (atomic_i64_fetch(&G.workers_wake_gen) >= 0) { while (!atomic_i32_fetch(&G.workers_shutdown)) {
__profn("Job scheduler cycle"); __profn("Job scheduler cycle");
{ {
__profn("Job scheduler wait"); __profn("Job scheduler wait");
@ -1857,11 +1845,8 @@ INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _)
struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex); struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex);
{ {
atomic_i64_fetch_add(&G.num_jobs_in_queue, num_waiters); atomic_i64_fetch_add(&G.num_jobs_in_queue, num_waiters);
if (atomic_i64_fetch(&G.workers_wake_gen) >= 0) {
atomic_i64_fetch_add(&G.workers_wake_gen, 1);
snc_cv_broadcast(&G.workers_wake_cv); snc_cv_broadcast(&G.workers_wake_cv);
} }
}
snc_unlock(&lock); snc_unlock(&lock);
} }
arena_temp_end(temp); arena_temp_end(temp);
@ -3886,7 +3871,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
/* Shutdown test thread */ /* Shutdown test thread */
{ {
struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex); struct snc_lock lock = snc_lock_e(&G.workers_wake_mutex);
atomic_i64_fetch_set(&G.workers_wake_gen, -1); atomic_i32_fetch_set(&G.workers_shutdown, 1);
snc_cv_broadcast(&G.workers_wake_cv); snc_cv_broadcast(&G.workers_wake_cv);
snc_unlock(&lock); snc_unlock(&lock);
} }