From a46395ecf932ea4e91ad047e92d1c70395e15673 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 1 Oct 2003 02:53:00 +0000 Subject: More Darwin. --- src/lib9/rendez.c | 180 ------------------------------------------------------ 1 file changed, 180 deletions(-) delete mode 100644 src/lib9/rendez.c (limited to 'src/lib9/rendez.c') 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 -#include - -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; -} - -- cgit v1.2.3