Blame


1 cfa37a7b 2004-04-10 devnull .TH LOCK 3
2 cfa37a7b 2004-04-10 devnull .SH NAME
3 cfa37a7b 2004-04-10 devnull lock, canlock, unlock,
4 cfa37a7b 2004-04-10 devnull qlock, canqlock, qunlock,
5 cfa37a7b 2004-04-10 devnull rlock, canrlock, runlock,
6 cfa37a7b 2004-04-10 devnull wlock, canwlock, wunlock,
7 cfa37a7b 2004-04-10 devnull rsleep, rwakeup, rwakeupall
8 cfa37a7b 2004-04-10 devnull incref, decref
9 cfa37a7b 2004-04-10 devnull \- spin locks, queueing rendezvous locks, reader-writer locks, rendezvous points, and reference counts
10 cfa37a7b 2004-04-10 devnull .SH SYNOPSIS
11 cfa37a7b 2004-04-10 devnull .ft L
12 cfa37a7b 2004-04-10 devnull .nf
13 cfa37a7b 2004-04-10 devnull #include <u.h>
14 cfa37a7b 2004-04-10 devnull #include <libc.h>
15 cfa37a7b 2004-04-10 devnull .PP
16 cfa37a7b 2004-04-10 devnull .ft L
17 cfa37a7b 2004-04-10 devnull .nf
18 cfa37a7b 2004-04-10 devnull void lock(Lock *l)
19 cfa37a7b 2004-04-10 devnull int canlock(Lock *l)
20 cfa37a7b 2004-04-10 devnull void unlock(Lock *l)
21 cfa37a7b 2004-04-10 devnull .PP
22 cfa37a7b 2004-04-10 devnull .ft L
23 cfa37a7b 2004-04-10 devnull .nf
24 cfa37a7b 2004-04-10 devnull void qlock(QLock *l)
25 cfa37a7b 2004-04-10 devnull int canqlock(QLock *l)
26 cfa37a7b 2004-04-10 devnull void qunlock(QLock *l)
27 cfa37a7b 2004-04-10 devnull .PP
28 cfa37a7b 2004-04-10 devnull .ft L
29 cfa37a7b 2004-04-10 devnull .nf
30 cfa37a7b 2004-04-10 devnull void rlock(RWLock *l)
31 cfa37a7b 2004-04-10 devnull int canrlock(RWLock *l)
32 cfa37a7b 2004-04-10 devnull void runlock(RWLock *l)
33 cfa37a7b 2004-04-10 devnull .PP
34 cfa37a7b 2004-04-10 devnull .ft L
35 cfa37a7b 2004-04-10 devnull .nf
36 cfa37a7b 2004-04-10 devnull void wlock(RWLock *l)
37 cfa37a7b 2004-04-10 devnull int canwlock(RWLock *l)
38 cfa37a7b 2004-04-10 devnull void wunlock(RWLock *l)
39 cfa37a7b 2004-04-10 devnull .PP
40 cfa37a7b 2004-04-10 devnull .ft L
41 cfa37a7b 2004-04-10 devnull .nf
42 cfa37a7b 2004-04-10 devnull typedef struct Rendez {
43 cfa37a7b 2004-04-10 devnull QLock *l;
44 cfa37a7b 2004-04-10 devnull \fI...\fP
45 cfa37a7b 2004-04-10 devnull } Rendez;
46 cfa37a7b 2004-04-10 devnull .PP
47 cfa37a7b 2004-04-10 devnull .ft L
48 cfa37a7b 2004-04-10 devnull .nf
49 cfa37a7b 2004-04-10 devnull void rsleep(Rendez *r)
50 cfa37a7b 2004-04-10 devnull int rwakeup(Rendez *r)
51 cfa37a7b 2004-04-10 devnull int rwakeupall(Rendez *r)
52 cfa37a7b 2004-04-10 devnull .PP
53 cfa37a7b 2004-04-10 devnull .ft L
54 cfa37a7b 2004-04-10 devnull #include <thread.h>
55 cfa37a7b 2004-04-10 devnull .PP
56 cfa37a7b 2004-04-10 devnull .ft L
57 cfa37a7b 2004-04-10 devnull .nf
58 cfa37a7b 2004-04-10 devnull typedef struct Ref {
59 cfa37a7b 2004-04-10 devnull long ref;
60 cfa37a7b 2004-04-10 devnull } Ref;
61 cfa37a7b 2004-04-10 devnull .PP
62 cfa37a7b 2004-04-10 devnull .ft L
63 cfa37a7b 2004-04-10 devnull .nf
64 cfa37a7b 2004-04-10 devnull void incref(Ref*)
65 cfa37a7b 2004-04-10 devnull long decref(Ref*)
66 cfa37a7b 2004-04-10 devnull .fi
67 cfa37a7b 2004-04-10 devnull .SH DESCRIPTION
68 cfa37a7b 2004-04-10 devnull These routines are used to synchronize processes sharing memory.
69 cfa37a7b 2004-04-10 devnull .PP
70 cfa37a7b 2004-04-10 devnull .B Locks
71 cfa37a7b 2004-04-10 devnull are spin locks,
72 cfa37a7b 2004-04-10 devnull .B QLocks
73 cfa37a7b 2004-04-10 devnull and
74 cfa37a7b 2004-04-10 devnull .B RWLocks
75 cfa37a7b 2004-04-10 devnull are different types of queueing rendezvous locks,
76 cfa37a7b 2004-04-10 devnull and
77 cfa37a7b 2004-04-10 devnull .B Rendezes
78 cfa37a7b 2004-04-10 devnull are rendezvous points.
79 cfa37a7b 2004-04-10 devnull .PP
80 cfa37a7b 2004-04-10 devnull Locks and rendezvous points work in regular programs as
81 cfa37a7b 2004-04-10 devnull well as programs that use the thread library
82 cfa37a7b 2004-04-10 devnull (see
83 bf8a59fa 2004-04-11 devnull .IR thread (3)).
84 cfa37a7b 2004-04-10 devnull The thread library replaces the
85 bf8a59fa 2004-04-11 devnull .IR rendezvous (3)
86 cfa37a7b 2004-04-10 devnull system call
87 cfa37a7b 2004-04-10 devnull with its own implementation,
88 cfa37a7b 2004-04-10 devnull .IR threadrendezvous ,
89 cfa37a7b 2004-04-10 devnull so that threads as well as processes may be synchronized by locking calls
90 cfa37a7b 2004-04-10 devnull in threaded programs.
91 cfa37a7b 2004-04-10 devnull .PP
92 cfa37a7b 2004-04-10 devnull Used carelessly, spin locks can be expensive and can easily generate deadlocks.
93 cfa37a7b 2004-04-10 devnull Their use is discouraged, especially in programs that use the
94 cfa37a7b 2004-04-10 devnull thread library because they prevent context switches between threads.
95 cfa37a7b 2004-04-10 devnull .PP
96 cfa37a7b 2004-04-10 devnull .I Lock
97 cfa37a7b 2004-04-10 devnull blocks until the lock has been obtained.
98 cfa37a7b 2004-04-10 devnull .I Canlock
99 cfa37a7b 2004-04-10 devnull is non-blocking.
100 cfa37a7b 2004-04-10 devnull It tries to obtain a lock and returns a non-zero value if it
101 cfa37a7b 2004-04-10 devnull was successful, 0 otherwise.
102 cfa37a7b 2004-04-10 devnull .I Unlock
103 cfa37a7b 2004-04-10 devnull releases a lock.
104 cfa37a7b 2004-04-10 devnull .PP
105 cfa37a7b 2004-04-10 devnull .B QLocks
106 cfa37a7b 2004-04-10 devnull have the same interface but are not spin locks; instead if the lock is taken
107 cfa37a7b 2004-04-10 devnull .I qlock
108 cfa37a7b 2004-04-10 devnull will suspend execution of the calling task until it is released.
109 cfa37a7b 2004-04-10 devnull .PP
110 cfa37a7b 2004-04-10 devnull Although
111 cfa37a7b 2004-04-10 devnull .B Locks
112 cfa37a7b 2004-04-10 devnull are the more primitive lock, they have limitations; for example,
113 cfa37a7b 2004-04-10 devnull they cannot synchronize between tasks in the same
114 cfa37a7b 2004-04-10 devnull .IR proc .
115 cfa37a7b 2004-04-10 devnull Use
116 cfa37a7b 2004-04-10 devnull .B QLocks
117 cfa37a7b 2004-04-10 devnull instead.
118 cfa37a7b 2004-04-10 devnull .PP
119 cfa37a7b 2004-04-10 devnull .B RWLocks
120 cfa37a7b 2004-04-10 devnull manage access to a data structure that has distinct readers and writers.
121 cfa37a7b 2004-04-10 devnull .I Rlock
122 cfa37a7b 2004-04-10 devnull grants read access;
123 cfa37a7b 2004-04-10 devnull .I runlock
124 cfa37a7b 2004-04-10 devnull releases it.
125 cfa37a7b 2004-04-10 devnull .I Wlock
126 cfa37a7b 2004-04-10 devnull grants write access;
127 cfa37a7b 2004-04-10 devnull .I wunlock
128 cfa37a7b 2004-04-10 devnull releases it.
129 cfa37a7b 2004-04-10 devnull .I Canrlock
130 cfa37a7b 2004-04-10 devnull and
131 cfa37a7b 2004-04-10 devnull .I canwlock
132 cfa37a7b 2004-04-10 devnull are the non-blocking versions.
133 cfa37a7b 2004-04-10 devnull There may be any number of simultaneous readers,
134 cfa37a7b 2004-04-10 devnull but only one writer.
135 cfa37a7b 2004-04-10 devnull Moreover,
136 cfa37a7b 2004-04-10 devnull if write access is granted no one may have
137 cfa37a7b 2004-04-10 devnull read access until write access is released.
138 cfa37a7b 2004-04-10 devnull .PP
139 cfa37a7b 2004-04-10 devnull All types of lock should be initialized to all zeros before use; this
140 cfa37a7b 2004-04-10 devnull puts them in the unlocked state.
141 cfa37a7b 2004-04-10 devnull .PP
142 cfa37a7b 2004-04-10 devnull .B Rendezes
143 cfa37a7b 2004-04-10 devnull are rendezvous points. Each
144 cfa37a7b 2004-04-10 devnull .B Rendez
145 cfa37a7b 2004-04-10 devnull .I r
146 cfa37a7b 2004-04-10 devnull is protected by a
147 cfa37a7b 2004-04-10 devnull .B QLock
148 cfa37a7b 2004-04-10 devnull .IB r -> l \fR,
149 cfa37a7b 2004-04-10 devnull which must be held by the callers of
150 cfa37a7b 2004-04-10 devnull .IR rsleep ,
151 cfa37a7b 2004-04-10 devnull .IR rwakeup ,
152 cfa37a7b 2004-04-10 devnull and
153 cfa37a7b 2004-04-10 devnull .IR rwakeupall .
154 cfa37a7b 2004-04-10 devnull .I Rsleep
155 cfa37a7b 2004-04-10 devnull atomically releases
156 cfa37a7b 2004-04-10 devnull .IB r -> l
157 cfa37a7b 2004-04-10 devnull and suspends execution of the calling task.
158 cfa37a7b 2004-04-10 devnull After resuming execution,
159 cfa37a7b 2004-04-10 devnull .I rsleep
160 cfa37a7b 2004-04-10 devnull will reacquire
161 cfa37a7b 2004-04-10 devnull .IB r -> l
162 cfa37a7b 2004-04-10 devnull before returning.
163 cfa37a7b 2004-04-10 devnull If any processes are sleeping on
164 cfa37a7b 2004-04-10 devnull .IR r ,
165 cfa37a7b 2004-04-10 devnull .I rwakeup
166 cfa37a7b 2004-04-10 devnull wakes one of them.
167 cfa37a7b 2004-04-10 devnull it returns 1 if a process was awakened, 0 if not.
168 cfa37a7b 2004-04-10 devnull .I Rwakeupall
169 cfa37a7b 2004-04-10 devnull wakes all processes sleeping on
170 cfa37a7b 2004-04-10 devnull .IR r ,
171 cfa37a7b 2004-04-10 devnull returning the number of processes awakened.
172 cfa37a7b 2004-04-10 devnull .I Rwakeup
173 cfa37a7b 2004-04-10 devnull and
174 cfa37a7b 2004-04-10 devnull .I rwakeupall
175 cfa37a7b 2004-04-10 devnull do not release
176 cfa37a7b 2004-04-10 devnull .IB r -> l
177 cfa37a7b 2004-04-10 devnull and do not suspend execution of the current task.
178 cfa37a7b 2004-04-10 devnull .PP
179 cfa37a7b 2004-04-10 devnull Before use,
180 cfa37a7b 2004-04-10 devnull .B Rendezes
181 cfa37a7b 2004-04-10 devnull should be initialized to all zeros except for
182 cfa37a7b 2004-04-10 devnull .IB r -> l
183 cfa37a7b 2004-04-10 devnull pointer, which should point at the
184 cfa37a7b 2004-04-10 devnull .B QLock
185 cfa37a7b 2004-04-10 devnull that will guard
186 cfa37a7b 2004-04-10 devnull .IR r .
187 cfa37a7b 2004-04-10 devnull .PP
188 cfa37a7b 2004-04-10 devnull A
189 cfa37a7b 2004-04-10 devnull .B Ref
190 cfa37a7b 2004-04-10 devnull contains a
191 cfa37a7b 2004-04-10 devnull .B long
192 cfa37a7b 2004-04-10 devnull that can be incremented and decremented atomically:
193 cfa37a7b 2004-04-10 devnull .I Incref
194 cfa37a7b 2004-04-10 devnull increments the
195 cfa37a7b 2004-04-10 devnull .I Ref
196 cfa37a7b 2004-04-10 devnull in one atomic operation.
197 cfa37a7b 2004-04-10 devnull .I Decref
198 cfa37a7b 2004-04-10 devnull atomically decrements the
199 cfa37a7b 2004-04-10 devnull .B Ref
200 cfa37a7b 2004-04-10 devnull and returns zero if the resulting value is zero, non-zero otherwise.
201 cfa37a7b 2004-04-10 devnull .SH SOURCE
202 b5fdffee 2004-04-19 devnull .B /usr/local/plan9/src/libc/port/lock.c
203 cfa37a7b 2004-04-10 devnull .br
204 b5fdffee 2004-04-19 devnull .B /usr/local/plan9/src/libc/9sys/qlock.c
205 cfa37a7b 2004-04-10 devnull .br
206 b5fdffee 2004-04-19 devnull .B /usr/local/plan9/src/libthread/ref.c
207 cfa37a7b 2004-04-10 devnull .SH SEE ALSO
208 cfa37a7b 2004-04-10 devnull .I rfork
209 cfa37a7b 2004-04-10 devnull in
210 bf8a59fa 2004-04-11 devnull .IR fork (3)
211 cfa37a7b 2004-04-10 devnull .SH BUGS
212 cfa37a7b 2004-04-10 devnull .B Locks
213 cfa37a7b 2004-04-10 devnull are not strictly spin locks.
214 cfa37a7b 2004-04-10 devnull After each unsuccessful attempt,
215 cfa37a7b 2004-04-10 devnull .I lock
216 cfa37a7b 2004-04-10 devnull calls
217 cfa37a7b 2004-04-10 devnull .B sleep(0)
218 cfa37a7b 2004-04-10 devnull to yield the CPU; this handles the common case
219 cfa37a7b 2004-04-10 devnull where some other process holds the lock.
220 cfa37a7b 2004-04-10 devnull After a thousand unsuccessful attempts,
221 cfa37a7b 2004-04-10 devnull .I lock
222 cfa37a7b 2004-04-10 devnull sleeps for 100ms between attempts.
223 cfa37a7b 2004-04-10 devnull Another another thousand unsuccessful attempts,
224 cfa37a7b 2004-04-10 devnull .I lock
225 cfa37a7b 2004-04-10 devnull sleeps for a full second between attempts.
226 cfa37a7b 2004-04-10 devnull .B Locks
227 cfa37a7b 2004-04-10 devnull are not intended to be held for long periods of time.
228 cfa37a7b 2004-04-10 devnull The 100ms and full second sleeps are only heuristics to
229 cfa37a7b 2004-04-10 devnull avoid tying up the CPU when a process deadlocks.
230 cfa37a7b 2004-04-10 devnull As discussed above,
231 cfa37a7b 2004-04-10 devnull if a lock is to be held for much more than a few instructions,
232 cfa37a7b 2004-04-10 devnull the queueing lock types should be almost always be used.