diff options
author | rsc <devnull@localhost> | 2005-01-14 03:45:44 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-01-14 03:45:44 +0000 |
commit | 78e51a8c6678b6e3dff3d619aa786669f531f4bc (patch) | |
tree | 015e00fde4fc837fd31b705e18d17dc913829388 /man/man3/lock.html | |
parent | 2634795b5f0053bc0ff08e5d7bbc0eda8efea061 (diff) | |
download | plan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.tar.gz plan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.tar.bz2 plan9port-78e51a8c6678b6e3dff3d619aa786669f531f4bc.zip |
checkpoint
Diffstat (limited to 'man/man3/lock.html')
-rw-r--r-- | man/man3/lock.html | 222 |
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 – 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 <u.h><br> + #include <libc.h><br> + + <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> + + void lock(Lock *l)<br> + int 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 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 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 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 rwakeup(Rendez *r)<br> + int rwakeupall(Rendez *r)<br> + + <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> + + #include <thread.h><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>−></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>−></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>−></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>−></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>−></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’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>’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> |