#ifndef _THR_DFLY_UMTX_H_
#define _THR_DFLY_UMTX_H_
#include <unistd.h>
#define cpu_pause() __asm __volatile("pause":::"memory")
typedef int umtx_t;
int __thr_umtx_lock(volatile umtx_t *mtx, int id, int timo);
int __thr_umtx_timedlock(volatile umtx_t *mtx, int id,
const struct timespec *timeout);
void __thr_umtx_unlock(volatile umtx_t *mtx, int v, int id);
static inline void
_thr_umtx_init(volatile umtx_t *mtx)
{
*mtx = 0;
}
static inline int
_thr_umtx_trylock(volatile umtx_t *mtx, int id, int temporary)
{
if (temporary)
sigblockall();
if (atomic_cmpset_acq_int(mtx, 0, id))
return (0);
cpu_pause();
if (atomic_cmpset_acq_int(mtx, 0, id))
return (0);
cpu_pause();
if (atomic_cmpset_acq_int(mtx, 0, id))
return (0);
if (temporary)
sigunblockall();
return (EBUSY);
}
static inline int
_thr_umtx_lock(volatile umtx_t *mtx, int id, int temporary)
{
int res;
if (temporary)
sigblockall();
if (atomic_cmpset_acq_int(mtx, 0, id))
return (0);
res = __thr_umtx_lock(mtx, id, 0);
if (res && temporary)
sigunblockall();
return res;
}
static inline int
_thr_umtx_timedlock(volatile umtx_t *mtx, int id,
const struct timespec *timeout, int temporary)
{
int res;
if (temporary)
sigblockall();
if (atomic_cmpset_acq_int(mtx, 0, id)) {
return (0);
}
res = __thr_umtx_timedlock(mtx, id, timeout);
if (res && temporary)
sigunblockall();
return res;
}
static inline void
_thr_umtx_unlock(volatile umtx_t *mtx, int id, int temporary)
{
int v;
v = atomic_swap_int(mtx, 0);
if (v != id)
__thr_umtx_unlock(mtx, v, id);
if (temporary)
sigunblockall();
}
int _thr_umtx_wait(volatile umtx_t *mtx, umtx_t exp,
const struct timespec *timeout, int clockid);
int _thr_umtx_wait_intr(volatile umtx_t *mtx, umtx_t exp);
void _thr_umtx_wake(volatile umtx_t *mtx, int count);
#endif