Data-Graph-Shared
view release on metacpan or search on metacpan
int notify_fd;
int backing_fd;
} GraphHandle;
/* ================================================================
* Mutex (same pattern as Heap)
* ================================================================ */
static const struct timespec graph_lock_timeout = { 2, 0 };
static inline int graph_pid_alive(uint32_t pid) {
if (pid == 0) return 1;
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
}
static inline void graph_mutex_lock(GraphHeader *hdr) {
uint32_t mypid = GRAPH_MUTEX_BIT | ((uint32_t)getpid() & GRAPH_MUTEX_PID);
for (int spin = 0; ; spin++) {
uint32_t expected = 0;
if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
#endif
continue;
}
__atomic_add_fetch(&hdr->mutex_waiters, 1, __ATOMIC_RELAXED);
uint32_t cur = __atomic_load_n(&hdr->mutex, __ATOMIC_RELAXED);
if (cur != 0) {
long rc = syscall(SYS_futex, &hdr->mutex, FUTEX_WAIT, cur,
&graph_lock_timeout, NULL, 0);
if (rc == -1 && errno == ETIMEDOUT && cur >= GRAPH_MUTEX_BIT) {
uint32_t pid = cur & GRAPH_MUTEX_PID;
if (!graph_pid_alive(pid) &&
__atomic_compare_exchange_n(&hdr->mutex, &cur, 0,
0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) {
/* Recovered â wake one waiter so it can proceed. */
syscall(SYS_futex, &hdr->mutex, FUTEX_WAKE, 1, NULL, NULL, 0);
}
}
}
__atomic_sub_fetch(&hdr->mutex_waiters, 1, __ATOMIC_RELAXED);
spin = 0;
}
( run in 2.111 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )