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)