Commit: 358d80e69b7e1fc2f4e889468dee439e1231a632
Parent: 9482ec737cc5430dda4c54553c010b245cd1e4b7
Author: Randy Palamar
Date: Tue, 8 Apr 2025 12:43:09 -0600
core/lib: properly check for timeout from wait functions
Also just use the Wait functions from Synchronization.lib on
Windows. They don't seem to have any major issues.
For now, the only supported timeout for the library push functions
on w32 for is 0 to poll. The cross process synchronization will
need a rework to be supported on w32. Its fine to just check the
return value on the functions for success.
Diffstat:
6 files changed, 18 insertions(+), 29 deletions(-)
diff --git a/beamformer_work_queue.c b/beamformer_work_queue.c
@@ -60,10 +60,9 @@ try_wait_sync(i32 *sync, i32 timeout_ms, os_wait_on_value_fn *os_wait_on_value)
if (current && atomic_cas(sync, ¤t, 0)) {
result = 1;
break;
- } else if (!timeout_ms) {
- break;
}
- os_wait_on_value(sync, 0, timeout_ms);
+ if (!timeout_ms || !os_wait_on_value(sync, 0, timeout_ms))
+ break;
}
return result;
}
diff --git a/build.sh b/build.sh
@@ -6,7 +6,7 @@ cflags="-march=native -std=c11 -Wall -I./external/include"
#cflags="${cflags} -fsanitize=address,undefined"
#cflags="${cflags} -fproc-stat-report"
#cflags="${cflags} -Rpass-missed=.*"
-libcflags="${cflags} -fPIC -shared -Wno-unused-variable"
+libcflags="${cflags} -fPIC -shared -Wno-unused-function -Wno-unused-variable"
ldflags="-lm"
cc=${CC:-cc}
@@ -30,8 +30,8 @@ MINGW64*)
raylib="libraylib.dll"
main="main_w32.c"
libname="beamformer.dll"
- ldflags="${ldflags} -lgdi32 -lwinmm -lntdll"
- extra_ldflags="-lntdll"
+ ldflags="${ldflags} -lgdi32 -lwinmm -lSynchronization"
+ extra_ldflags="-lSynchronization"
if [ ! ${NO_MATLAB} ]; then
libcflags="${libcflags} -DMATLAB_CONSOLE"
extra_ldflags="${extra_ldflags} -llibmat -llibmex"
diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c
@@ -48,9 +48,9 @@ W32(i32) GetLastError(void);
W32(iptr) MapViewOfFile(iptr, u32, u32, u32, u64);
W32(iptr) OpenFileMappingA(u32, b32, c8 *);
W32(b32) ReadFile(iptr, u8 *, i32, i32 *, void *);
-W32(i32) RtlWaitOnAddress(void *, void *, uz, void *);
W32(void) Sleep(u32);
W32(void) UnmapViewOfFile(iptr);
+W32(b32) WaitOnAddress(void *, void *, uz, i32);
W32(b32) WriteFile(iptr, u8 *, i32, i32 *, void *);
#else
@@ -79,7 +79,7 @@ static OS_WAIT_ON_VALUE_FN(os_wait_on_value)
timeout_value.tv_nsec = (timeout_ms % 1000) * 1000000;
timeout = &timeout_value;
}
- syscall(SYS_futex, value, FUTEX_WAIT, current, timeout, 0, 0);
+ return syscall(SYS_futex, value, FUTEX_WAIT, current, timeout, 0, 0) == 0;
}
static Pipe
@@ -135,13 +135,9 @@ os_open_shared_memory_area(char *name)
static OS_WAIT_ON_VALUE_FN(os_wait_on_value)
{
- i64 *timeout = 0, timeout_value;
- if (timeout_ms != -1) {
- /* TODO(rnp): not sure about this one, but this is how wine converts the ms */
- timeout_value = -(i64)timeout_ms * 10000;
- timeout = &timeout_value;
- }
- RtlWaitOnAddress(value, ¤t, sizeof(*value), timeout);
+ /* TODO(rnp): this doesn't work across processes on win32 */
+ return 0;
+ return WaitOnAddress(value, ¤t, sizeof(*value), timeout_ms);
}
static Pipe
@@ -345,7 +341,7 @@ send_data(char *pipe_name, char *shm_name, void *data, u32 data_size)
if (result) {
beamformer_start_compute(shm_name, 0);
/* TODO(rnp): should we just set timeout on acquiring the lock instead of this? */
- os_wait_on_value(&g_bp->raw_data_sync, 0, -1);
+ try_wait_sync(&g_bp->raw_data_sync, -1, os_wait_on_value);
}
return result;
}
diff --git a/os_linux.c b/os_linux.c
@@ -255,12 +255,12 @@ os_create_thread(Arena arena, iptr user_context, s8 name, os_thread_entry_point_
static OS_WAIT_ON_VALUE_FN(os_wait_on_value)
{
struct timespec *timeout = 0, timeout_value;
- if (timeout_ms != -1) {
+ if (timeout_ms != (u32)-1) {
timeout_value.tv_sec = timeout_ms / 1000;
timeout_value.tv_nsec = (timeout_ms % 1000) * 1000000;
timeout = &timeout_value;
}
- syscall(SYS_futex, value, FUTEX_WAIT, current, timeout, 0, 0);
+ return syscall(SYS_futex, value, FUTEX_WAIT, current, timeout, 0, 0) == 0;
}
static OS_WAKE_WAITERS_FN(os_wake_waiters)
diff --git a/os_win32.c b/os_win32.c
@@ -96,9 +96,9 @@ W32(void *) MapViewOfFile(iptr, u32, u32, u32, u64);
W32(b32) ReadDirectoryChangesW(iptr, u8 *, u32, b32, u32, u32 *, void *, void *);
W32(b32) ReadFile(iptr, u8 *, i32, i32 *, void *);
W32(b32) ReleaseSemaphore(iptr, i64, i64 *);
-W32(i32) RtlWakeAddressAll(void *);
-W32(i32) RtlWaitOnAddress(void *, void *, uz, void *);
W32(i32) SetThreadDescription(iptr, u16 *);
+W32(b32) WaitOnAddress(void *, void *, uz, u32);
+W32(i32) WakeByAddressAll(void *);
W32(b32) WriteFile(iptr, u8 *, i32, i32 *, void *);
W32(void *) VirtualAlloc(u8 *, iz, u32, u32);
W32(b32) VirtualFree(u8 *, iz, u32);
@@ -321,20 +321,14 @@ os_create_thread(Arena arena, iptr user_context, s8 name, os_thread_entry_point_
static OS_WAIT_ON_VALUE_FN(os_wait_on_value)
{
- i64 *timeout = 0, timeout_value;
- if (timeout_ms != -1) {
- /* TODO(rnp): not sure about this one, but this is how wine converts the ms */
- timeout_value = -(i64)timeout_ms * 10000;
- timeout = &timeout_value;
- }
- RtlWaitOnAddress(value, ¤t, sizeof(*value), timeout);
+ return WaitOnAddress(value, ¤t, sizeof(*value), timeout_ms);
}
static OS_WAKE_WAITERS_FN(os_wake_waiters)
{
if (sync) {
atomic_inc(sync, 1);
- RtlWakeAddressAll(sync);
+ WakeByAddressAll(sync);
}
}
diff --git a/util.h b/util.h
@@ -252,7 +252,7 @@ typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn);
#define OS_READ_FILE_FN(name) iz name(iptr file, void *buf, iz size)
typedef OS_READ_FILE_FN(os_read_file_fn);
-#define OS_WAIT_ON_VALUE_FN(name) void name(i32 *value, i32 current, i32 timeout_ms)
+#define OS_WAIT_ON_VALUE_FN(name) b32 name(i32 *value, i32 current, u32 timeout_ms)
typedef OS_WAIT_ON_VALUE_FN(os_wait_on_value_fn);
#define OS_WAKE_WAITERS_FN(name) void name(i32 *sync)