|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6:
7:
8: void
9: qlock(QLock *q)
10: {
11: Proc *p, *mp;
12:
13: if(u)
14: u->p->qlockpc = getcallerpc(((uchar*)&q) - sizeof(q));
15:
16: lock(&q->use);
17: if(!q->locked) {
18: q->locked = 1;
19: unlock(&q->use);
20: return;
21: }
22: p = q->tail;
23: mp = u->p;
24: if(p == 0)
25: q->head = mp;
26: else
27: p->qnext = mp;
28: q->tail = mp;
29: mp->qnext = 0;
30: mp->state = Queueing;
31: unlock(&q->use);
32: sched();
33: }
34:
35: int
36: canqlock(QLock *q)
37: {
38: if(!canlock(&q->use))
39: return 0;
40:
41: if(q->locked){
42: unlock(&q->use);
43: return 0;
44: }
45: if(u)
46: u->p->qlockpc = getcallerpc(((uchar*)&q) - sizeof(q));
47: q->locked = 1;
48: unlock(&q->use);
49: return 1;
50: }
51:
52: void
53: qunlock(QLock *q)
54: {
55: Proc *p;
56:
57: if(u)
58: u->p->qlockpc = 0;
59: lock(&q->use);
60: p = q->head;
61: if(p) {
62: q->head = p->qnext;
63: if(q->head == 0)
64: q->tail = 0;
65: unlock(&q->use);
66: ready(p);
67: return;
68: }
69: q->locked = 0;
70: unlock(&q->use);
71: }
72:
73: void
74: rlock(RWlock *l)
75: {
76: qlock(&l->x); /* wait here for writers and exclusion */
77: lock(l);
78: l->readers++;
79: canqlock(&l->k); /* block writers if we are the first reader */
80: unlock(l);
81: qunlock(&l->x);
82: }
83:
84: void
85: runlock(RWlock *l)
86: {
87: lock(l);
88: if(--l->readers == 0) /* last reader out allows writers */
89: qunlock(&l->k);
90: unlock(l);
91: }
92:
93: void
94: wlock(RWlock *l)
95: {
96: qlock(&l->x); /* wait here for writers and exclusion */
97: qlock(&l->k); /* wait here for last reader */
98: }
99:
100: void
101: wunlock(RWlock *l)
102: {
103: qunlock(&l->x);
104: qunlock(&l->k);
105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.