Blame


1 f1e8706d 2004-12-27 devnull #include "threadimpl.h"
2 f1e8706d 2004-12-27 devnull
3 4753f069 2005-01-17 devnull #undef exits
4 4753f069 2005-01-17 devnull #undef _exits
5 4753f069 2005-01-17 devnull
6 a620761c 2005-01-06 devnull static int
7 a620761c 2005-01-06 devnull timefmt(Fmt *fmt)
8 a620761c 2005-01-06 devnull {
9 a620761c 2005-01-06 devnull static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
10 a620761c 2005-01-06 devnull "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
11 a620761c 2005-01-06 devnull vlong ns;
12 a620761c 2005-01-06 devnull Tm tm;
13 a620761c 2005-01-06 devnull ns = nsec();
14 a620761c 2005-01-06 devnull tm = *localtime(time(0));
15 a620761c 2005-01-06 devnull return fmtprint(fmt, "%s %2d %02d:%02d:%02d.%03d",
16 a620761c 2005-01-06 devnull mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
17 a620761c 2005-01-06 devnull (int)(ns%1000000000)/1000000);
18 a620761c 2005-01-06 devnull }
19 a620761c 2005-01-06 devnull
20 f1e8706d 2004-12-27 devnull /*
21 f1e8706d 2004-12-27 devnull * spin locks
22 f1e8706d 2004-12-27 devnull */
23 f1e8706d 2004-12-27 devnull extern int _tas(int*);
24 f1e8706d 2004-12-27 devnull
25 f1e8706d 2004-12-27 devnull void
26 f1e8706d 2004-12-27 devnull _threadunlock(Lock *l, ulong pc)
27 f1e8706d 2004-12-27 devnull {
28 f1e8706d 2004-12-27 devnull USED(pc);
29 f1e8706d 2004-12-27 devnull
30 f1e8706d 2004-12-27 devnull l->held = 0;
31 f1e8706d 2004-12-27 devnull }
32 f1e8706d 2004-12-27 devnull
33 f1e8706d 2004-12-27 devnull int
34 f1e8706d 2004-12-27 devnull _threadlock(Lock *l, int block, ulong pc)
35 f1e8706d 2004-12-27 devnull {
36 f1e8706d 2004-12-27 devnull int i;
37 a620761c 2005-01-06 devnull static int first=1;
38 a0a331aa 2005-01-06 devnull if(first) {first=0; fmtinstall('\001', timefmt);}
39 f1e8706d 2004-12-27 devnull
40 f1e8706d 2004-12-27 devnull USED(pc);
41 f1e8706d 2004-12-27 devnull
42 f1e8706d 2004-12-27 devnull /* once fast */
43 f1e8706d 2004-12-27 devnull if(!_tas(&l->held))
44 f1e8706d 2004-12-27 devnull return 1;
45 f1e8706d 2004-12-27 devnull if(!block)
46 f1e8706d 2004-12-27 devnull return 0;
47 f1e8706d 2004-12-27 devnull
48 f1e8706d 2004-12-27 devnull /* a thousand times pretty fast */
49 815552b9 2005-01-06 devnull for(i=0; i<1000; i++){
50 f1e8706d 2004-12-27 devnull if(!_tas(&l->held))
51 f1e8706d 2004-12-27 devnull return 1;
52 f1e8706d 2004-12-27 devnull sched_yield();
53 f1e8706d 2004-12-27 devnull }
54 a0a331aa 2005-01-06 devnull /* now increasingly slow */
55 a620761c 2005-01-06 devnull for(i=0; i<10; i++){
56 a620761c 2005-01-06 devnull if(!_tas(&l->held))
57 a620761c 2005-01-06 devnull return 1;
58 a620761c 2005-01-06 devnull usleep(1);
59 a620761c 2005-01-06 devnull }
60 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop1 %p from %lux\n", argv0, l, pc);
61 a620761c 2005-01-06 devnull for(i=0; i<10; i++){
62 a620761c 2005-01-06 devnull if(!_tas(&l->held))
63 a620761c 2005-01-06 devnull return 1;
64 a620761c 2005-01-06 devnull usleep(10);
65 a620761c 2005-01-06 devnull }
66 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop2 %p from %lux\n", argv0, l, pc);
67 a620761c 2005-01-06 devnull for(i=0; i<10; i++){
68 a620761c 2005-01-06 devnull if(!_tas(&l->held))
69 a620761c 2005-01-06 devnull return 1;
70 a620761c 2005-01-06 devnull usleep(100);
71 a620761c 2005-01-06 devnull }
72 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop3 %p from %lux\n", argv0, l, pc);
73 a620761c 2005-01-06 devnull for(i=0; i<10; i++){
74 a620761c 2005-01-06 devnull if(!_tas(&l->held))
75 a620761c 2005-01-06 devnull return 1;
76 a620761c 2005-01-06 devnull usleep(1000);
77 a620761c 2005-01-06 devnull }
78 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop4 %p from %lux\n", argv0, l, pc);
79 a620761c 2005-01-06 devnull for(i=0; i<10; i++){
80 a620761c 2005-01-06 devnull if(!_tas(&l->held))
81 a620761c 2005-01-06 devnull return 1;
82 a620761c 2005-01-06 devnull usleep(10*1000);
83 a620761c 2005-01-06 devnull }
84 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop5 %p from %lux\n", argv0, l, pc);
85 f1e8706d 2004-12-27 devnull for(i=0; i<1000; i++){
86 f1e8706d 2004-12-27 devnull if(!_tas(&l->held))
87 f1e8706d 2004-12-27 devnull return 1;
88 f1e8706d 2004-12-27 devnull usleep(100*1000);
89 f1e8706d 2004-12-27 devnull }
90 a0a331aa 2005-01-06 devnull fprint(2, "%\001 %s: lock loop6 %p from %lux\n", argv0, l, pc);
91 f1e8706d 2004-12-27 devnull /* take your time */
92 f1e8706d 2004-12-27 devnull while(_tas(&l->held))
93 f1e8706d 2004-12-27 devnull usleep(1000*1000);
94 f1e8706d 2004-12-27 devnull return 1;
95 f1e8706d 2004-12-27 devnull }
96 f1e8706d 2004-12-27 devnull
97 f1e8706d 2004-12-27 devnull /*
98 f1e8706d 2004-12-27 devnull * sleep and wakeup
99 f1e8706d 2004-12-27 devnull */
100 f1e8706d 2004-12-27 devnull static void
101 f1e8706d 2004-12-27 devnull ign(int x)
102 f1e8706d 2004-12-27 devnull {
103 f1e8706d 2004-12-27 devnull USED(x);
104 f1e8706d 2004-12-27 devnull }
105 f1e8706d 2004-12-27 devnull
106 f1e8706d 2004-12-27 devnull static void /*__attribute__((constructor))*/
107 f1e8706d 2004-12-27 devnull ignusr1(int restart)
108 f1e8706d 2004-12-27 devnull {
109 f1e8706d 2004-12-27 devnull struct sigaction sa;
110 f1e8706d 2004-12-27 devnull
111 f1e8706d 2004-12-27 devnull memset(&sa, 0, sizeof sa);
112 f1e8706d 2004-12-27 devnull sa.sa_handler = ign;
113 f1e8706d 2004-12-27 devnull sigemptyset(&sa.sa_mask);
114 f1e8706d 2004-12-27 devnull sigaddset(&sa.sa_mask, SIGUSR1);
115 f1e8706d 2004-12-27 devnull if(restart)
116 f1e8706d 2004-12-27 devnull sa.sa_flags = SA_RESTART;
117 f1e8706d 2004-12-27 devnull sigaction(SIGUSR1, &sa, nil);
118 f1e8706d 2004-12-27 devnull }
119 f1e8706d 2004-12-27 devnull
120 f1e8706d 2004-12-27 devnull void
121 f1e8706d 2004-12-27 devnull _procsleep(_Procrendez *r)
122 f1e8706d 2004-12-27 devnull {
123 f1e8706d 2004-12-27 devnull sigset_t mask;
124 f1e8706d 2004-12-27 devnull
125 f1e8706d 2004-12-27 devnull /*
126 f1e8706d 2004-12-27 devnull * Go to sleep.
127 f1e8706d 2004-12-27 devnull *
128 f1e8706d 2004-12-27 devnull * Block USR1, set the handler to interrupt system calls,
129 f1e8706d 2004-12-27 devnull * unlock the vouslock so our waker can wake us,
130 f1e8706d 2004-12-27 devnull * and then suspend.
131 f1e8706d 2004-12-27 devnull */
132 955a2ca7 2004-12-27 devnull again:
133 f1e8706d 2004-12-27 devnull r->asleep = 1;
134 f1e8706d 2004-12-27 devnull r->pid = getpid();
135 f1e8706d 2004-12-27 devnull
136 f1e8706d 2004-12-27 devnull sigprocmask(SIG_SETMASK, nil, &mask);
137 f1e8706d 2004-12-27 devnull sigaddset(&mask, SIGUSR1);
138 f1e8706d 2004-12-27 devnull sigprocmask(SIG_SETMASK, &mask, nil);
139 f1e8706d 2004-12-27 devnull ignusr1(0);
140 f1e8706d 2004-12-27 devnull unlock(r->l);
141 f1e8706d 2004-12-27 devnull sigdelset(&mask, SIGUSR1);
142 f1e8706d 2004-12-27 devnull sigsuspend(&mask);
143 f1e8706d 2004-12-27 devnull
144 f1e8706d 2004-12-27 devnull /*
145 f1e8706d 2004-12-27 devnull * We're awake. Make USR1 not interrupt system calls.
146 f1e8706d 2004-12-27 devnull */
147 f1e8706d 2004-12-27 devnull lock(r->l);
148 955a2ca7 2004-12-27 devnull ignusr1(1);
149 955a2ca7 2004-12-27 devnull if(r->asleep && r->pid == getpid()){
150 955a2ca7 2004-12-27 devnull /* Didn't really wake up - signal from something else */
151 955a2ca7 2004-12-27 devnull goto again;
152 955a2ca7 2004-12-27 devnull }
153 f1e8706d 2004-12-27 devnull }
154 f1e8706d 2004-12-27 devnull
155 f1e8706d 2004-12-27 devnull void
156 a0a331aa 2005-01-06 devnull _procwakeupandunlock(_Procrendez *r)
157 f1e8706d 2004-12-27 devnull {
158 a0a331aa 2005-01-06 devnull int pid;
159 a0a331aa 2005-01-06 devnull
160 a0a331aa 2005-01-06 devnull pid = 0;
161 f1e8706d 2004-12-27 devnull if(r->asleep){
162 f1e8706d 2004-12-27 devnull r->asleep = 0;
163 f1e8706d 2004-12-27 devnull assert(r->pid >= 1);
164 a0a331aa 2005-01-06 devnull pid = r->pid;
165 f1e8706d 2004-12-27 devnull }
166 a0a331aa 2005-01-06 devnull assert(r->l);
167 a0a331aa 2005-01-06 devnull unlock(r->l);
168 a0a331aa 2005-01-06 devnull if(pid)
169 a0a331aa 2005-01-06 devnull kill(pid, SIGUSR1);
170 f1e8706d 2004-12-27 devnull }
171 f1e8706d 2004-12-27 devnull
172 f1e8706d 2004-12-27 devnull /*
173 f1e8706d 2004-12-27 devnull * process creation and exit
174 f1e8706d 2004-12-27 devnull */
175 f1e8706d 2004-12-27 devnull typedef struct Stackfree Stackfree;
176 f1e8706d 2004-12-27 devnull struct Stackfree
177 f1e8706d 2004-12-27 devnull {
178 f1e8706d 2004-12-27 devnull Stackfree *next;
179 f1e8706d 2004-12-27 devnull int pid;
180 a620761c 2005-01-06 devnull int pid1;
181 f1e8706d 2004-12-27 devnull };
182 f1e8706d 2004-12-27 devnull static Lock stacklock;
183 f1e8706d 2004-12-27 devnull static Stackfree *stackfree;
184 f1e8706d 2004-12-27 devnull
185 f1e8706d 2004-12-27 devnull static void
186 a620761c 2005-01-06 devnull delayfreestack(uchar *stk, int pid, int pid1)
187 f1e8706d 2004-12-27 devnull {
188 f1e8706d 2004-12-27 devnull Stackfree *sf;
189 f1e8706d 2004-12-27 devnull
190 f1e8706d 2004-12-27 devnull sf = (Stackfree*)stk;
191 a620761c 2005-01-06 devnull sf->pid = pid;
192 a620761c 2005-01-06 devnull sf->pid1 = pid1;
193 f1e8706d 2004-12-27 devnull lock(&stacklock);
194 f1e8706d 2004-12-27 devnull sf->next = stackfree;
195 f1e8706d 2004-12-27 devnull stackfree = sf;
196 f1e8706d 2004-12-27 devnull unlock(&stacklock);
197 f1e8706d 2004-12-27 devnull }
198 f1e8706d 2004-12-27 devnull
199 f1e8706d 2004-12-27 devnull static void
200 f1e8706d 2004-12-27 devnull dofreestacks(void)
201 f1e8706d 2004-12-27 devnull {
202 f1e8706d 2004-12-27 devnull Stackfree *sf, *last, *next;
203 f1e8706d 2004-12-27 devnull
204 f1e8706d 2004-12-27 devnull if(stackfree==nil || !canlock(&stacklock))
205 f1e8706d 2004-12-27 devnull return;
206 f1e8706d 2004-12-27 devnull
207 f1e8706d 2004-12-27 devnull for(last=nil,sf=stackfree; sf; last=sf,sf=next){
208 f1e8706d 2004-12-27 devnull next = sf->next;
209 a620761c 2005-01-06 devnull if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH)
210 a620761c 2005-01-06 devnull if(sf->pid1 >= 1 && kill(sf->pid1, 0) < 0 && errno == ESRCH){
211 f1e8706d 2004-12-27 devnull free(sf);
212 2c87dda8 2004-12-28 devnull if(last)
213 2c87dda8 2004-12-28 devnull last->next = next;
214 2c87dda8 2004-12-28 devnull else
215 2c87dda8 2004-12-28 devnull stackfree = next;
216 f1e8706d 2004-12-27 devnull sf = last;
217 f1e8706d 2004-12-27 devnull }
218 f1e8706d 2004-12-27 devnull }
219 2c87dda8 2004-12-28 devnull unlock(&stacklock);
220 2c87dda8 2004-12-28 devnull }
221 f1e8706d 2004-12-27 devnull
222 f1e8706d 2004-12-27 devnull static int
223 f1e8706d 2004-12-27 devnull startprocfn(void *v)
224 f1e8706d 2004-12-27 devnull {
225 f1e8706d 2004-12-27 devnull void **a;
226 f1e8706d 2004-12-27 devnull uchar *stk;
227 f1e8706d 2004-12-27 devnull void (*fn)(void*);
228 f1e8706d 2004-12-27 devnull Proc *p;
229 a620761c 2005-01-06 devnull int pid0, pid1;
230 f1e8706d 2004-12-27 devnull
231 f1e8706d 2004-12-27 devnull a = (void**)v;
232 f1e8706d 2004-12-27 devnull fn = a[0];
233 f1e8706d 2004-12-27 devnull p = a[1];
234 f1e8706d 2004-12-27 devnull stk = a[2];
235 a620761c 2005-01-06 devnull pid0 = (int)a[4];
236 a620761c 2005-01-06 devnull pid1 = getpid();
237 f1e8706d 2004-12-27 devnull free(a);
238 a620761c 2005-01-06 devnull p->osprocid = pid1;
239 f1e8706d 2004-12-27 devnull
240 f1e8706d 2004-12-27 devnull (*fn)(p);
241 f1e8706d 2004-12-27 devnull
242 a620761c 2005-01-06 devnull delayfreestack(stk, pid0, pid1);
243 f1e8706d 2004-12-27 devnull _exit(0);
244 f1e8706d 2004-12-27 devnull return 0;
245 f1e8706d 2004-12-27 devnull }
246 f1e8706d 2004-12-27 devnull
247 f1e8706d 2004-12-27 devnull /*
248 f1e8706d 2004-12-27 devnull * indirect through here so that parent need not wait for child zombie
249 f1e8706d 2004-12-27 devnull *
250 f1e8706d 2004-12-27 devnull * slight race - if child exits and then another process starts before we
251 f1e8706d 2004-12-27 devnull * manage to exit, we'll be running on a freed stack.
252 f1e8706d 2004-12-27 devnull */
253 f1e8706d 2004-12-27 devnull static int
254 f1e8706d 2004-12-27 devnull trampnowait(void *v)
255 f1e8706d 2004-12-27 devnull {
256 f1e8706d 2004-12-27 devnull void **a;
257 a620761c 2005-01-06 devnull int *kidpid;
258 f1e8706d 2004-12-27 devnull
259 f1e8706d 2004-12-27 devnull a = (void*)v;
260 a620761c 2005-01-06 devnull kidpid = a[3];
261 a620761c 2005-01-06 devnull a[4] = (void*)getpid();
262 a620761c 2005-01-06 devnull *kidpid = clone(startprocfn, a[2]+65536-512, CLONE_VM|CLONE_FILES, a);
263 f1e8706d 2004-12-27 devnull _exit(0);
264 f1e8706d 2004-12-27 devnull return 0;
265 f1e8706d 2004-12-27 devnull }
266 f1e8706d 2004-12-27 devnull
267 f1e8706d 2004-12-27 devnull void
268 f1e8706d 2004-12-27 devnull _procstart(Proc *p, void (*fn)(Proc*))
269 f1e8706d 2004-12-27 devnull {
270 f1e8706d 2004-12-27 devnull void **a;
271 f1e8706d 2004-12-27 devnull uchar *stk;
272 f1e8706d 2004-12-27 devnull int pid, kidpid, status;
273 f1e8706d 2004-12-27 devnull
274 f1e8706d 2004-12-27 devnull dofreestacks();
275 a620761c 2005-01-06 devnull a = malloc(5*sizeof a[0]);
276 f1e8706d 2004-12-27 devnull if(a == nil)
277 f1e8706d 2004-12-27 devnull sysfatal("_procstart malloc: %r");
278 f1e8706d 2004-12-27 devnull stk = malloc(65536);
279 f1e8706d 2004-12-27 devnull if(stk == nil)
280 f1e8706d 2004-12-27 devnull sysfatal("_procstart malloc stack: %r");
281 f1e8706d 2004-12-27 devnull
282 f1e8706d 2004-12-27 devnull a[0] = fn;
283 f1e8706d 2004-12-27 devnull a[1] = p;
284 f1e8706d 2004-12-27 devnull a[2] = stk;
285 f1e8706d 2004-12-27 devnull a[3] = &kidpid;
286 f1e8706d 2004-12-27 devnull kidpid = -1;
287 f1e8706d 2004-12-27 devnull
288 f1e8706d 2004-12-27 devnull pid = clone(trampnowait, stk+65536-16, CLONE_VM|CLONE_FILES, a);
289 f1e8706d 2004-12-27 devnull if(pid > 0)
290 f1e8706d 2004-12-27 devnull if(wait4(pid, &status, __WALL, 0) < 0)
291 f1e8706d 2004-12-27 devnull fprint(2, "ffork wait4: %r\n");
292 f1e8706d 2004-12-27 devnull if(pid < 0 || kidpid < 0){
293 f1e8706d 2004-12-27 devnull fprint(2, "_procstart clone: %r\n");
294 f1e8706d 2004-12-27 devnull abort();
295 f1e8706d 2004-12-27 devnull }
296 f1e8706d 2004-12-27 devnull }
297 f1e8706d 2004-12-27 devnull
298 f1e8706d 2004-12-27 devnull static char *threadexitsmsg;
299 f1e8706d 2004-12-27 devnull void
300 f1e8706d 2004-12-27 devnull sigusr2handler(int s)
301 f1e8706d 2004-12-27 devnull {
302 2c87dda8 2004-12-28 devnull /* fprint(2, "%d usr2 %d\n", time(0), getpid()); */
303 f1e8706d 2004-12-27 devnull if(threadexitsmsg)
304 f1e8706d 2004-12-27 devnull _exits(threadexitsmsg);
305 f1e8706d 2004-12-27 devnull }
306 f1e8706d 2004-12-27 devnull
307 f1e8706d 2004-12-27 devnull void
308 f1e8706d 2004-12-27 devnull threadexitsall(char *msg)
309 f1e8706d 2004-12-27 devnull {
310 f1e8706d 2004-12-27 devnull static int pid[1024];
311 f1e8706d 2004-12-27 devnull int i, npid, mypid;
312 f1e8706d 2004-12-27 devnull Proc *p;
313 9689b580 2005-07-27 devnull
314 f19d5682 2005-07-28 devnull if(msg == nil)
315 f19d5682 2005-07-28 devnull msg = "";
316 f19d5682 2005-07-28 devnull
317 9689b580 2005-07-27 devnull /*
318 9689b580 2005-07-27 devnull * Only one guy, ever, gets to run this.
319 9689b580 2005-07-27 devnull * If two guys do it, inevitably they end up
320 9689b580 2005-07-27 devnull * tripping over each other in the underlying
321 9689b580 2005-07-27 devnull * C library exit() implementation, which is
322 9689b580 2005-07-27 devnull * trying to run the atexit handlers and apparently
323 9689b580 2005-07-27 devnull * not thread safe. This has been observed on
324 9689b580 2005-07-27 devnull * both Linux and OpenBSD. Sigh.
325 9689b580 2005-07-27 devnull */
326 9689b580 2005-07-27 devnull {
327 9689b580 2005-07-27 devnull static Lock onelock;
328 f19d5682 2005-07-28 devnull if(!canlock(&onelock))
329 f19d5682 2005-07-28 devnull _exits(threadexitsmsg);
330 f19d5682 2005-07-28 devnull threadexitsmsg = msg;
331 9689b580 2005-07-27 devnull }
332 f1e8706d 2004-12-27 devnull
333 f1e8706d 2004-12-27 devnull mypid = getpid();
334 f1e8706d 2004-12-27 devnull lock(&_threadprocslock);
335 f1e8706d 2004-12-27 devnull npid = 0;
336 f1e8706d 2004-12-27 devnull for(p=_threadprocs; p; p=p->next)
337 f1e8706d 2004-12-27 devnull if(p->osprocid != mypid && p->osprocid >= 1)
338 f1e8706d 2004-12-27 devnull pid[npid++] = p->osprocid;
339 f1e8706d 2004-12-27 devnull for(i=0; i<npid; i++)
340 f1e8706d 2004-12-27 devnull kill(pid[i], SIGUSR2);
341 f1e8706d 2004-12-27 devnull unlock(&_threadprocslock);
342 f1e8706d 2004-12-27 devnull exits(msg);
343 f1e8706d 2004-12-27 devnull }
344 f1e8706d 2004-12-27 devnull
345 f1e8706d 2004-12-27 devnull /*
346 f1e8706d 2004-12-27 devnull * per-process data, indexed by pid
347 f1e8706d 2004-12-27 devnull *
348 f1e8706d 2004-12-27 devnull * could use modify_ldt and a segment register
349 f1e8706d 2004-12-27 devnull * to avoid the many calls to getpid(), but i don't
350 f1e8706d 2004-12-27 devnull * care -- this is compatibility code. linux 2.6 with
351 f1e8706d 2004-12-27 devnull * nptl is a good enough pthreads to avoid this whole file.
352 f1e8706d 2004-12-27 devnull */
353 f1e8706d 2004-12-27 devnull typedef struct Perproc Perproc;
354 f1e8706d 2004-12-27 devnull struct Perproc
355 f1e8706d 2004-12-27 devnull {
356 f1e8706d 2004-12-27 devnull int pid;
357 f1e8706d 2004-12-27 devnull Proc *proc;
358 f1e8706d 2004-12-27 devnull };
359 f1e8706d 2004-12-27 devnull
360 f1e8706d 2004-12-27 devnull static Lock perlock;
361 f1e8706d 2004-12-27 devnull static Perproc perproc[1024];
362 f1e8706d 2004-12-27 devnull #define P ((Proc*)-1)
363 f1e8706d 2004-12-27 devnull
364 f1e8706d 2004-12-27 devnull static Perproc*
365 f1e8706d 2004-12-27 devnull myperproc(void)
366 f1e8706d 2004-12-27 devnull {
367 f1e8706d 2004-12-27 devnull int i, pid, h;
368 f1e8706d 2004-12-27 devnull Perproc *p;
369 f1e8706d 2004-12-27 devnull
370 f1e8706d 2004-12-27 devnull pid = getpid();
371 f1e8706d 2004-12-27 devnull h = pid%nelem(perproc);
372 f1e8706d 2004-12-27 devnull for(i=0; i<nelem(perproc); i++){
373 f1e8706d 2004-12-27 devnull p = &perproc[(i+h)%nelem(perproc)];
374 f1e8706d 2004-12-27 devnull if(p->pid == pid)
375 f1e8706d 2004-12-27 devnull return p;
376 f1e8706d 2004-12-27 devnull if(p->pid == 0){
377 f1e8706d 2004-12-27 devnull print("found 0 at %d (h=%d)\n", (i+h)%nelem(perproc), h);
378 f1e8706d 2004-12-27 devnull break;
379 f1e8706d 2004-12-27 devnull }
380 f1e8706d 2004-12-27 devnull }
381 f1e8706d 2004-12-27 devnull fprint(2, "myperproc %d: cannot find self\n", pid);
382 f1e8706d 2004-12-27 devnull abort();
383 f1e8706d 2004-12-27 devnull return nil;
384 f1e8706d 2004-12-27 devnull }
385 f1e8706d 2004-12-27 devnull
386 f1e8706d 2004-12-27 devnull static Perproc*
387 f1e8706d 2004-12-27 devnull newperproc(void)
388 f1e8706d 2004-12-27 devnull {
389 f1e8706d 2004-12-27 devnull int i, pid, h;
390 f1e8706d 2004-12-27 devnull Perproc *p;
391 f1e8706d 2004-12-27 devnull
392 f1e8706d 2004-12-27 devnull lock(&perlock);
393 f1e8706d 2004-12-27 devnull pid = getpid();
394 f1e8706d 2004-12-27 devnull h = pid%nelem(perproc);
395 f1e8706d 2004-12-27 devnull for(i=0; i<nelem(perproc); i++){
396 f1e8706d 2004-12-27 devnull p = &perproc[(i+h)%nelem(perproc)];
397 f1e8706d 2004-12-27 devnull if(p->pid == pid || p->pid == -1 || p->pid == 0){
398 f1e8706d 2004-12-27 devnull p->pid = pid;
399 f1e8706d 2004-12-27 devnull unlock(&perlock);
400 f1e8706d 2004-12-27 devnull return p;
401 f1e8706d 2004-12-27 devnull }
402 f1e8706d 2004-12-27 devnull }
403 f1e8706d 2004-12-27 devnull fprint(2, "newperproc %d: out of procs\n", pid);
404 f1e8706d 2004-12-27 devnull abort();
405 f1e8706d 2004-12-27 devnull return nil;
406 f1e8706d 2004-12-27 devnull }
407 f1e8706d 2004-12-27 devnull
408 f1e8706d 2004-12-27 devnull Proc*
409 f1e8706d 2004-12-27 devnull _threadproc(void)
410 f1e8706d 2004-12-27 devnull {
411 f1e8706d 2004-12-27 devnull return myperproc()->proc;
412 f1e8706d 2004-12-27 devnull }
413 f1e8706d 2004-12-27 devnull
414 f1e8706d 2004-12-27 devnull void
415 f1e8706d 2004-12-27 devnull _threadsetproc(Proc *p)
416 f1e8706d 2004-12-27 devnull {
417 f1e8706d 2004-12-27 devnull Perproc *pp;
418 f1e8706d 2004-12-27 devnull
419 2c87dda8 2004-12-28 devnull if(p)
420 2c87dda8 2004-12-28 devnull p->osprocid = getpid();
421 f1e8706d 2004-12-27 devnull pp = newperproc();
422 f1e8706d 2004-12-27 devnull pp->proc = p;
423 f1e8706d 2004-12-27 devnull if(p == nil)
424 f1e8706d 2004-12-27 devnull pp->pid = -1;
425 f1e8706d 2004-12-27 devnull }
426 f1e8706d 2004-12-27 devnull
427 f1e8706d 2004-12-27 devnull void
428 f1e8706d 2004-12-27 devnull _pthreadinit(void)
429 f1e8706d 2004-12-27 devnull {
430 f1e8706d 2004-12-27 devnull signal(SIGUSR2, sigusr2handler);
431 f1e8706d 2004-12-27 devnull }
432 f1e8706d 2004-12-27 devnull
433 1d2533d0 2004-12-28 devnull void
434 1d2533d0 2004-12-28 devnull _threadpexit(void)
435 1d2533d0 2004-12-28 devnull {
436 1d2533d0 2004-12-28 devnull _exit(0);
437 f51bf048 2005-11-01 devnull }
438 f51bf048 2005-11-01 devnull
439 f51bf048 2005-11-01 devnull #ifdef __arm__
440 f51bf048 2005-11-01 devnull void
441 f51bf048 2005-11-01 devnull makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
442 f51bf048 2005-11-01 devnull {
443 f51bf048 2005-11-01 devnull int i, *sp;
444 f51bf048 2005-11-01 devnull va_list arg;
445 f51bf048 2005-11-01 devnull
446 f51bf048 2005-11-01 devnull sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
447 f51bf048 2005-11-01 devnull va_start(arg, argc);
448 f51bf048 2005-11-01 devnull for(i=0; i<4 && i<argc; i++)
449 9aa463c5 2005-11-03 devnull uc->uc_mcontext.gregs[i] = va_arg(arg, uint);
450 9aa463c5 2005-11-03 devnull va_end(arg);
451 f51bf048 2005-11-01 devnull uc->uc_mcontext.gregs[13] = (uint)sp;
452 f51bf048 2005-11-01 devnull uc->uc_mcontext.gregs[14] = (uint)fn;
453 1d2533d0 2004-12-28 devnull }
454 a620761c 2005-01-06 devnull
455 f51bf048 2005-11-01 devnull int
456 f51bf048 2005-11-01 devnull swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
457 f51bf048 2005-11-01 devnull {
458 f51bf048 2005-11-01 devnull if(getcontext(oucp) == 0)
459 f51bf048 2005-11-01 devnull setcontext(ucp);
460 f51bf048 2005-11-01 devnull return 0;
461 f51bf048 2005-11-01 devnull }
462 f51bf048 2005-11-01 devnull #endif
463 f51bf048 2005-11-01 devnull