lock 4.6 KB

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