/src/plan9port/src/lib9/qlock.c
Line | Count | Source |
1 | | #include <u.h> |
2 | | #include <libc.h> |
3 | | |
4 | | /* |
5 | | * The function pointers are supplied by the thread |
6 | | * library during its initialization. If there is no thread |
7 | | * library, there is no multithreading. |
8 | | */ |
9 | | |
10 | | int (*_lock)(Lock*, int, ulong); |
11 | | void (*_unlock)(Lock*, ulong); |
12 | | int (*_qlock)(QLock*, int, ulong); /* do not use */ |
13 | | void (*_qunlock)(QLock*, ulong); |
14 | | void (*_rsleep)(Rendez*, ulong); /* do not use */ |
15 | | int (*_rwakeup)(Rendez*, int, ulong); |
16 | | int (*_rlock)(RWLock*, int, ulong); /* do not use */ |
17 | | int (*_wlock)(RWLock*, int, ulong); |
18 | | void (*_runlock)(RWLock*, ulong); |
19 | | void (*_wunlock)(RWLock*, ulong); |
20 | | |
21 | | void |
22 | | lock(Lock *l) |
23 | 0 | { |
24 | 0 | if(_lock) |
25 | 0 | (*_lock)(l, 1, getcallerpc(&l)); |
26 | 0 | else |
27 | 0 | l->held = 1; |
28 | 0 | } |
29 | | |
30 | | int |
31 | | canlock(Lock *l) |
32 | 0 | { |
33 | 0 | if(_lock) |
34 | 0 | return (*_lock)(l, 0, getcallerpc(&l)); |
35 | 0 | else{ |
36 | 0 | if(l->held) |
37 | 0 | return 0; |
38 | 0 | l->held = 1; |
39 | 0 | return 1; |
40 | 0 | } |
41 | 0 | } |
42 | | |
43 | | void |
44 | | unlock(Lock *l) |
45 | 0 | { |
46 | 0 | if(_unlock) |
47 | 0 | (*_unlock)(l, getcallerpc(&l)); |
48 | 0 | else |
49 | 0 | l->held = 0; |
50 | 0 | } |
51 | | |
52 | | void |
53 | | qlock(QLock *l) |
54 | 0 | { |
55 | 0 | if(_qlock) |
56 | 0 | (*_qlock)(l, 1, getcallerpc(&l)); |
57 | 0 | else |
58 | 0 | l->l.held = 1; |
59 | 0 | } |
60 | | |
61 | | int |
62 | | canqlock(QLock *l) |
63 | 0 | { |
64 | 0 | if(_qlock) |
65 | 0 | return (*_qlock)(l, 0, getcallerpc(&l)); |
66 | 0 | else{ |
67 | 0 | if(l->l.held) |
68 | 0 | return 0; |
69 | 0 | l->l.held = 1; |
70 | 0 | return 1; |
71 | 0 | } |
72 | 0 | } |
73 | | |
74 | | void |
75 | | qunlock(QLock *l) |
76 | 0 | { |
77 | 0 | if(_qunlock) |
78 | 0 | (*_qunlock)(l, getcallerpc(&l)); |
79 | 0 | else |
80 | 0 | l->l.held = 0; |
81 | 0 | } |
82 | | |
83 | | void |
84 | | rlock(RWLock *l) |
85 | 0 | { |
86 | 0 | if(_rlock) |
87 | 0 | (*_rlock)(l, 1, getcallerpc(&l)); |
88 | 0 | else |
89 | 0 | l->readers++; |
90 | 0 | } |
91 | | |
92 | | int |
93 | | canrlock(RWLock *l) |
94 | 0 | { |
95 | 0 | if(_rlock) |
96 | 0 | return (*_rlock)(l, 0, getcallerpc(&l)); |
97 | 0 | else{ |
98 | 0 | if(l->writer) |
99 | 0 | return 0; |
100 | 0 | l->readers++; |
101 | 0 | return 1; |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | void |
106 | | runlock(RWLock *l) |
107 | 0 | { |
108 | 0 | if(_runlock) |
109 | 0 | (*_runlock)(l, getcallerpc(&l)); |
110 | 0 | else |
111 | 0 | l->readers--; |
112 | 0 | } |
113 | | |
114 | | void |
115 | | wlock(RWLock *l) |
116 | 0 | { |
117 | 0 | if(_wlock) |
118 | 0 | (*_wlock)(l, 1, getcallerpc(&l)); |
119 | 0 | else |
120 | 0 | l->writer = (void*)1; |
121 | 0 | } |
122 | | |
123 | | int |
124 | | canwlock(RWLock *l) |
125 | 0 | { |
126 | 0 | if(_wlock) |
127 | 0 | return (*_wlock)(l, 0, getcallerpc(&l)); |
128 | 0 | else{ |
129 | 0 | if(l->writer || l->readers) |
130 | 0 | return 0; |
131 | 0 | l->writer = (void*)1; |
132 | 0 | return 1; |
133 | 0 | } |
134 | 0 | } |
135 | | |
136 | | void |
137 | | wunlock(RWLock *l) |
138 | 0 | { |
139 | 0 | if(_wunlock) |
140 | 0 | (*_wunlock)(l, getcallerpc(&l)); |
141 | 0 | else |
142 | 0 | l->writer = nil; |
143 | 0 | } |
144 | | |
145 | | void |
146 | | rsleep(Rendez *r) |
147 | 0 | { |
148 | 0 | if(_rsleep) |
149 | 0 | (*_rsleep)(r, getcallerpc(&r)); |
150 | 0 | } |
151 | | |
152 | | int |
153 | | rwakeup(Rendez *r) |
154 | 0 | { |
155 | 0 | if(_rwakeup) |
156 | 0 | return (*_rwakeup)(r, 0, getcallerpc(&r)); |
157 | 0 | return 0; |
158 | 0 | } |
159 | | |
160 | | int |
161 | | rwakeupall(Rendez *r) |
162 | 0 | { |
163 | 0 | if(_rwakeup) |
164 | 0 | return (*_rwakeup)(r, 1, getcallerpc(&r)); |
165 | 0 | return 0; |
166 | 0 | } |