blob: 9f2a6a101e698b98079de8dc8bb67aa225b3c65c [file] [log] [blame]
#pragma once
#include "atomic.h"
#include <limits.h>
#include <zircon/syscalls.h>
#include <stdatomic.h>
void __wait(atomic_int* futex, atomic_int* waiters, int current_value);
/* Self-synchronized-destruction-safe lock functions */
#define UNLOCKED 0
#define LOCKED_NO_WAITERS 1
#define LOCKED_MAYBE_WAITERS 2
static inline void lock(atomic_int* l) {
if (a_cas_shim(l, UNLOCKED, LOCKED_NO_WAITERS)) {
a_cas_shim(l, LOCKED_NO_WAITERS, LOCKED_MAYBE_WAITERS);
do
__wait(l, UNLOCKED, LOCKED_MAYBE_WAITERS);
while (a_cas_shim(l, UNLOCKED, LOCKED_MAYBE_WAITERS));
}
}
static inline void unlock(atomic_int* l) {
if (atomic_exchange(l, UNLOCKED) == LOCKED_MAYBE_WAITERS)
_zx_futex_wake(l, 1);
}
static inline void unlock_requeue(atomic_int* l, zx_futex_t* r) {
atomic_store(l, UNLOCKED);
_zx_futex_requeue(l, /* wake count */ 0, /* l futex value */ UNLOCKED,
r, /* requeue count */ 1, /* requeue owner */ ZX_HANDLE_INVALID);
}