summaryrefslogtreecommitdiff
path: root/static/plan9-4e/man2/lock.2
blob: ef36d37a32c029f5837d0bbb03eaea52f39e7c59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
.TH LOCK 2
.SH NAME
lock, canlock, unlock,
qlock, canqlock, qunlock,
rlock, runlock, canrlock,
wlock, wunlock, canwlock,
incref, decref
\- shared memory spin locks, rendez-vous locks, reader-writer locks, and
atomic increment and decrement
.SH SYNOPSIS
.B
#include <u.h>
.br
.B
#include <libc.h>
.PP
.B
void	lock(Lock *l)
.PP
.B
int	canlock(Lock *l)
.PP
.B
void	unlock(Lock *l)
.PP
.B
void	qlock(QLock *l)
.PP
.B
void	qunlock(QLock *l)
.PP
.B
int	canqlock(QLock *l)
.PP
.B
void	rlock(RWLock *l)
.PP
.B
void	runlock(RWLock *l)
.PP
.B
int	canrlock(RWLock *l)
.PP
.B
void	wlock(RWLock *l)
.PP
.B
void	wunlock(RWLock *l)
.PP
.B
int	canwlock(RWLock *l)
.PP
.PP
.B
#include <thread.h>
.PP
.B
typedef struct Ref {
.br
.B
	long ref;
.br
.B
} Ref;
.PP
.B
void incref(Ref*)
.PP
.B
long decref(Ref*)
.SH DESCRIPTION
These routines are used  to synchronize processes sharing memory.
.PP
The first group
.RI ( lock ,
.IR canlock , 
.IR unlock )
uses spin locks in shared memory.
The second group
.RI ( qlock ,
.IR canqlock ,
.IR qunlock ),
uses rendezvous locks in shared
memory.
The third group
.RI ( rlock ,
.IR runlock ,
.IR canrlock ,
.IR wlock ,
.IR wunlock ,
.IR canwlock ),
also uses rendezvous locks but has slightly different
semantics.
.PP
Locks work in regular programs as well as programs that use the thread library
(see
.IR thread (2)).
The thread library replaces the
.B rendezvous
system call
(see
.IR rendezvous (2))
with its own implementation,
.BR threadrendezvous ,
so that threads as well as processes may be synchronized by locking calls
in threaded programs.
.PP
Used carelessly, spin locks can be expensive and can easily generate deadlocks.
Their use is discouraged, especially in programs that use the
thread library because they prevent context switches between threads.
.PP
.I Lock
blocks until the lock has been obtained.
.I Canlock
is non-blocking.
It tries to obtain a lock and returns a non-zero value if it
was successful, 0 otherwise.
.I Unlock
releases a lock.
.PP
.B QLocks
have the same interface but are not spin locks; instead if the lock is taken
.I qlock
will suspend execution of the calling task until it is released.
.PP
Although
.B Locks
are the more primitive lock, they have limitations; for example,
they cannot synchronize between tasks in the same
.IR proc .
Use
.B QLocks
instead.
.PP
.B RWLocks
manage access to a data structure that has distinct readers and writers.
.I Rlock
grants read access;
.I runlock
releases it.
.I Wlock
grants write access;
.I wunlock
releases it.
.I Canrlock
and
.I canwlock
are the non-blocking versions.
There may be any number of simultaneous readers,
but only one writer.
Moreover,
if write access is granted no one may have
read access until write access is released.
.PP
All types of lock should be initialized to all zeros before use; this
puts them in the unlocked state.
.PP
A
.B Ref
contains a
.B long
that can be incremented and decremented atomically:
.I Incref
increments the
.I Ref
in one atomic operation.
.I Decref
atomically decrements the
.B Ref
and returns zero if the resulting value is zero, non-zero otherwise.
.SH SOURCE
.B /sys/src/libc/port/lock.c
.br
.B /sys/src/libc/9sys/qlock.c
.br
.B /sys/src/libthread/ref.c
.SH SEE ALSO
.I rfork
in
.IR fork (2)