aboutsummaryrefslogtreecommitdiff
path: root/man/man3/lock.html
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-01-14 03:45:44 +0000
committerrsc <devnull@localhost>2005-01-14 03:45:44 +0000
commit78e51a8c6678b6e3dff3d619aa786669f531f4bc (patch)
tree015e00fde4fc837fd31b705e18d17dc913829388 /man/man3/lock.html
parent2634795b5f0053bc0ff08e5d7bbc0eda8efea061 (diff)
downloadplan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.tar.gz
plan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.tar.bz2
plan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.zip
checkpoint
Diffstat (limited to 'man/man3/lock.html')
-rw-r--r--man/man3/lock.html222
1 files changed, 222 insertions, 0 deletions
diff --git a/man/man3/lock.html b/man/man3/lock.html
new file mode 100644
index 00000000..72d66e12
--- /dev/null
+++ b/man/man3/lock.html
@@ -0,0 +1,222 @@
+<head>
+<title>lock(3) - Plan 9 from User Space</title>
+<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
+</head>
+<body bgcolor=#ffffff>
+<table border=0 cellpadding=0 cellspacing=0 width=100%>
+<tr height=10><td>
+<tr><td width=20><td>
+<tr><td width=20><td><b>LOCK(3)</b><td align=right><b>LOCK(3)</b>
+<tr><td width=20><td colspan=2>
+ <br>
+<p><font size=+1><b>NAME </b></font><br>
+
+<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ lock, canlock, unlock, qlock, canqlock, qunlock, rlock, canrlock,
+ runlock, wlock, canwlock, wunlock, rsleep, rwakeup, rwakeupall
+ incref, decref &ndash; spin locks, queueing rendezvous locks, reader-writer
+ locks, rendezvous points, and reference counts<br>
+
+</table>
+<p><font size=+1><b>SYNOPSIS </b></font><br>
+
+<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ <tt><font size=+1>#include &lt;u.h&gt;<br>
+ #include &lt;libc.h&gt;<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void lock(Lock *l)<br>
+ int &nbsp;&nbsp;&nbsp;canlock(Lock *l)<br>
+ void unlock(Lock *l)<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void qlock(QLock *l)<br>
+ int &nbsp;&nbsp;&nbsp;canqlock(QLock *l)<br>
+ void qunlock(QLock *l)<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void rlock(RWLock *l)<br>
+ int &nbsp;&nbsp;&nbsp;canrlock(RWLock *l)<br>
+ void runlock(RWLock *l)<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void wlock(RWLock *l)<br>
+ int &nbsp;&nbsp;&nbsp;canwlock(RWLock *l)<br>
+ void wunlock(RWLock *l)<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ typedef struct Rendez {<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ QLock *l;<br>
+
+ </table>
+ </font></tt>
+ <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ <i>...<br>
+ </i>
+ </table>
+ <tt><font size=+1>} Rendez;<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void rsleep(Rendez *r)<br>
+ int &nbsp;&nbsp;&nbsp;rwakeup(Rendez *r)<br>
+ int &nbsp;&nbsp;&nbsp;rwakeupall(Rendez *r)<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ #include &lt;thread.h&gt;<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ typedef struct Ref {<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ long ref;<br>
+
+ </table>
+ } Ref;<br>
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ void incref(Ref*)<br>
+ long decref(Ref*)<br>
+ </font></tt>
+</table>
+<p><font size=+1><b>DESCRIPTION </b></font><br>
+
+<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ These routines are used to synchronize processes sharing memory.
+
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ <tt><font size=+1>Locks</font></tt> are spin locks, <tt><font size=+1>QLocks</font></tt> and <tt><font size=+1>RWLocks</font></tt> are different types of
+ queueing locks, and <tt><font size=+1>Rendezes</font></tt> are rendezvous points.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ Locks and rendezvous points have trivial implementations in programs
+ not using the thread library (see <a href="../man3/thread.html"><i>thread</i>(3)</a>), since such programs
+ have no concurrency.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ 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.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ <i>Lock</i> blocks until the lock has been obtained. <i>Canlock</i> is non-blocking.
+ It tries to obtain a lock and returns a non-zero value if it was
+ successful, 0 otherwise. <i>Unlock</i> releases a lock.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ <tt><font size=+1>QLocks</font></tt> have the same interface but are not spin locks; instead
+ if the lock is taken <i>qlock</i> will suspend execution of the calling
+ thread until it is released.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ Although <tt><font size=+1>Locks</font></tt> are the more primitive lock, they have limitations;
+ for example, they cannot synchronize between tasks in the same
+ <i>proc</i>. Use <tt><font size=+1>QLocks</font></tt> instead.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ <tt><font size=+1>RWLocks</font></tt> manage access to a data structure that has distinct readers
+ and writers. <i>Rlock</i> grants read access; <i>runlock</i> releases it. <i>Wlock</i>
+ grants write access; <i>wunlock</i> releases it. <i>Canrlock</i> and <i>canwlock</i>
+ 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.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ All types of lock should be initialized to all zeros before use;
+ this puts them in the unlocked state.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ <tt><font size=+1>Rendezes</font></tt> are rendezvous points. Each <tt><font size=+1>Rendez</font></tt> <i>r</i> is protected by
+ a <tt><font size=+1>QLock</font></tt> <i>r</i><tt><font size=+1>&#8722;&gt;</font></tt><i>l</i>, which must be held by the callers of <i>rsleep</i>, <i>rwakeup</i>,
+ and <i>rwakeupall</i>. <i>Rsleep</i> atomically releases <i>r</i><tt><font size=+1>&#8722;&gt;</font></tt><i>l</i> and suspends execution
+ of the calling task. After resuming execution, <i>rsleep</i> will reacquire
+ <i>r</i><tt><font size=+1>&#8722;&gt;</font></tt><i>l</i> before returning. If any processes
+ are sleeping on <i>r</i>, <i>rwakeup</i> wakes one of them. it returns 1 if
+ a process was awakened, 0 if not. <i>Rwakeupall</i> wakes all processes
+ sleeping on <i>r</i>, returning the number of processes awakened. <i>Rwakeup</i>
+ and <i>rwakeupall</i> do not release <i>r</i><tt><font size=+1>&#8722;&gt;</font></tt><i>l</i> and do not suspend execution
+ of the current task.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ Before use, <tt><font size=+1>Rendezes</font></tt> should be initialized to all zeros except
+ for <i>r</i><tt><font size=+1>&#8722;&gt;</font></tt><i>l</i> pointer, which should point at the <tt><font size=+1>QLock</font></tt> that will guard
+ <i>r</i>.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ A <tt><font size=+1>Ref</font></tt> contains a <tt><font size=+1>long</font></tt> that can be incremented and decremented
+ atomically: <i>Incref</i> increments the <i>Ref</i> in one atomic operation.
+ <i>Decref</i> atomically decrements the <tt><font size=+1>Ref</font></tt> and returns zero if the resulting
+ value is zero, non-zero otherwise.<br>
+
+</table>
+<p><font size=+1><b>SOURCE </b></font><br>
+
+<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ <tt><font size=+1>/usr/local/plan9/src/lib9/qlock.c<br>
+ /usr/local/plan9/src/libthread<br>
+ </font></tt>
+</table>
+<p><font size=+1><b>BUGS </b></font><br>
+
+<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
+
+ <tt><font size=+1>Locks</font></tt> are not always spin locks. Instead they are usually implemented
+ using the <i>pthreads</i> library&#8217;s <tt><font size=+1>pthread_mutex_t</font></tt>, whose implementation
+ method is not defined.
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ On <i>pthreads</i>-based systems, the implementation of <tt><font size=+1>Lock</font></tt> never calls
+ <i>pthread_mutex_destroy</i> to free the <tt><font size=+1>pthread_mutex_t</font></tt>&#8217;s. This leads
+ to resource leaks on FreeBSD 5 (though not on Linux 2.6, where
+ <i>pthread_mutex_destroy</i> is a no-op).
+ <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
+
+ On systems that do not have a usable <i>pthreads</i> implementation,
+ the <tt><font size=+1>Lock</font></tt> implementation provided by <i>libthread</i> is still not exactly
+ a spin lock. After each unsuccessful attempt, <i>lock</i> calls <tt><font size=+1>sleep(0)</font></tt>
+ to yield the CPU; this handles the common case where some other
+ process holds the lock. After a thousand
+ unsuccessful attempts, <i>lock</i> sleeps for 100ms between attempts.
+ Another another thousand unsuccessful attempts, <i>lock</i> sleeps for
+ a full second between attempts. <tt><font size=+1>Locks</font></tt> are not intended to be held
+ for long periods of time. The 100ms and full second sleeps are
+ only heuristics to avoid tying up the CPU when a
+ process deadlocks. As discussed above, if a lock is to be held
+ for much more than a few instructions, the queueing lock types
+ should be almost always be used.<br>
+
+</table>
+
+<td width=20>
+<tr height=20><td>
+</table>
+<!-- TRAILER -->
+<table border=0 cellpadding=0 cellspacing=0 width=100%>
+<tr height=15><td width=10><td><td width=10>
+<tr><td><td>
+<center>
+<a href="../../"><img src="../../dist/spaceglenda100.png" alt="Space Glenda" border=1></a>
+</center>
+</table>
+<!-- TRAILER -->
+</body></html>