diff options
| author | rsc <devnull@localhost> | 2003-10-01 02:53:00 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2003-10-01 02:53:00 +0000 |
| commit | a46395ecf932ea4e91ad047e92d1c70395e15673 (patch) | |
| tree | f6f6d26edf773119b7e8e12d1b225c556c30bda5 /src/lib9/rendez.c | |
| parent | a995e477ffb4dd1184da87e9e46a9e57f3178c63 (diff) | |
| download | plan9port-a46395ecf932ea4e91ad047e92d1c70395e15673.tar.gz plan9port-a46395ecf932ea4e91ad047e92d1c70395e15673.zip | |
More Darwin.
Diffstat (limited to 'src/lib9/rendez.c')
| -rw-r--r-- | src/lib9/rendez.c | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/src/lib9/rendez.c b/src/lib9/rendez.c deleted file mode 100644 index 320bd11a..00000000 --- a/src/lib9/rendez.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - NAME - rendezvous - user level process synchronization - - SYNOPSIS - ulong rendezvous(ulong tag, ulong value) - - DESCRIPTION - The rendezvous system call allows two processes to synchro- - nize and exchange a value. In conjunction with the shared - memory system calls (see segattach(2) and fork(2)), it - enables parallel programs to control their scheduling. - - Two processes wishing to synchronize call rendezvous with a - common tag, typically an address in memory they share. One - process will arrive at the rendezvous first; it suspends - execution until a second arrives. When a second process - meets the rendezvous the value arguments are exchanged - between the processes and returned as the result of the - respective rendezvous system calls. Both processes are - awakened when the rendezvous succeeds. - - The set of tag values which two processes may use to - rendezvous-their tag space-is inherited when a process - forks, unless RFREND is set in the argument to rfork; see - fork(2). - - If a rendezvous is interrupted the return value is ~0, so - that value should not be used in normal communication. - - * This simulates rendezvous with shared memory, pause, and SIGUSR1. - */ - -#include <signal.h> -#include <lib9.h> - -enum -{ - VOUSHASH = 257, -}; - -typedef struct Vous Vous; -struct Vous -{ - Vous *link; - Lock lk; - int pid; - ulong val; - ulong tag; -}; - -static void -ign(int x) -{ - USED(x); -} - -void /*__attribute__((constructor))*/ -ignusr1(void) -{ - signal(SIGUSR1, ign); -} - -static Vous vouspool[2048]; -static int nvousused; -static Vous *vousfree; -static Vous *voushash[VOUSHASH]; -static Lock vouslock; - -static Vous* -getvous(void) -{ - Vous *v; - - if(vousfree){ - v = vousfree; - vousfree = v->link; - }else if(nvousused < nelem(vouspool)) - v = &vouspool[nvousused++]; - else - abort(); - return v; -} - -static void -putvous(Vous *v) -{ - lock(&vouslock); - v->link = vousfree; - vousfree = v; - unlock(&vouslock); -} - -static Vous* -findvous(ulong tag, ulong val, int pid) -{ - int h; - Vous *v, **l; - - lock(&vouslock); - h = tag%VOUSHASH; - for(l=&voushash[h], v=*l; v; l=&(*l)->link, v=*l){ - if(v->tag == tag){ - *l = v->link; - unlock(&vouslock); - return v; - } - } - v = getvous(); - v->pid = pid; - v->link = voushash[h]; - v->val = val; - v->tag = tag; - lock(&v->lk); - voushash[h] = v; - unlock(&vouslock); - return v; -} - -#define DBG 0 -ulong -rendezvous(ulong tag, ulong val) -{ - int me, vpid; - ulong rval; - Vous *v; - sigset_t mask; - - me = getpid(); - v = findvous(tag, val, me); - if(v->pid == me){ - if(DBG)fprint(2, "pid is %d tag %lux, sleeping\n", me, tag); - /* - * No rendezvous partner was found; the next guy - * through will find v and wake us, so we must go - * to sleep. - * - * To go to sleep: - * 1. disable USR1 signals. - * 2. unlock v->lk (tells waker okay to signal us). - * 3. atomically suspend and enable USR1 signals. - * - * The call to ignusr1() could be done once at - * process creation instead of every time through rendezvous. - */ - v->val = val; - ignusr1(); - sigprocmask(SIG_SETMASK, NULL, &mask); - sigaddset(&mask, SIGUSR1); - sigprocmask(SIG_SETMASK, &mask, NULL); - sigdelset(&mask, SIGUSR1); - unlock(&v->lk); - sigsuspend(&mask); - rval = v->val; - if(DBG)fprint(2, "pid is %d, awake\n", me); - putvous(v); - }else{ - /* - * Found someone to meet. Wake him: - * - * A. lock v->lk (waits for him to get to his step 2) - * B. send a USR1 - * - * He won't get the USR1 until he suspends, which - * means it must wake him up (it can't get delivered - * before he sleeps). - */ - vpid = v->pid; - lock(&v->lk); - rval = v->val; - v->val = val; - unlock(&v->lk); - if(kill(vpid, SIGUSR1) < 0){ - if(DBG)fprint(2, "pid is %d, kill %d failed: %r\n", me, vpid); - abort(); - } - } - return rval; -} - |
