xref: /plan9/sys/src/cmd/unix/drawterm/kern/rendez.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1 #include	"u.h"
2 #include	"lib.h"
3 #include	"dat.h"
4 #include	"fns.h"
5 #include	"error.h"
6 
7 void
sleep(Rendez * r,int (* f)(void *),void * arg)8 sleep(Rendez *r, int (*f)(void*), void *arg)
9 {
10 	int s;
11 
12 	s = splhi();
13 
14 	lock(&r->lk);
15 	lock(&up->rlock);
16 	if(r->p){
17 		print("double sleep %lud %lud\n", r->p->pid, up->pid);
18 		dumpstack();
19 	}
20 
21 	/*
22 	 *  Wakeup only knows there may be something to do by testing
23 	 *  r->p in order to get something to lock on.
24 	 *  Flush that information out to memory in case the sleep is
25 	 *  committed.
26 	 */
27 	r->p = up;
28 
29 	if((*f)(arg) || up->notepending){
30 		/*
31 		 *  if condition happened or a note is pending
32 		 *  never mind
33 		 */
34 		r->p = nil;
35 		unlock(&up->rlock);
36 		unlock(&r->lk);
37 	} else {
38 		/*
39 		 *  now we are committed to
40 		 *  change state and call scheduler
41 		 */
42 		up->state = Wakeme;
43 		up->r = r;
44 
45 		/* statistics */
46 		/* m->cs++; */
47 
48 		unlock(&up->rlock);
49 		unlock(&r->lk);
50 
51 		procsleep();
52 	}
53 
54 	if(up->notepending) {
55 		up->notepending = 0;
56 		splx(s);
57 		error(Eintr);
58 	}
59 
60 	splx(s);
61 }
62 
63 Proc*
wakeup(Rendez * r)64 wakeup(Rendez *r)
65 {
66 	Proc *p;
67 	int s;
68 
69 	s = splhi();
70 
71 	lock(&r->lk);
72 	p = r->p;
73 
74 	if(p != nil){
75 		lock(&p->rlock);
76 		if(p->state != Wakeme || p->r != r)
77 			panic("wakeup: state");
78 		r->p = nil;
79 		p->r = nil;
80 		p->state = Running;
81 		procwakeup(p);
82 		unlock(&p->rlock);
83 	}
84 	unlock(&r->lk);
85 
86 	splx(s);
87 
88 	return p;
89 }
90 
91