2 175b8a53 2004-04-21 devnull * This needs to be callable from a signal handler, so it has been
3 175b8a53 2004-04-21 devnull * written to avoid locks. The only lock is the one used to acquire
4 175b8a53 2004-04-21 devnull * an entry in the table, and we make sure that acquiring is done
5 175b8a53 2004-04-21 devnull * when not in a handler. Lookup and delete do not need locks.
6 175b8a53 2004-04-21 devnull * It's a scan-forward hash table. To avoid breaking chains,
7 175b8a53 2004-04-21 devnull * T ((void*)-1) is used as a non-breaking nil.
10 fd04aace 2003-11-23 devnull #include <u.h>
11 fd04aace 2003-11-23 devnull #include <libc.h>
12 fd04aace 2003-11-23 devnull #include "9proc.h"
14 175b8a53 2004-04-21 devnull enum { PIDHASH = 1021 };
16 175b8a53 2004-04-21 devnull #define T ((void*)-1)
17 175b8a53 2004-04-21 devnull static Uproc *alluproc[PIDHASH];
18 175b8a53 2004-04-21 devnull static int allupid[PIDHASH];
19 fd04aace 2003-11-23 devnull static Lock uproclock;
22 175b8a53 2004-04-21 devnull _p9uproc(int inhandler)
24 175b8a53 2004-04-21 devnull int i, h, pid;
25 fd04aace 2003-11-23 devnull Uproc *up;
27 175b8a53 2004-04-21 devnull /* for now, assume getpid is fast or cached */
28 fd04aace 2003-11-23 devnull pid = getpid();
31 175b8a53 2004-04-21 devnull * this part - the lookup - needs to run without locks
32 175b8a53 2004-04-21 devnull * so that it can safely be called from within the notify handler.
33 175b8a53 2004-04-21 devnull * notify calls _p9uproc, and fork and rfork call _p9uproc
34 175b8a53 2004-04-21 devnull * in both parent and child, so if we're in a signal handler,
35 175b8a53 2004-04-21 devnull * we should find something in the table.
37 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
38 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
39 175b8a53 2004-04-21 devnull up = alluproc[h];
40 175b8a53 2004-04-21 devnull if(up == nil)
42 175b8a53 2004-04-21 devnull if(allupid[h] == pid)
43 fd04aace 2003-11-23 devnull return up;
44 175b8a53 2004-04-21 devnull if(++h == PIDHASH)
48 175b8a53 2004-04-21 devnull if(inhandler)
49 175b8a53 2004-04-21 devnull sysfatal("did not find uproc in signal handler");
51 175b8a53 2004-04-21 devnull /* need to allocate */
52 175b8a53 2004-04-21 devnull while((up = mallocz(sizeof(Uproc), 1)) == nil)
53 fd04aace 2003-11-23 devnull sleep(1000);
55 175b8a53 2004-04-21 devnull up = mallocz(sizeof(Uproc), 1);
56 175b8a53 2004-04-21 devnull lock(&uproclock);
57 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
58 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
59 175b8a53 2004-04-21 devnull if(alluproc[h]==T || alluproc[h]==nil){
60 175b8a53 2004-04-21 devnull alluproc[h] = up;
61 175b8a53 2004-04-21 devnull allupid[h] = pid;
62 0b424d7b 2004-04-21 devnull unlock(&uproclock);
63 175b8a53 2004-04-21 devnull return up;
65 175b8a53 2004-04-21 devnull if(++h == PIDHASH)
68 fd04aace 2003-11-23 devnull unlock(&uproclock);
70 175b8a53 2004-04-21 devnull /* out of pids! */
71 175b8a53 2004-04-21 devnull sysfatal("too many processes in uproc table");
72 175b8a53 2004-04-21 devnull return nil;
76 fd04aace 2003-11-23 devnull _p9uprocdie(void)
78 175b8a53 2004-04-21 devnull Uproc *up;
79 175b8a53 2004-04-21 devnull int pid, i, h;
81 fd04aace 2003-11-23 devnull pid = getpid();
82 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
83 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
84 175b8a53 2004-04-21 devnull up = alluproc[h];
85 175b8a53 2004-04-21 devnull if(up == nil)
87 175b8a53 2004-04-21 devnull if(up == T)
88 175b8a53 2004-04-21 devnull continue;
89 175b8a53 2004-04-21 devnull if(allupid[h] == pid){
90 175b8a53 2004-04-21 devnull up = alluproc[h];
91 175b8a53 2004-04-21 devnull alluproc[h] = T;
92 fd04aace 2003-11-23 devnull free(up);
93 175b8a53 2004-04-21 devnull allupid[h] = 0;