Last active
October 10, 2016 09:04
-
-
Save deadtrickster/1576f2e4e60f106a3fd51ae6f66855a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(with-pinned-objects (queue me) | |
(setf (waitqueue-token queue) me) | |
(release-mutex mutex) | |
;; Now we go to sleep using futex-wait. If anyone else | |
;; manages to grab MUTEX and call CONDITION-NOTIFY during | |
;; this comment, it will change the token, and so futex-wait | |
;; returns immediately instead of sleeping. Ergo, no lost | |
;; wakeup. We may get spurious wakeups, but that's ok. | |
(setf status | |
(case (allow-with-interrupts | |
(futex-wait (waitqueue-token-address queue) | |
(get-lisp-obj-address me) | |
;; our way of saying "no | |
;; timeout": | |
(or to-sec -1) | |
(or to-usec 0))) | |
((1) | |
;; 1 = ETIMEDOUT | |
:timeout) | |
(t | |
;; -1 = EWOULDBLOCK, possibly spurious wakeup | |
;; 0 = normal wakeup | |
;; 2 = EINTR, a spurious wakeup | |
:ok)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static inline int sys_futex(void *futex, int op, int val, struct timespec *rel) | |
{ | |
return syscall(SYS_futex, futex, op, val, rel); | |
} | |
int | |
futex_wait(int *lock_word, int oldval, long sec, unsigned long usec) | |
{ | |
struct timespec timeout; | |
int t; | |
if (sec<0) { | |
t = sys_futex(lock_word, futex_wait_op(), oldval, 0); | |
} | |
else { | |
timeout.tv_sec = sec; | |
timeout.tv_nsec = usec * 1000; | |
t = sys_futex(lock_word, futex_wait_op(), oldval, &timeout); | |
} | |
if (t==0) | |
return 0; | |
else if (errno==ETIMEDOUT) | |
return 1; | |
else if (errno==EINTR) | |
return 2; | |
else | |
/* EWOULDBLOCK and others, need to check the lock */ | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment