Browse Source

Unify compiler `Futex` interface

gingerBill 2 years ago
parent
commit
60d0390ef8
2 changed files with 20 additions and 29 deletions
  1. 3 3
      src/thread_pool.cpp
  2. 17 26
      src/threading.cpp

+ 3 - 3
src/thread_pool.cpp

@@ -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
src/threading.cpp

@@ -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;
-typedef volatile int32_t Footex;
-
-gb_internal void tpool_wake_addr(Futex *addr) {
+gb_internal void futex_signal(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;
-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);
 	_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;
-typedef volatile int32_t Footex;
-
-gb_internal void tpool_wake_addr(Futex *addr) {
+gb_internal void futex_signal(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;