Provided by: freebsd-manpages_9.2+1-1_all bug

NAME

       rmlock,  rm_init,  rm_init_flags,  rm_destroy,  rm_rlock, rm_try_rlock, rm_wlock, rm_runlock, rm_wunlock,
       rm_wowned, RM_SYSINIT — kernel reader/writer lock optimized for mostly read access patterns

SYNOPSIS

       #include <sys/param.h>
       #include <sys/lock.h>
       #include <sys/rmlock.h>

       void
       rm_init(struct rmlock *rm, const char *name);

       void
       rm_init_flags(struct rmlock *rm, const char *name, int opts);

       void
       rm_destroy(struct rmlock *rm);

       void
       rm_rlock(struct rmlock *rm, struct rm_priotracker* tracker);

       int
       rm_try_rlock(struct rmlock *rm, struct rm_priotracker* tracker);

       void
       rm_wlock(struct rmlock *rm);

       void
       rm_runlock(struct rmlock *rm, struct rm_priotracker* tracker);

       void
       rm_wunlock(struct rmlock *rm);

       int
       rm_wowned(struct rmlock *rm);

       #include <sys/kernel.h>

       RM_SYSINIT(name, struct rmlock *rm, const char *desc, int opts);

DESCRIPTION

       Mostly reader locks allow shared access to protected data by multiple threads, or exclusive access  by  a
       single  thread.   The  threads with shared access are known as readers since they only read the protected
       data.  A thread with exclusive access is known as a writer since it can modify protected data.

       Read mostly locks are designed to be efficient for locks almost exclusively used as reader locks  and  as
       such  should be used for protecting data that rarely changes.  Acquiring an exclusive lock after the lock
       had been locked for shared access is an expensive operation.

       Although reader/writer locks look very  similar  to  sx(9)  locks,  their  usage  pattern  is  different.
       Reader/writer  locks  can  be  treated  as  mutexes (see mutex(9)) with shared/exclusive semantics unless
       initialized with RM_SLEEPABLE.  Unlike sx(9), an rmlock can be locked while holding a non-spin mutex, and
       an rmlock cannot be held while sleeping, again unless initialized with RM_SLEEPABLE.   The  rmlock  locks
       have  full  priority  propagation  like  mutexes.   The  rm_priotracker  structure  argument  supplied in
       rm_rlock() and rm_runlock() is used to keep track of the read owner(s).  Another  important  property  is
       that shared holders of rmlock can recurse if the lock has been initialized with the LO_RECURSABLE option,
       however exclusive locks are not allowed to recurse.

   Macros and Functions
       rm_init(struct rmlock *rm, const char *name)
               Initialize  structure  located  at  rm  as  mostly  reader  lock,  described  by  name.  The name
               description is used solely for debugging purposes.  This function must be called before any other
               operations on the lock.

       rm_init_flags(struct rmlock *rm, const char *name, int opts)
               Initialize the rm lock just like the rm_init() function, but specifying a set of  optional  flags
               to  alter  the  behaviour  of  rm,  through  the  opts  argument.  It contains one or more of the
               following flags:

               RM_NOWITNESS  Instruct witness(4) to ignore this lock.

               RM_RECURSE    Allow threads to recursively acquire exclusive locks for rm.

               RM_SLEEPABLE  Allow writers to sleep while holding  the  lock.   Readers  must  not  sleep  while
                             holding  the lock and can avoid to sleep on taking the lock by using rm_try_rlock()
                             instead of rm_rlock().

       rm_rlock(struct rmlock *rm, struct rm_priotracker* tracker)
               Lock rm as a reader.  Using tracker to track read owners of  a  lock  for  priority  propagation.
               This  data  structure  is  only used internally by rmlock and must persist until rm_runlock() has
               been called.  This data structure can be allocated on the stack  since  rmlocks  cannot  be  held
               while  sleeping.   If  any thread holds this lock exclusively, the current thread blocks, and its
               priority is  propagated  to  the  exclusive  holder.   If  the  lock  was  initialized  with  the
               LO_RECURSABLE  option  the rm_rlock() function can be called when the thread has already acquired
               reader access on rm.  This is called “recursing on a lock”.

       rm_try_rlock(struct rmlock *rm, struct rm_priotracker* tracker)
               Try to lock rm as a reader.  rm_try_rlock()  will  return  0  if  the  lock  cannot  be  acquired
               immediately;  otherwise  the  lock  will be acquired and a non-zero value will be returned.  Note
               that rm_try_rlock() may fail even while the lock is not currently held by a writer.

       rm_wlock(struct rmlock *rm)
               Lock rm as a writer.  If there are any shared owners of the lock, the current thread blocks.  The
               rm_wlock() function cannot be called recursively.

       rm_runlock(struct rmlock *rm, struct rm_priotracker* tracker)
               This function releases a shared lock previously acquired by  rm_rlock().   The  tracker  argument
               must match the tracker argument used for acquiring the shared lock

       rm_wunlock(struct rmlock *rm)
               This function releases an exclusive lock previously acquired by rm_wlock().

       rm_destroy(struct rmlock *rm)
               This  functions  destroys  a  lock  previously  initialized  with rm_init().  The rm lock must be
               unlocked.

       rm_wowned(struct rmlock *rm)
               This function returns a non-zero value if the current thread owns an exclusive lock on rm.

SEE ALSO

       locking(9), mutex(9), panic(9), rwlock(9), sema(9), sx(9)

HISTORY

       These functions appeared in FreeBSD 7.0.

AUTHORS

       The rmlock facility was written by Stephan Uphoff.  This manual page was written  by  Gleb  Smirnoff  for
       rwlock and modified to reflect rmlock by Stephan Uphoff.

BUGS

       The rmlock implementation is currently not optimized for single processor systems.

       rm_try_rlock()  can fail transiently even when there is no writer, while another reader updates the state
       on the local CPU.

       The rmlock implementation uses a single per CPU list shared by all rmlocks in  the  system.   If  rmlocks
       become popular, hashing to multiple per CPU queues may be needed to speed up the writer lock process.

       The rmlock can currently not be used as a lock argument for condition variable wait functions.

Debian                                          November 10, 2007                                      RMLOCK(9)