2 * This needs to be callable from a signal handler, so it has been
3 * written to avoid locks. The only lock is the one used to acquire
4 * an entry in the table, and we make sure that acquiring is done
5 * when not in a handler. Lookup and delete do not need locks.
6 * It's a scan-forward hash table. To avoid breaking chains,
7 * T ((void*)-1) is used as a non-breaking nil.
14 enum { PIDHASH = 1021 };
17 static Uproc *alluproc[PIDHASH];
18 static int allupid[PIDHASH];
19 static Lock uproclock;
26 /* called right after fork - no locking needed */
27 for(i=0; i<PIDHASH; i++)
28 if(alluproc[i] != T && alluproc[i] != 0)
30 memset(alluproc, 0, sizeof alluproc);
31 memset(allupid, 0, sizeof allupid);
35 _p9uproc(int inhandler)
40 /* for now, assume getpid is fast or cached */
44 * this part - the lookup - needs to run without locks
45 * so that it can safely be called from within the notify handler.
46 * notify calls _p9uproc, and fork and rfork call _p9uproc
47 * in both parent and child, so if we're in a signal handler,
48 * we should find something in the table.
51 for(i=0; i<PIDHASH; i++){
62 fprint(2, "%s: did not find uproc for pid %d in signal handler\n", argv0, pid);
66 /* need to allocate */
67 while((up = mallocz(sizeof(Uproc), 1)) == nil)
70 /* fprint(2, "alloc uproc for pid %d\n", pid); */
74 for(i=0; i<PIDHASH; i++){
75 if(alluproc[h]==T || alluproc[h]==nil){
87 sysfatal("too many processes in uproc table");
98 /* fprint(2, "reap uproc for pid %d\n", pid); */
100 for(i=0; i<PIDHASH; i++){
106 if(allupid[h] == pid){