summaryrefslogtreecommitdiffstats
path: root/share/man/man9/rmlock.9
diff options
context:
space:
mode:
Diffstat (limited to 'share/man/man9/rmlock.9')
-rw-r--r--share/man/man9/rmlock.9314
1 files changed, 314 insertions, 0 deletions
diff --git a/share/man/man9/rmlock.9 b/share/man/man9/rmlock.9
new file mode 100644
index 0000000..aeb3b45
--- /dev/null
+++ b/share/man/man9/rmlock.9
@@ -0,0 +1,314 @@
+.\" Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org>
+.\" Copyright (c) 2006 Gleb Smirnoff <glebius@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.\" Based on rwlock.9 man page
+.Dd June 25, 2013
+.Dt RMLOCK 9
+.Os
+.Sh NAME
+.Nm rmlock ,
+.Nm rm_init ,
+.Nm rm_init_flags ,
+.Nm rm_destroy ,
+.Nm rm_rlock ,
+.Nm rm_try_rlock ,
+.Nm rm_wlock ,
+.Nm rm_runlock ,
+.Nm rm_wunlock ,
+.Nm rm_wowned ,
+.Nm rm_sleep ,
+.Nm rm_assert ,
+.Nm RM_SYSINIT
+.Nd kernel reader/writer lock optimized for read-mostly access patterns
+.Sh SYNOPSIS
+.In sys/param.h
+.In sys/lock.h
+.In sys/rmlock.h
+.Ft void
+.Fn rm_init "struct rmlock *rm" "const char *name"
+.Ft void
+.Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
+.Ft void
+.Fn rm_destroy "struct rmlock *rm"
+.Ft void
+.Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+.Ft int
+.Fn rm_try_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+.Ft void
+.Fn rm_wlock "struct rmlock *rm"
+.Ft void
+.Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+.Ft void
+.Fn rm_wunlock "struct rmlock *rm"
+.Ft int
+.Fn rm_wowned "const struct rmlock *rm"
+.Ft int
+.Fn rm_sleep "void *wchan" "struct rmlock *rm" "int priority" "const char *wmesg" "int timo"
+.Pp
+.Cd "options INVARIANTS"
+.Cd "options INVARIANT_SUPPORT"
+.Ft void
+.Fn rm_assert "struct rmlock *rm" "int what"
+.In sys/kernel.h
+.Fn RM_SYSINIT "name" "struct rmlock *rm" "const char *desc" "int opts"
+.Sh DESCRIPTION
+Read-mostly 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
+.Em readers
+since they only read the protected data.
+A thread with exclusive access is known as a
+.Em writer
+since it can modify protected data.
+.Pp
+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 has been locked for shared access
+is an expensive operation.
+.Pp
+Normal read-mostly locks are similar to
+.Xr rwlock 9
+locks and follow the same lock ordering rules as
+.Xr rwlock 9
+locks.
+Read-mostly locks have full priority propagation like mutexes.
+Unlike
+.Xr rwlock 9 ,
+read-mostly locks propagate priority to both readers and writers.
+This is implemented via the
+.Va rm_priotracker
+structure argument supplied to
+.Fn rm_rlock
+and
+.Fn rm_runlock .
+Readers can recurse if the lock is initialized with the
+.Dv RM_RECURSE
+option;
+however, writers are never allowed to recurse.
+.Pp
+Sleepable read-mostly locks are created by passing
+.Dv RM_SLEEPABLE
+to
+.Fn rm_init_flags .
+Unlike normal read-mostly locks,
+sleepable read-mostly locks follow the same lock ordering rules as
+.Xr sx 9
+locks.
+Sleepable read-mostly locks do not propagate priority to writers,
+but they do propagate priority to readers.
+Writers are permitted to sleep while holding a read-mostly lock,
+but readers are not.
+Unlike other sleepable locks such as
+.Xr sx 9
+locks,
+readers must use try operations on other sleepable locks to avoid sleeping.
+.Ss Macros and Functions
+.Bl -tag -width indent
+.It Fn rm_init "struct rmlock *rm" "const char *name"
+Initialize the read-mostly lock
+.Fa rm .
+The
+.Fa name
+description is used solely for debugging purposes.
+This function must be called before any other operations
+on the lock.
+.It Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
+Similar to
+.Fn rm_init ,
+initialize the read-mostly lock
+.Fa rm
+with a set of optional flags.
+The
+.Fa opts
+arguments contains one or more of the following flags:
+.Bl -tag -width ".Dv RM_NOWITNESS"
+.It Dv RM_NOWITNESS
+Instruct
+.Xr witness 4
+to ignore this lock.
+.It Dv RM_RECURSE
+Allow threads to recursively acquire shared locks for
+.Fa rm .
+.It Dv RM_SLEEPABLE
+Create a sleepable read-mostly lock.
+.El
+.It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+Lock
+.Fa rm
+as a reader using
+.Fa tracker
+to track read owners of a lock for priority propagation.
+This data structure is only used internally by
+.Nm
+and must persist until
+.Fn rm_runlock
+has been called.
+This data structure can be allocated on the stack since
+readers cannot sleep.
+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
+.Dv RM_RECURSE
+option the
+.Fn rm_rlock
+function can be called when the current thread has already acquired reader
+access on
+.Fa rm .
+.It Fn rm_try_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+Try to lock
+.Fa rm
+as a reader.
+.Fn 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
+.Fn rm_try_rlock
+may fail even while the lock is not currently held by a writer.
+If the lock was initialized with the
+.Dv RM_RECURSE
+option,
+.Fn rm_try_rlock
+will succeed if the current thread has already acquired reader access.
+.It Fn rm_wlock "struct rmlock *rm"
+Lock
+.Fa rm
+as a writer.
+If there are any shared owners of the lock, the current thread blocks.
+The
+.Fn rm_wlock
+function cannot be called recursively.
+.It Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
+This function releases a shared lock previously acquired by
+.Fn rm_rlock .
+The
+.Fa tracker
+argument must match the
+.Fa tracker
+argument used for acquiring the shared lock
+.It Fn rm_wunlock "struct rmlock *rm"
+This function releases an exclusive lock previously acquired by
+.Fn rm_wlock .
+.It Fn rm_destroy "struct rmlock *rm"
+This functions destroys a lock previously initialized with
+.Fn rm_init .
+The
+.Fa rm
+lock must be unlocked.
+.It Fn rm_wowned "const struct rmlock *rm"
+This function returns a non-zero value if the current thread owns an
+exclusive lock on
+.Fa rm .
+.It Fn rm_sleep "void *wchan" "struct rmlock *rm" "int priority" "const char *wmesg" "int timo"
+This function atomically releases
+.Fa rm
+while waiting for an event.
+The
+.Fa rm
+lock must be exclusively locked.
+For more details on the parameters to this function,
+see
+.Xr sleep 9 .
+.It Fn rm_assert "struct rmlock *rm" "int what"
+This function asserts that the
+.Fa rm
+lock is in the state specified by
+.Fa what .
+If the assertions are not true and the kernel is compiled with
+.Cd "options INVARIANTS"
+and
+.Cd "options INVARIANT_SUPPORT" ,
+the kernel will panic.
+Currently the following base assertions are supported:
+.Bl -tag -width ".Dv RA_UNLOCKED"
+.It Dv RA_LOCKED
+Assert that current thread holds either a shared or exclusive lock
+of
+.Fa rm .
+.It Dv RA_RLOCKED
+Assert that current thread holds a shared lock of
+.Fa rm .
+.It Dv RA_WLOCKED
+Assert that current thread holds an exclusive lock of
+.Fa rm .
+.It Dv RA_UNLOCKED
+Assert that current thread holds neither a shared nor exclusive lock of
+.Fa rm .
+.El
+.Pp
+In addition, one of the following optional flags may be specified with
+.Dv RA_LOCKED ,
+.Dv RA_RLOCKED ,
+or
+.Dv RA_WLOCKED :
+.Bl -tag -width ".Dv RA_NOTRECURSED"
+.It Dv RA_RECURSED
+Assert that the current thread holds a recursive lock of
+.Fa rm .
+.It Dv RA_NOTRECURSED
+Assert that the current thread does not hold a recursive lock of
+.Fa rm .
+.El
+.El
+.Sh SEE ALSO
+.Xr locking 9 ,
+.Xr mutex 9 ,
+.Xr panic 9 ,
+.Xr rwlock 9 ,
+.Xr sleep 9 ,
+.Xr sema 9 ,
+.Xr sx 9
+.Sh HISTORY
+These
+functions appeared in
+.Fx 7.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+facility was written by
+.An "Stephan Uphoff" .
+This manual page was written by
+.An "Gleb Smirnoff"
+for rwlock and modified to reflect rmlock by
+.An "Stephan Uphoff" .
+.Sh BUGS
+The
+.Nm
+implementation is currently not optimized for single processor systems.
+.Pp
+.Fn rm_try_rlock
+can fail transiently even when there is no writer, while another reader
+updates the state on the local CPU.
+.Pp
+The
+.Nm
+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.
OpenPOWER on IntegriCloud