#include <u.h> | |
#include <signal.h> | |
#include <libc.h> | |
#define DBG 0 | |
static void | |
ign(int x) | |
{ | |
USED(x); | |
} | |
void /*__attribute__((constructor))*/ | |
ignusr1(int restart) | |
{ | |
struct sigaction sa; | |
memset(&sa, 0, sizeof sa); | |
sa.sa_handler = ign; | |
sigemptyset(&sa.sa_mask); | |
sigaddset(&sa.sa_mask, SIGUSR1); | |
if(restart) | |
sa.sa_flags = SA_RESTART; | |
sigaction(SIGUSR1, &sa, nil); | |
} | |
void | |
_procsleep(_Procrend *r) | |
{ | |
sigset_t mask; | |
/* | |
* Go to sleep. | |
* | |
* Block USR1, set the handler to interrupt system calls, | |
* unlock the vouslock so our waker can wake us, | |
* and then suspend. | |
*/ | |
r->asleep = 1; | |
r->pid = getpid(); | |
sigprocmask(SIG_SETMASK, nil, &mask); | |
sigaddset(&mask, SIGUSR1); | |
sigprocmask(SIG_SETMASK, &mask, nil); | |
ignusr1(0); | |
unlock(r->l); | |
sigdelset(&mask, SIGUSR1); | |
sigsuspend(&mask); | |
/* | |
* We're awake. Make USR1 not interrupt system calls. | |
*/ | |
ignusr1(1); | |
assert(r->asleep == 0); | |
lock(r->l); | |
} | |
void | |
_procwakeup(_Procrend *r) | |
{ | |
r->asleep = 0; | |
assert(r->pid >= 1); | |
kill(r->pid, SIGUSR1); | |
} |