From 60d0390ef8ceabb0567ee1ba968fdaf2024d34bf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 Jan 2023 14:48:31 +0000 Subject: [PATCH] Unify compiler `Futex` interface --- src/thread_pool.cpp | 6 +++--- src/threading.cpp | 43 +++++++++++++++++-------------------------- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 3565ef25a..57ed5e3c5 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -136,7 +136,7 @@ gb_internal void thread_pool_wait(ThreadPool *pool) { break; } - tpool_wait_on_addr(&pool->tasks_left, rem_tasks); + futex_wait(&pool->tasks_left, rem_tasks); } } @@ -160,7 +160,7 @@ work_start: finished_tasks += 1; } if (finished_tasks > 0 && !pool->tasks_left) { - tpool_wake_addr(&pool->tasks_left); + futex_signal(&pool->tasks_left); } // If there's still work somewhere and we don't have it, steal it @@ -183,7 +183,7 @@ work_start: pool->tasks_left.fetch_sub(1); if (!pool->tasks_left) { - tpool_wake_addr(&pool->tasks_left); + futex_signal(&pool->tasks_left); } goto work_start; diff --git a/src/threading.cpp b/src/threading.cpp index 493e57c91..cb3150c2a 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -41,6 +41,11 @@ struct Thread { struct ThreadPool *pool; }; +typedef std::atomic Futex; +typedef volatile int32_t Footex; + +gb_internal void futex_wait(Futex *addr, Footex val); +gb_internal void futex_signal(Futex *addr); gb_internal void mutex_init (BlockingMutex *m); gb_internal void mutex_destroy (BlockingMutex *m); @@ -441,12 +446,9 @@ gb_internal void thread_set_name(Thread *t, char const *name) { #include #include -typedef std::atomic Futex; -typedef volatile int32_t Footex; - -gb_internal void tpool_wake_addr(Futex *addr) { +gb_internal void futex_signal(Futex *addr) { for (;;) { - int ret = syscall(SYS_futex, addr, FUTEX_WAKE, 1, NULL, NULL, 0); + int ret = syscall(SYS_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL, 0); if (ret == -1) { perror("Futex wake"); GB_PANIC("Failed in futex wake!\n"); @@ -456,9 +458,9 @@ gb_internal void tpool_wake_addr(Futex *addr) { } } -gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { +gb_internal void futex_wait(Futex *addr, Footex val) { for (;;) { - int ret = syscall(SYS_futex, addr, FUTEX_WAIT, val, NULL, NULL, 0); + int ret = syscall(SYS_futex, addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, NULL, NULL, 0); if (ret == -1) { if (errno != EAGAIN) { perror("Futex wait"); @@ -479,14 +481,11 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { #include #include -typedef std::atomic Futex; -typedef volatile int32_t Footex; - -gb_internal void tpool_wake_addr(Futex *addr) { +gb_internal void futex_signal(Futex *addr) { _umtx_op(addr, UMTX_OP_WAKE, 1, 0, 0); } -gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { +gb_internal void futex_wait(Futex *addr, Footex val) { for (;;) { int ret = _umtx_op(addr, UMTX_OP_WAIT_UINT, val, 0, NULL); if (ret == 0) { @@ -508,10 +507,7 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { #include -typedef std::atomic Futex; -typedef volatile int32_t Footex; - -gb_internal void tpool_wake_addr(Futex *addr) { +gb_internal void futex_signal(Futex *addr) { for (;;) { int ret = futex((volatile uint32_t *)addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL); if (ret == -1) { @@ -527,7 +523,7 @@ gb_internal void tpool_wake_addr(Futex *addr) { } } -gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { +gb_internal void futex_wait(Futex *addr, Footex val) { for (;;) { int ret = futex((volatile uint32_t *)addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, NULL, NULL); if (ret == -1) { @@ -547,16 +543,13 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { #elif defined(GB_SYSTEM_OSX) -typedef std::atomic Futex; -typedef volatile int64_t Footex; - #define UL_COMPARE_AND_WAIT 0x00000001 #define ULF_NO_ERRNO 0x01000000 extern "C" int __ulock_wait(uint32_t operation, void *addr, uint64_t value, uint32_t timeout); /* timeout is specified in microseconds */ extern "C" int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value); -gb_internal void tpool_wake_addr(Futex *addr) { +gb_internal void futex_signal(Futex *addr) { for (;;) { int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, 0); if (ret >= 0) { @@ -572,7 +565,7 @@ gb_internal void tpool_wake_addr(Futex *addr) { } } -gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { +gb_internal void futex_wait(Futex *addr, Footex val) { for (;;) { int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, val, 0); if (ret >= 0) { @@ -592,14 +585,12 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { } } #elif defined(GB_SYSTEM_WINDOWS) -typedef std::atomic Futex; -typedef volatile int64_t Footex; -gb_internal void tpool_wake_addr(Futex *addr) { +gb_internal void futex_signal(Futex *addr) { WakeByAddressSingle((void *)addr); } -gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) { +gb_internal void futex_wait(Futex *addr, Footex val) { for (;;) { WaitOnAddress(addr, (void *)&val, sizeof(val), INFINITE); if (*addr != val) break;