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 f1bfc54e 2004-05-14 devnull void
22 f1bfc54e 2004-05-14 devnull _clearuproc(void)
23 f1bfc54e 2004-05-14 devnull {
24 f1bfc54e 2004-05-14 devnull int i;
25 f1bfc54e 2004-05-14 devnull
26 f1bfc54e 2004-05-14 devnull /* called right after fork - no locking needed */
27 f1bfc54e 2004-05-14 devnull for(i=0; i<PIDHASH; i++)
28 f1bfc54e 2004-05-14 devnull if(alluproc[i] != T && alluproc[i] != 0)
29 f1bfc54e 2004-05-14 devnull free(alluproc[i]);
30 f1bfc54e 2004-05-14 devnull memset(alluproc, 0, sizeof alluproc);
31 f1bfc54e 2004-05-14 devnull memset(allupid, 0, sizeof allupid);
32 f1bfc54e 2004-05-14 devnull }
33 f1bfc54e 2004-05-14 devnull
34 fd04aace 2003-11-23 devnull Uproc*
35 175b8a53 2004-04-21 devnull _p9uproc(int inhandler)
36 fd04aace 2003-11-23 devnull {
37 175b8a53 2004-04-21 devnull int i, h, pid;
38 fd04aace 2003-11-23 devnull Uproc *up;
39 fd04aace 2003-11-23 devnull
40 175b8a53 2004-04-21 devnull /* for now, assume getpid is fast or cached */
41 fd04aace 2003-11-23 devnull pid = getpid();
42 175b8a53 2004-04-21 devnull
43 175b8a53 2004-04-21 devnull /*
44 175b8a53 2004-04-21 devnull * this part - the lookup - needs to run without locks
45 175b8a53 2004-04-21 devnull * so that it can safely be called from within the notify handler.
46 175b8a53 2004-04-21 devnull * notify calls _p9uproc, and fork and rfork call _p9uproc
47 175b8a53 2004-04-21 devnull * in both parent and child, so if we're in a signal handler,
48 175b8a53 2004-04-21 devnull * we should find something in the table.
49 175b8a53 2004-04-21 devnull */
50 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
51 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
52 175b8a53 2004-04-21 devnull up = alluproc[h];
53 175b8a53 2004-04-21 devnull if(up == nil)
54 175b8a53 2004-04-21 devnull break;
55 175b8a53 2004-04-21 devnull if(allupid[h] == pid)
56 fd04aace 2003-11-23 devnull return up;
57 175b8a53 2004-04-21 devnull if(++h == PIDHASH)
58 175b8a53 2004-04-21 devnull h = 0;
59 fd04aace 2003-11-23 devnull }
60 fd04aace 2003-11-23 devnull
61 b1455f33 2004-04-30 devnull if(inhandler){
62 b1455f33 2004-04-30 devnull fprint(2, "%s: did not find uproc for pid %d in signal handler\n", argv0, pid);
63 b1455f33 2004-04-30 devnull abort();
64 b1455f33 2004-04-30 devnull }
65 fd04aace 2003-11-23 devnull
66 175b8a53 2004-04-21 devnull /* need to allocate */
67 175b8a53 2004-04-21 devnull while((up = mallocz(sizeof(Uproc), 1)) == nil)
68 fd04aace 2003-11-23 devnull sleep(1000);
69 fd04aace 2003-11-23 devnull
70 2e965b33 2004-05-05 devnull /* fprint(2, "alloc uproc for pid %d\n", pid); */
71 b1455f33 2004-04-30 devnull up->pid = pid;
72 175b8a53 2004-04-21 devnull lock(&uproclock);
73 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
74 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
75 175b8a53 2004-04-21 devnull if(alluproc[h]==T || alluproc[h]==nil){
76 175b8a53 2004-04-21 devnull alluproc[h] = up;
77 175b8a53 2004-04-21 devnull allupid[h] = pid;
78 0b424d7b 2004-04-21 devnull unlock(&uproclock);
79 175b8a53 2004-04-21 devnull return up;
80 175b8a53 2004-04-21 devnull }
81 175b8a53 2004-04-21 devnull if(++h == PIDHASH)
82 175b8a53 2004-04-21 devnull h = 0;
83 175b8a53 2004-04-21 devnull }
84 fd04aace 2003-11-23 devnull unlock(&uproclock);
85 175b8a53 2004-04-21 devnull
86 175b8a53 2004-04-21 devnull /* out of pids! */
87 175b8a53 2004-04-21 devnull sysfatal("too many processes in uproc table");
88 175b8a53 2004-04-21 devnull return nil;
89 fd04aace 2003-11-23 devnull }
90 fd04aace 2003-11-23 devnull
91 fd04aace 2003-11-23 devnull void
92 fd04aace 2003-11-23 devnull _p9uprocdie(void)
93 fd04aace 2003-11-23 devnull {
94 175b8a53 2004-04-21 devnull Uproc *up;
95 175b8a53 2004-04-21 devnull int pid, i, h;
96 fd04aace 2003-11-23 devnull
97 fd04aace 2003-11-23 devnull pid = getpid();
98 2e965b33 2004-05-05 devnull /* fprint(2, "reap uproc for pid %d\n", pid); */
99 175b8a53 2004-04-21 devnull h = pid%PIDHASH;
100 175b8a53 2004-04-21 devnull for(i=0; i<PIDHASH; i++){
101 175b8a53 2004-04-21 devnull up = alluproc[h];
102 175b8a53 2004-04-21 devnull if(up == nil)
103 175b8a53 2004-04-21 devnull break;
104 175b8a53 2004-04-21 devnull if(up == T)
105 175b8a53 2004-04-21 devnull continue;
106 175b8a53 2004-04-21 devnull if(allupid[h] == pid){
107 175b8a53 2004-04-21 devnull up = alluproc[h];
108 175b8a53 2004-04-21 devnull alluproc[h] = T;
109 fd04aace 2003-11-23 devnull free(up);
110 175b8a53 2004-04-21 devnull allupid[h] = 0;
111 fd04aace 2003-11-23 devnull }
112 fd04aace 2003-11-23 devnull }
113 fd04aace 2003-11-23 devnull }