LOCK(2) LOCK(2) NAME lock, canlock, unlock, qlock, canqlock, qunlock, rlock, runlock, wlock, wunlock, incref, decref - shared memory spin locks, rendez-vous locks, reader-writer locks, and atomic increment and decrement SYNOPSIS #include <u.h> #include <libc.h> void lock(Lock*) int canlock(Lock*) void unlock(Lock*) void qlock(QLock*) void qunlock(QLock*) int canqlock(QLock*) void rlock(RWLock*) void runlock(RWLock*) void wlock(RWLock*) void wunlock(RWLock*) #include <thread.h> typedef struct Ref { long ref; } Ref; void incref(Ref*) long decref(Ref*) DESCRIPTION These routines are used to synchronize processes sharing memory. The first group (lock, canlock, unlock) uses spin locks in shared memory. The second group (qlock, canqlock, qunlock), uses rendezvous locks in shared memory. The third group (rlock, runlock, wlock, wunlock), also uses rendezvous locks but has slightly different semantics. Page 1 Plan 9 (printed 12/25/24) LOCK(2) LOCK(2) Locks work in regular programs as well as programs that use the thread library (see thread(2)). The thread library replaces the rendezvous system call (see rendezvous(2)) with its own implementation, threadrendezvous, so that threads as well as processes may be synchronized by locking calls in threaded programs. 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. Lock blocks until the lock has been obtained. Canlock is non-blocking. It tries to obtain a lock and returns a non- zero value if it was successful, 0 otherwise. Unlock releases a lock. QLocks have the same interface but are not spin locks; instead if the lock is taken qlock will suspend execution of the calling task until it is released. Although Locks are the more primitive lock, they have limi- tations; for example, they cannot synchronize between tasks in the same proc. Use QLocks instead. RWLocks manage access to a data structure that has distinct readers and writers. Rlock grants read access; runlock releases it. Wlock grants write access; wunlock releases it. 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. All types of lock should be initialized to all zeros before use; this puts them in the unlocked state. A Ref contains a long that can be incremented and decre- mented atomically: Incref increments the Ref in one atomic operation. Decref atomically decrements the Ref and returns zero if the resulting value is zero, non-zero otherwise. SOURCE /sys/src/libc/port/lock.c /sys/src/libc/9sys/qlock.c /sys/src/libthread/ref.c SEE ALSO rfork in fork(2) Page 2 Plan 9 (printed 12/25/24)