mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Unify compiler Futex interface
This commit is contained in:
+3
-3
@@ -136,7 +136,7 @@ gb_internal void thread_pool_wait(ThreadPool *pool) {
|
|||||||
break;
|
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;
|
finished_tasks += 1;
|
||||||
}
|
}
|
||||||
if (finished_tasks > 0 && !pool->tasks_left) {
|
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
|
// 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);
|
pool->tasks_left.fetch_sub(1);
|
||||||
|
|
||||||
if (!pool->tasks_left) {
|
if (!pool->tasks_left) {
|
||||||
tpool_wake_addr(&pool->tasks_left);
|
futex_signal(&pool->tasks_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto work_start;
|
goto work_start;
|
||||||
|
|||||||
+17
-26
@@ -41,6 +41,11 @@ struct Thread {
|
|||||||
struct ThreadPool *pool;
|
struct ThreadPool *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::atomic<int32_t> 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_init (BlockingMutex *m);
|
||||||
gb_internal void mutex_destroy (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 <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
typedef std::atomic<int32_t> Futex;
|
gb_internal void futex_signal(Futex *addr) {
|
||||||
typedef volatile int32_t Footex;
|
|
||||||
|
|
||||||
gb_internal void tpool_wake_addr(Futex *addr) {
|
|
||||||
for (;;) {
|
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) {
|
if (ret == -1) {
|
||||||
perror("Futex wake");
|
perror("Futex wake");
|
||||||
GB_PANIC("Failed in futex wake!\n");
|
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 (;;) {
|
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 (ret == -1) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
perror("Futex wait");
|
perror("Futex wait");
|
||||||
@@ -479,14 +481,11 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) {
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/umtx.h>
|
#include <sys/umtx.h>
|
||||||
|
|
||||||
typedef std::atomic<int32_t> Futex;
|
gb_internal void futex_signal(Futex *addr) {
|
||||||
typedef volatile int32_t Footex;
|
|
||||||
|
|
||||||
gb_internal void tpool_wake_addr(Futex *addr) {
|
|
||||||
_umtx_op(addr, UMTX_OP_WAKE, 1, 0, 0);
|
_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 (;;) {
|
for (;;) {
|
||||||
int ret = _umtx_op(addr, UMTX_OP_WAIT_UINT, val, 0, NULL);
|
int ret = _umtx_op(addr, UMTX_OP_WAIT_UINT, val, 0, NULL);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -508,10 +507,7 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) {
|
|||||||
|
|
||||||
#include <sys/futex.h>
|
#include <sys/futex.h>
|
||||||
|
|
||||||
typedef std::atomic<int32_t> Futex;
|
gb_internal void futex_signal(Futex *addr) {
|
||||||
typedef volatile int32_t Footex;
|
|
||||||
|
|
||||||
gb_internal void tpool_wake_addr(Futex *addr) {
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ret = futex((volatile uint32_t *)addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL);
|
int ret = futex((volatile uint32_t *)addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL);
|
||||||
if (ret == -1) {
|
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 (;;) {
|
for (;;) {
|
||||||
int ret = futex((volatile uint32_t *)addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, NULL, NULL);
|
int ret = futex((volatile uint32_t *)addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, NULL, NULL);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
@@ -547,16 +543,13 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) {
|
|||||||
|
|
||||||
#elif defined(GB_SYSTEM_OSX)
|
#elif defined(GB_SYSTEM_OSX)
|
||||||
|
|
||||||
typedef std::atomic<int64_t> Futex;
|
|
||||||
typedef volatile int64_t Footex;
|
|
||||||
|
|
||||||
#define UL_COMPARE_AND_WAIT 0x00000001
|
#define UL_COMPARE_AND_WAIT 0x00000001
|
||||||
#define ULF_NO_ERRNO 0x01000000
|
#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_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);
|
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 (;;) {
|
for (;;) {
|
||||||
int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, 0);
|
int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, 0);
|
||||||
if (ret >= 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 (;;) {
|
for (;;) {
|
||||||
int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, val, 0);
|
int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, val, 0);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
@@ -592,14 +585,12 @@ gb_internal void tpool_wait_on_addr(Futex *addr, Footex val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(GB_SYSTEM_WINDOWS)
|
#elif defined(GB_SYSTEM_WINDOWS)
|
||||||
typedef std::atomic<int64_t> Futex;
|
|
||||||
typedef volatile int64_t Footex;
|
|
||||||
|
|
||||||
gb_internal void tpool_wake_addr(Futex *addr) {
|
gb_internal void futex_signal(Futex *addr) {
|
||||||
WakeByAddressSingle((void *)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 (;;) {
|
for (;;) {
|
||||||
WaitOnAddress(addr, (void *)&val, sizeof(val), INFINITE);
|
WaitOnAddress(addr, (void *)&val, sizeof(val), INFINITE);
|
||||||
if (*addr != val) break;
|
if (*addr != val) break;
|
||||||
|
|||||||
Reference in New Issue
Block a user