diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2023-01-01 13:26:43 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-01 13:26:43 +0000 |
| commit | 28fb35f2f7a6ffd75e76dd95352f4194d79b3166 (patch) | |
| tree | eac021b897fe6525a076264d5545aac6c96cfbb5 /src/threading.cpp | |
| parent | 547c7bce1b28757415c553830a18d94636cedbf8 (diff) | |
| parent | c1384afe2fd705ce075277aa8dc6bc259dc94cdc (diff) | |
Merge pull request #2263 from odin-lang/compiler-improvements-2022-12
Compiler Improvements for 2022-12
Diffstat (limited to 'src/threading.cpp')
| -rw-r--r-- | src/threading.cpp | 253 |
1 files changed, 100 insertions, 153 deletions
diff --git a/src/threading.cpp b/src/threading.cpp index 63e3415b2..e92ed5e31 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -1,6 +1,10 @@ #if defined(GB_SYSTEM_LINUX) #include <signal.h> #endif +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif struct BlockingMutex; struct RecursiveMutex; @@ -23,49 +27,46 @@ struct Thread { isize user_index; isize volatile return_value; - Semaphore * semaphore; isize stack_size; std::atomic<bool> is_running; }; -void mutex_init (BlockingMutex *m); -void mutex_destroy (BlockingMutex *m); -void mutex_lock (BlockingMutex *m); -bool mutex_try_lock(BlockingMutex *m); -void mutex_unlock (BlockingMutex *m); -void mutex_init (RecursiveMutex *m); -void mutex_destroy (RecursiveMutex *m); -void mutex_lock (RecursiveMutex *m); -bool mutex_try_lock(RecursiveMutex *m); -void mutex_unlock (RecursiveMutex *m); +gb_internal void mutex_init (BlockingMutex *m); +gb_internal void mutex_destroy (BlockingMutex *m); +gb_internal void mutex_lock (BlockingMutex *m); +gb_internal bool mutex_try_lock(BlockingMutex *m); +gb_internal void mutex_unlock (BlockingMutex *m); +gb_internal void mutex_init (RecursiveMutex *m); +gb_internal void mutex_destroy (RecursiveMutex *m); +gb_internal void mutex_lock (RecursiveMutex *m); +gb_internal bool mutex_try_lock(RecursiveMutex *m); +gb_internal void mutex_unlock (RecursiveMutex *m); -void semaphore_init (Semaphore *s); -void semaphore_destroy(Semaphore *s); -void semaphore_post (Semaphore *s, i32 count); -void semaphore_wait (Semaphore *s); -void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } +gb_internal void semaphore_init (Semaphore *s); +gb_internal void semaphore_destroy(Semaphore *s); +gb_internal void semaphore_post (Semaphore *s, i32 count); +gb_internal void semaphore_wait (Semaphore *s); +gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } -void condition_init(Condition *c); -void condition_destroy(Condition *c); -void condition_broadcast(Condition *c); -void condition_signal(Condition *c); -void condition_wait(Condition *c, BlockingMutex *m); -void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms); +gb_internal void condition_init(Condition *c); +gb_internal void condition_destroy(Condition *c); +gb_internal void condition_broadcast(Condition *c); +gb_internal void condition_signal(Condition *c); +gb_internal void condition_wait(Condition *c, BlockingMutex *m); +gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms); -u32 thread_current_id(void); +gb_internal u32 thread_current_id(void); -void thread_init (Thread *t); -void thread_destroy (Thread *t); -void thread_start (Thread *t, ThreadProc *proc, void *data); -void thread_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size); -void thread_join (Thread *t); -bool thread_is_running (Thread const *t); -void thread_set_name (Thread *t, char const *name); +gb_internal void thread_init_and_start (Thread *t, ThreadProc *proc, void *data); +gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *data, isize stack_size); +gb_internal void thread_join_and_destroy(Thread *t); +gb_internal bool thread_is_running (Thread const *t); +gb_internal void thread_set_name (Thread *t, char const *name); -void yield_thread(void); -void yield_process(void); +gb_internal void yield_thread(void); +gb_internal void yield_process(void); struct MutexGuard { @@ -106,36 +107,36 @@ struct MutexGuard { struct BlockingMutex { SRWLOCK srwlock; }; - void mutex_init(BlockingMutex *m) { + gb_internal void mutex_init(BlockingMutex *m) { } - void mutex_destroy(BlockingMutex *m) { + gb_internal void mutex_destroy(BlockingMutex *m) { } - void mutex_lock(BlockingMutex *m) { + gb_internal void mutex_lock(BlockingMutex *m) { AcquireSRWLockExclusive(&m->srwlock); } - bool mutex_try_lock(BlockingMutex *m) { + gb_internal bool mutex_try_lock(BlockingMutex *m) { return !!TryAcquireSRWLockExclusive(&m->srwlock); } - void mutex_unlock(BlockingMutex *m) { + gb_internal void mutex_unlock(BlockingMutex *m) { ReleaseSRWLockExclusive(&m->srwlock); } struct RecursiveMutex { CRITICAL_SECTION win32_critical_section; }; - void mutex_init(RecursiveMutex *m) { + gb_internal void mutex_init(RecursiveMutex *m) { InitializeCriticalSection(&m->win32_critical_section); } - void mutex_destroy(RecursiveMutex *m) { + gb_internal void mutex_destroy(RecursiveMutex *m) { DeleteCriticalSection(&m->win32_critical_section); } - void mutex_lock(RecursiveMutex *m) { + gb_internal void mutex_lock(RecursiveMutex *m) { EnterCriticalSection(&m->win32_critical_section); } - bool mutex_try_lock(RecursiveMutex *m) { + gb_internal bool mutex_try_lock(RecursiveMutex *m) { return TryEnterCriticalSection(&m->win32_critical_section) != 0; } - void mutex_unlock(RecursiveMutex *m) { + gb_internal void mutex_unlock(RecursiveMutex *m) { LeaveCriticalSection(&m->win32_critical_section); } @@ -143,16 +144,16 @@ struct MutexGuard { void *win32_handle; }; - void semaphore_init(Semaphore *s) { + gb_internal void semaphore_init(Semaphore *s) { s->win32_handle = CreateSemaphoreA(NULL, 0, I32_MAX, NULL); } - void semaphore_destroy(Semaphore *s) { + gb_internal void semaphore_destroy(Semaphore *s) { CloseHandle(s->win32_handle); } - void semaphore_post(Semaphore *s, i32 count) { + gb_internal void semaphore_post(Semaphore *s, i32 count) { ReleaseSemaphore(s->win32_handle, count, NULL); } - void semaphore_wait(Semaphore *s) { + gb_internal void semaphore_wait(Semaphore *s) { WaitForSingleObjectEx(s->win32_handle, INFINITE, FALSE); } @@ -160,20 +161,20 @@ struct MutexGuard { CONDITION_VARIABLE cond; }; - void condition_init(Condition *c) { + gb_internal void condition_init(Condition *c) { } - void condition_destroy(Condition *c) { + gb_internal void condition_destroy(Condition *c) { } - void condition_broadcast(Condition *c) { + gb_internal void condition_broadcast(Condition *c) { WakeAllConditionVariable(&c->cond); } - void condition_signal(Condition *c) { + gb_internal void condition_signal(Condition *c) { WakeConditionVariable(&c->cond); } - void condition_wait(Condition *c, BlockingMutex *m) { + gb_internal void condition_wait(Condition *c, BlockingMutex *m) { SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0); } - void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) { + gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) { SleepConditionVariableSRW(&c->cond, &m->srwlock, timeout_in_ms, 0); } @@ -181,19 +182,19 @@ struct MutexGuard { struct BlockingMutex { pthread_mutex_t pthread_mutex; }; - void mutex_init(BlockingMutex *m) { + gb_internal void mutex_init(BlockingMutex *m) { pthread_mutex_init(&m->pthread_mutex, nullptr); } - void mutex_destroy(BlockingMutex *m) { + gb_internal void mutex_destroy(BlockingMutex *m) { pthread_mutex_destroy(&m->pthread_mutex); } - void mutex_lock(BlockingMutex *m) { + gb_internal void mutex_lock(BlockingMutex *m) { pthread_mutex_lock(&m->pthread_mutex); } - bool mutex_try_lock(BlockingMutex *m) { + gb_internal bool mutex_try_lock(BlockingMutex *m) { return pthread_mutex_trylock(&m->pthread_mutex) == 0; } - void mutex_unlock(BlockingMutex *m) { + gb_internal void mutex_unlock(BlockingMutex *m) { pthread_mutex_unlock(&m->pthread_mutex); } @@ -201,21 +202,21 @@ struct MutexGuard { pthread_mutex_t pthread_mutex; pthread_mutexattr_t pthread_mutexattr; }; - void mutex_init(RecursiveMutex *m) { + gb_internal void mutex_init(RecursiveMutex *m) { pthread_mutexattr_init(&m->pthread_mutexattr); pthread_mutexattr_settype(&m->pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&m->pthread_mutex, &m->pthread_mutexattr); } - void mutex_destroy(RecursiveMutex *m) { + gb_internal void mutex_destroy(RecursiveMutex *m) { pthread_mutex_destroy(&m->pthread_mutex); } - void mutex_lock(RecursiveMutex *m) { + gb_internal void mutex_lock(RecursiveMutex *m) { pthread_mutex_lock(&m->pthread_mutex); } - bool mutex_try_lock(RecursiveMutex *m) { + gb_internal bool mutex_try_lock(RecursiveMutex *m) { return pthread_mutex_trylock(&m->pthread_mutex) == 0; } - void mutex_unlock(RecursiveMutex *m) { + gb_internal void mutex_unlock(RecursiveMutex *m) { pthread_mutex_unlock(&m->pthread_mutex); } @@ -224,18 +225,18 @@ struct MutexGuard { semaphore_t osx_handle; }; - void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); } - void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); } - void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); } - void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); } + gb_internal void semaphore_init (Semaphore *s) { semaphore_create(mach_task_self(), &s->osx_handle, SYNC_POLICY_FIFO, 0); } + gb_internal void semaphore_destroy(Semaphore *s) { semaphore_destroy(mach_task_self(), s->osx_handle); } + gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) semaphore_signal(s->osx_handle); } + gb_internal void semaphore_wait (Semaphore *s) { semaphore_wait(s->osx_handle); } #elif defined(GB_SYSTEM_UNIX) struct Semaphore { sem_t unix_handle; }; - void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); } - void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); } - void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); } + gb_internal void semaphore_init (Semaphore *s) { sem_init(&s->unix_handle, 0, 0); } + gb_internal void semaphore_destroy(Semaphore *s) { sem_destroy(&s->unix_handle); } + gb_internal void semaphore_post (Semaphore *s, i32 count) { while (count --> 0) sem_post(&s->unix_handle); } void semaphore_wait (Semaphore *s) { int i; do { i = sem_wait(&s->unix_handle); } while (i == -1 && errno == EINTR); } #else #error Implement Semaphore for this platform @@ -246,22 +247,22 @@ struct MutexGuard { pthread_cond_t pthread_cond; }; - void condition_init(Condition *c) { + gb_internal void condition_init(Condition *c) { pthread_cond_init(&c->pthread_cond, NULL); } - void condition_destroy(Condition *c) { + gb_internal void condition_destroy(Condition *c) { pthread_cond_destroy(&c->pthread_cond); } - void condition_broadcast(Condition *c) { + gb_internal void condition_broadcast(Condition *c) { pthread_cond_broadcast(&c->pthread_cond); } - void condition_signal(Condition *c) { + gb_internal void condition_signal(Condition *c) { pthread_cond_signal(&c->pthread_cond); } - void condition_wait(Condition *c, BlockingMutex *m) { + gb_internal void condition_wait(Condition *c, BlockingMutex *m) { pthread_cond_wait(&c->pthread_cond, &m->pthread_mutex); } - void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) { + gb_internal void condition_wait_with_timeout(Condition *c, BlockingMutex *m, u32 timeout_in_ms) { struct timespec abstime = {}; abstime.tv_sec = timeout_in_ms/1000; abstime.tv_nsec = cast(long)(timeout_in_ms%1000)*1e6; @@ -269,51 +270,9 @@ struct MutexGuard { } #endif - - -struct Barrier { - BlockingMutex mutex; - Condition cond; - isize index; - isize generation_id; - isize thread_count; -}; - -void barrier_init(Barrier *b, isize thread_count) { - mutex_init(&b->mutex); - condition_init(&b->cond); - b->index = 0; - b->generation_id = 0; - b->thread_count = 0; -} - -void barrier_destroy(Barrier *b) { - condition_destroy(&b->cond); - mutex_destroy(&b->mutex); -} - -// Returns true if it is the leader -bool barrier_wait(Barrier *b) { - mutex_lock(&b->mutex); - defer (mutex_unlock(&b->mutex)); - isize local_gen = b->generation_id; - b->index += 1; - if (b->index < b->thread_count) { - while (local_gen == b->generation_id && b->index < b->thread_count) { - condition_wait(&b->cond, &b->mutex); - } - return false; - } - b->index = 0; - b->generation_id += 1; - condition_broadcast(&b->cond); - return true; -} - - -u32 thread_current_id(void) { +gb_internal u32 thread_current_id(void) { u32 thread_id; #if defined(GB_SYSTEM_WINDOWS) #if defined(GB_ARCH_32_BIT) && defined(GB_CPU_X86) @@ -340,7 +299,7 @@ u32 thread_current_id(void) { } -gb_inline void yield_thread(void) { +gb_internal gb_inline void yield_thread(void) { #if defined(GB_SYSTEM_WINDOWS) _mm_pause(); #elif defined(GB_SYSTEM_OSX) @@ -358,7 +317,7 @@ gb_inline void yield_thread(void) { #endif } -gb_inline void yield(void) { +gb_internal gb_inline void yield(void) { #if defined(GB_SYSTEM_WINDOWS) YieldProcessor(); #else @@ -366,39 +325,19 @@ gb_inline void yield(void) { #endif } - -void thread_init(Thread *t) { - gb_zero_item(t); -#if defined(GB_SYSTEM_WINDOWS) - t->win32_handle = INVALID_HANDLE_VALUE; -#else - t->posix_handle = 0; -#endif - t->semaphore = gb_alloc_item(heap_allocator(), Semaphore); - semaphore_init(t->semaphore); -} - -void thread_destroy(Thread *t) { - thread_join(t); - semaphore_destroy(t->semaphore); - gb_free(heap_allocator(), t->semaphore); -} - - -void gb__thread_run(Thread *t) { - semaphore_release(t->semaphore); +gb_internal void private__thread_run(Thread *t) { t->return_value = t->proc(t); } #if defined(GB_SYSTEM_WINDOWS) - DWORD __stdcall internal_thread_proc(void *arg) { + gb_internal DWORD __stdcall internal_thread_proc(void *arg) { Thread *t = cast(Thread *)arg; t->is_running.store(true); - gb__thread_run(t); + private__thread_run(t); return 0; } #else - void *internal_thread_proc(void *arg) { + gb_internal void *internal_thread_proc(void *arg) { #if (GB_SYSTEM_LINUX) // NOTE: Don't permit any signal delivery to threads on Linux. sigset_t mask = {}; @@ -408,14 +347,20 @@ void gb__thread_run(Thread *t) { Thread *t = cast(Thread *)arg; t->is_running.store(true); - gb__thread_run(t); + private__thread_run(t); return NULL; } #endif -void thread_start(Thread *t, ThreadProc *proc, void *user_data) { thread_start_with_stack(t, proc, user_data, 0); } +gb_internal void thread_init_and_start(Thread *t, ThreadProc *proc, void *user_data) { thread_init_and_start_with_stack(t, proc, user_data, 0); } -void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) { +gb_internal void thread_init_and_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize stack_size) { + gb_zero_item(t); +#if defined(GB_SYSTEM_WINDOWS) + t->win32_handle = INVALID_HANDLE_VALUE; +#else + t->posix_handle = 0; +#endif GB_ASSERT(!t->is_running.load()); GB_ASSERT(proc != NULL); t->proc = proc; @@ -429,19 +374,17 @@ void thread_start_with_stack(Thread *t, ThreadProc *proc, void *user_data, isize { pthread_attr_t attr; pthread_attr_init(&attr); + defer (pthread_attr_destroy(&attr)); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (stack_size != 0) { pthread_attr_setstacksize(&attr, stack_size); } pthread_create(&t->posix_handle, &attr, internal_thread_proc, t); - pthread_attr_destroy(&attr); } #endif - - semaphore_wait(t->semaphore); } -void thread_join(Thread *t) { +gb_internal void thread_join_and_destroy(Thread *t) { if (!t->is_running.load()) { return; } @@ -457,9 +400,9 @@ void thread_join(Thread *t) { t->is_running.store(false); } -bool thread_is_running(Thread const *t) { return t->is_running.load(); } +gb_internal bool thread_is_running(Thread const *t) { return t->is_running.load(); } -void thread_set_name(Thread *t, char const *name) { +gb_internal void thread_set_name(Thread *t, char const *name) { #if defined(GB_COMPILER_MSVC) #pragma pack(push, 8) typedef struct { @@ -494,3 +437,7 @@ void thread_set_name(Thread *t, char const *name) { #endif } + +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif
\ No newline at end of file |