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