Skip to content

Instantly share code, notes, and snippets.

@kawaii-ghost
Last active May 20, 2025 00:16
Show Gist options
  • Save kawaii-ghost/c5ca98040972741b04d6935bc5164439 to your computer and use it in GitHub Desktop.
Save kawaii-ghost/c5ca98040972741b04d6935bc5164439 to your computer and use it in GitHub Desktop.
Implement WaitOnAddress API on Linux (rev 2)
static bool WaitOnAddress(volatile void *Address, void *CompareAddress, size_t AddressSize, uint32_t Milliseconds) {
struct timespec ts;
struct timespec *timeout = NULL;
if (Milliseconds != UINT_MAX) {
ts.tv_sec = Milliseconds / 1000;
ts.tv_nsec = (Milliseconds % 1000) * 1000000;
timeout = &ts;
}
uint32_t shared_value = atomic_load((atomic_uintptr_t*)Address);
uint32_t expected_value = *(uint32_t*)CompareAddress;
if (shared_value == expected_value) {
int result = futex((uint32_t*)Address, FUTEX_WAIT_PRIVATE, expected_value, timeout, NULL, 0);
if (result == -1) {
if (errno == ETIMEDOUT) {
return false;
} else {
perror("futex wait (WaitOnAddress)");
return false;
}
}
return true;
} else {
return false;
}
}
static void WakeByAddressAll(void *Address) {
if (futex((uint32_t*)Address, FUTEX_WAKE_PRIVATE, 128, NULL, NULL, 0) == -1) {
perror("futex wake (WakeByAddressAll)");
}
}
static void WakeByAddressSingle(void *Address) {
if (futex((uint32_t*)Address, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0) == -1) {
perror("futex wake (WakeByAddressSingle)");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment