summaryrefslogtreecommitdiffstats
path: root/src/lib9/rendez.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-10-01 02:53:00 +0000
committerrsc <devnull@localhost>2003-10-01 02:53:00 +0000
commita46395ecf932ea4e91ad047e92d1c70395e15673 (patch)
treef6f6d26edf773119b7e8e12d1b225c556c30bda5 /src/lib9/rendez.c
parenta995e477ffb4dd1184da87e9e46a9e57f3178c63 (diff)
downloadplan9port-a46395ecf932ea4e91ad047e92d1c70395e15673.tar.gz
plan9port-a46395ecf932ea4e91ad047e92d1c70395e15673.zip
More Darwin.
Diffstat (limited to 'src/lib9/rendez.c')
-rw-r--r--src/lib9/rendez.c180
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;
-}
-