Blame


1 175b8a53 2004-04-21 devnull /*
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.
8 175b8a53 2004-04-21 devnull */
9 175b8a53 2004-04-21 devnull
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"
13 fd04aace 2003-11-23 devnull
14 175b8a53 2004-04-21 devnull enum { PIDHASH = 1021 };
15 175b8a53 2004-04-21 devnull
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;
20 fd04aace 2003-11-23 devnull
21 fd04aace 2003-11-23 devnull Uproc*
22 175b8a53 2004-04-21 devnull _p9uproc(int inhandler)
23 fd04aace 2003-11-23 devnull {
24 175b8a53 2004-04-21 devnull int i, h, pid;
25 fd04aace 2003-11-23 devnull Uproc *up;
26 fd04aace 2003-11-23 devnull
27 175b8a53 2004-04-21 devnull /* for now, assume getpid is fast or cached */
28 fd04aace 2003-11-23 devnull pid = getpid();
29 175b8a53 2004-04-21 devnull
30 175b8a53 2004-04-21 devnull /*
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.
36 175b8a53 2004-04-21 devnull */
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)
41 175b8a53 2004-04-21 devnull break;
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)
45 175b8a53 2004-04-21 devnull h = 0;
46 fd04aace 2003-11-23 devnull }
47 fd04aace 2003-11-23 devnull
48 175b8a53 2004-04-21 devnull if(inhandler)
49 175b8a53 2004-04-21 devnull sysfatal("did not find uproc in signal handler");
50 fd04aace 2003-11-23 devnull
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);
54 fd04aace 2003-11-23 devnull
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;
64 175b8a53 2004-04-21 devnull }
65 175b8a53 2004-04-21 devnull if(++h == PIDHASH)
66 175b8a53 2004-04-21 devnull h = 0;
67 175b8a53 2004-04-21 devnull }
68 fd04aace 2003-11-23 devnull unlock(&uproclock);
69 175b8a53 2004-04-21 devnull
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;
73 fd04aace 2003-11-23 devnull }
74 fd04aace 2003-11-23 devnull
75 fd04aace 2003-11-23 devnull void
76 fd04aace 2003-11-23 devnull _p9uprocdie(void)
77 fd04aace 2003-11-23 devnull {
78 175b8a53 2004-04-21 devnull Uproc *up;
79 175b8a53 2004-04-21 devnull int pid, i, h;
80 fd04aace 2003-11-23 devnull
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)
86 175b8a53 2004-04-21 devnull break;
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;
94 fd04aace 2003-11-23 devnull }
95 fd04aace 2003-11-23 devnull }
96 fd04aace 2003-11-23 devnull }