2000-08-14 06:37:37 +04:00
|
|
|
.\" $NetBSD: lock.9,v 1.3 2000/08/14 02:37:37 deberg Exp $
|
2000-06-26 03:45:22 +04:00
|
|
|
.\"
|
|
|
|
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
|
|
|
|
.\" 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.
|
|
|
|
.\" 3. All advertising materials mentioning features or use of this software
|
|
|
|
.\" must display the following acknowledgement:
|
|
|
|
.\" This product includes software developed by the NetBSD
|
|
|
|
.\" Foundation, Inc. and its contributors.
|
|
|
|
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
|
|
|
.\" contributors may be used to endorse or promote products derived
|
|
|
|
.\" from this software without specific prior written permission.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
|
|
|
.\"
|
|
|
|
.Dd June 23, 2000
|
|
|
|
.Dt LOCK 9
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
|
|
|
.Nm lock ,
|
|
|
|
.Nm simple_lock_init ,
|
|
|
|
.Nm simple_lock ,
|
|
|
|
.Nm simple_lock_try ,
|
|
|
|
.Nm simple_unlock ,
|
|
|
|
.Nm simple_lock_freecheck ,
|
|
|
|
.Nm simple_lock_dump ,
|
|
|
|
.Nm lockinit ,
|
|
|
|
.Nm lockmgr ,
|
|
|
|
.Nm lockstatus ,
|
|
|
|
.Nm lockmgr_printinfo ,
|
|
|
|
.Nm spinlockinit ,
|
|
|
|
.Nm spinlockmgr
|
|
|
|
.Nd kernel lock functions
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.Fd #include <sys/lock.h>
|
|
|
|
.Ft void
|
|
|
|
.Fn simple_lock_init "struct simplelock *slock"
|
|
|
|
.Ft void
|
|
|
|
.Fn simple_lock "struct simplelock *slock"
|
|
|
|
.Ft int
|
|
|
|
.Fn simple_lock_try "struct simplelock *slock"
|
|
|
|
.Ft void
|
|
|
|
.Fn simple_lock_unlock "struct simplelock *slock"
|
|
|
|
.Ft void
|
|
|
|
.Fn simple_lock_freecheck "void *start" "void *end"
|
|
|
|
.Ft void
|
|
|
|
.Fn simple_lock_dump "void"
|
|
|
|
.Ft void
|
|
|
|
.Fn lockinit "struct lock *lock" "int prio" "const char *wmesg" \
|
|
|
|
"int timo" "int flags"
|
|
|
|
.Ft int
|
|
|
|
.Fn lockmgr "struct lock *lock" "u_int flags" "struct simplelock *slock"
|
|
|
|
.Ft int
|
|
|
|
.Fn lockstatus "struct lock *lock"
|
|
|
|
.Ft void
|
|
|
|
.Fn lockmgr_printinfo "struct lock *lock"
|
|
|
|
.Ft void
|
|
|
|
.Fn spinlockinit "struct lock *lock" "const char *wmesg" "int flags"
|
|
|
|
.Ft int
|
|
|
|
.Fn spinlockmgr "struct lock *lock" "u_int flags" "struct simplelock *slock"
|
|
|
|
.Sh DESCRIPTION
|
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Nm
|
2000-07-07 05:26:13 +04:00
|
|
|
functions provide synchronisation capabilities in the kernel by preventing
|
|
|
|
multiple threads from simultaneously executing critical section of code which
|
|
|
|
access shared data. A number of different locks are available:
|
2000-06-26 03:45:22 +04:00
|
|
|
.Pp
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It struct simplelock
|
|
|
|
Provides a simple spinning mutex. The simplelock operations are implemented
|
|
|
|
with machine-dependent locking primitives.
|
|
|
|
.It struct lock
|
|
|
|
A general lock structure for multiple shared locks, upgrading from
|
|
|
|
shared to exclusive, and sleeping/spinning until the lock can be
|
|
|
|
gained.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
If the kernel option LOCKDEBUG is enabled, additional facilities
|
2000-07-07 05:26:13 +04:00
|
|
|
are provided to record additional lock information. These facilities are
|
2000-06-26 03:45:22 +04:00
|
|
|
provided to assist in determining deadlock occurrences.
|
|
|
|
.Sh FUNCTIONS
|
|
|
|
The functions which operate on simplelocks are:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fn simple_lock_init "slock"
|
|
|
|
The simplelock
|
|
|
|
.Fa slock
|
2000-07-07 05:26:13 +04:00
|
|
|
is initialised to the unlocked state. A statically allocated simplelock
|
|
|
|
also can be initialised with the macro SIMPLELOCK_INITIALIZER. The
|
|
|
|
effect is the same as the dynamic initialisation by a call to
|
|
|
|
simple_lock_init. For example,
|
|
|
|
.Pp
|
2000-06-26 03:45:22 +04:00
|
|
|
struct simplelock slock = SIMPLELOCK_INITIALIZER;
|
|
|
|
.It Fn simple_lock "slock"
|
|
|
|
The simplelock
|
|
|
|
.Fa slock
|
|
|
|
is locked. If the simplelock is held then execution will
|
2000-07-07 05:26:13 +04:00
|
|
|
spin until the simplelock is acquired. Care must be taken that the
|
|
|
|
calling thread does not already hold the simplelock. In this case, the
|
|
|
|
simplelock can never be acquired. If kernel option LOCKDEBUG is enabled,
|
|
|
|
a "locking against myself" panic will occur.
|
2000-06-26 03:45:22 +04:00
|
|
|
.It Fn simple_lock_try "slock"
|
|
|
|
Try to acquire the simplelock
|
|
|
|
.Fa slock
|
2000-07-07 05:26:13 +04:00
|
|
|
without spinning. If the simplelock is held by another thread
|
2000-06-26 03:45:22 +04:00
|
|
|
then the return value is 0. If the simplelock was acquired
|
|
|
|
successfully then the return value is 1.
|
|
|
|
.It Fn simple_lock_unlock "slock"
|
|
|
|
The simplelock
|
|
|
|
.Fa slock
|
2000-07-07 05:26:13 +04:00
|
|
|
is unlocked. The simplelock must be locked and the calling thread must
|
|
|
|
be the one that last acquired the simplelock. If the calling
|
|
|
|
thread does not hold the simplelock, the simplelock will be released
|
|
|
|
but the kernel behaviour is undefined.
|
2000-06-26 03:45:22 +04:00
|
|
|
.It Fn simple_lock_freecheck "start" "end"
|
2000-07-07 05:26:13 +04:00
|
|
|
Check that all simplelocks in the address range
|
2000-06-26 03:45:22 +04:00
|
|
|
.Fa start
|
|
|
|
to
|
|
|
|
.Fa end
|
2000-07-07 05:26:13 +04:00
|
|
|
are not held. If a simplelock within the range is found, the kernel
|
|
|
|
enters the debugger. This function is available only with kernel
|
|
|
|
option LOCKDEBUG. It provides a mechanism for basic simplelock
|
|
|
|
consistency checks.
|
2000-06-26 03:45:22 +04:00
|
|
|
.It Fn simple_lock_dump "void"
|
|
|
|
Dump the state of all simplelocks in the kernel. This function is
|
|
|
|
available only with kernel option LOCKDEBUG.
|
|
|
|
.El
|
|
|
|
.Pp
|
2000-08-14 06:37:37 +04:00
|
|
|
The functions which operate on locks are:
|
2000-06-26 03:45:22 +04:00
|
|
|
.Pp
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fn lockinit "lock" "prio" "wmesg" "timo" "flags"
|
|
|
|
The lock
|
|
|
|
.Fa lock
|
|
|
|
is initialised according to the parameters provided. Arguments are as
|
|
|
|
follows:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fa lock
|
|
|
|
The lock.
|
|
|
|
.It Fa prio
|
|
|
|
The priority at which to sleep.
|
|
|
|
.It Fa wmesg
|
|
|
|
This is the sleep message for sleep locks or a simple name for spin locks.
|
|
|
|
.It Fa timo
|
|
|
|
The maximum sleep time. Used by tsleep(9).
|
|
|
|
.It Fa flags
|
|
|
|
Flags to specify the lock type. Valid lock request types are:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It LK_SHARED
|
|
|
|
Get one of many possible shared locks. If a thread holding an
|
|
|
|
exclusive lock requests a shared lock, the exclusive lock(s) will be
|
|
|
|
downgraded to shared locks.
|
|
|
|
.It LK_EXCLUSIVE
|
|
|
|
Stop further shared locks, when they are cleared, grant a pending
|
|
|
|
upgrade if it exists, then grant an exclusive lock. Only one exclusive
|
|
|
|
lock may exist at a time, except that a thread holding an exclusive
|
|
|
|
lock may get additional exclusive locks if it explicitly sets the
|
|
|
|
LK_CANRECURSE flag in the lock request, or if the LK_CANRECUSE flag
|
|
|
|
was set when the lock was initialized.
|
|
|
|
.It LK_UPGRADE
|
|
|
|
The thread must hold a shared lock that it wants to have upgraded to
|
|
|
|
an exclusive lock. Other threads may get exclusive access to the
|
|
|
|
resource between the time that the upgrade is requested and the time
|
|
|
|
that it is granted.
|
|
|
|
.It LK_EXCLUPGRADE
|
|
|
|
The thread must hold a shared lock that it wants to have upgraded to
|
|
|
|
an exclusive lock. If the request succeeds, no other threads will
|
|
|
|
have gotten exclusive access to the resource between the time that the
|
|
|
|
upgrade is requested and the time that it is granted. However, if
|
|
|
|
another thread has already requested an upgrade, the request will
|
|
|
|
fail (see error returns below).
|
|
|
|
.It LK_DOWNGRADE
|
|
|
|
The thread must hold an exclusive lock that it wants to have
|
|
|
|
downgraded to a shared lock. If the thread holds multiple (recursive)
|
|
|
|
exclusive locks, they will all be downgraded to shared locks.
|
|
|
|
.It LK_RELEASE
|
|
|
|
Release one instance of a lock.
|
|
|
|
.It LK_DRAIN
|
|
|
|
Wait for all activity on the lock to end, then mark it
|
|
|
|
decommissioned. This feature is used before freeing a lock that is
|
|
|
|
part of a piece of memory that is about to be freed.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
Additional flags which may be used:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It LK_NOWAIT
|
|
|
|
Do not sleep to await lock.
|
|
|
|
.It LK_SLEEPFAIL
|
|
|
|
Sleep, then return failure.
|
|
|
|
.It LK_CANRECURSE
|
|
|
|
This may be recursive lock attempt.
|
|
|
|
.It LK_REENABLE
|
|
|
|
Lock is to be reenabled after drain. The LK_REENABLE flag may be set
|
|
|
|
only at the release of a lock obtained by drain.
|
|
|
|
.It LK_SETRECURSE
|
|
|
|
Other locks while we have it OK.
|
|
|
|
.It LK_RECURSEFAIL
|
|
|
|
Attempt at recursive lock fails.
|
|
|
|
.El
|
|
|
|
.El
|
|
|
|
.It Fn lockmgr "lock" "flags" "slock"
|
|
|
|
Set, change or release a lock according to the parameters provided.
|
|
|
|
Arguments are as follows:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fa lock
|
|
|
|
The lock.
|
|
|
|
.It Fa flags
|
|
|
|
Flags to specify the lock type. Lock request types are the same as outlined
|
|
|
|
above.
|
|
|
|
.It Fa slock
|
|
|
|
Simplelock interlock. The simplelock
|
|
|
|
.Fa slock
|
|
|
|
is set by the caller. When the lock
|
|
|
|
.Fa lock
|
2000-07-07 05:26:13 +04:00
|
|
|
is acquired, the simplelock is released.
|
2000-06-26 03:45:22 +04:00
|
|
|
.El
|
|
|
|
.It Fn lockstatus "lock"
|
|
|
|
Determine the status of lock
|
|
|
|
.Fa lock .
|
|
|
|
Returns LK_EXCLUSIVE or LK_SHARED for exclusive and shared locks
|
|
|
|
respectively.
|
|
|
|
.It Fn lockmgr_printinfo "lock"
|
|
|
|
Print out information about state of lock
|
|
|
|
.Fa lock .
|
|
|
|
.It Fn spinlockinit "lock" "wmesg" "flags"
|
|
|
|
The lock
|
|
|
|
.Fa lock
|
|
|
|
is initialised as a spinlock according to the parameters provided.
|
|
|
|
Arguments are as follows:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fa lock
|
|
|
|
The lock.
|
|
|
|
.It Fa wmesg
|
|
|
|
This is a simple name for lock.
|
|
|
|
.It Fa flags
|
|
|
|
Flags to specify the lock type. Lock request types are the same as outlined
|
|
|
|
above.
|
|
|
|
.El
|
|
|
|
.It Fn spinlockmgr "lock" "flags" "slock"
|
|
|
|
Set, change or release a lock according to the parameters provided.
|
|
|
|
Arguments are as follows:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It Fa lock
|
|
|
|
The spin lock.
|
|
|
|
.It Fa flags
|
|
|
|
Flags to specify the lock type. Lock request types are the same as outlined
|
|
|
|
above.
|
|
|
|
.It Fa slock
|
|
|
|
Simplelock interlock. The simplelock
|
|
|
|
.Fa slock
|
|
|
|
is set by the caller. When the lock
|
|
|
|
.Fa lock
|
2000-07-07 05:26:13 +04:00
|
|
|
is acquired, the simplelock is released.
|
2000-06-26 03:45:22 +04:00
|
|
|
.El
|
|
|
|
.El
|
|
|
|
.Sh RETURN VALUES
|
|
|
|
Successfully obtained locks return 0. Locks will always succeed
|
|
|
|
unless one of the following is true:
|
|
|
|
.Bl -tag -width compact
|
|
|
|
.It
|
|
|
|
LK_FORCEUPGRADE is requested and some other process has already
|
|
|
|
requested a lock upgrade (returns EBUSY).
|
|
|
|
.It
|
2000-07-07 05:26:13 +04:00
|
|
|
LK_WAIT is set and a sleep would be required (returns EBUSY).
|
2000-06-26 03:45:22 +04:00
|
|
|
.It
|
2000-07-07 05:26:13 +04:00
|
|
|
LK_SLEEPFAIL is set and a sleep was done (returns ENOLCK).
|
2000-06-26 03:45:22 +04:00
|
|
|
.It
|
|
|
|
PCATCH is set in lock priority and a signal arrives (returns
|
2000-07-07 05:26:13 +04:00
|
|
|
either EINTR or ERESTART if system calls is to be restarted).
|
2000-06-26 03:45:22 +04:00
|
|
|
.It
|
|
|
|
Non-null lock timeout and timeout expires (returns EWOULDBLOCK).
|
|
|
|
.It
|
|
|
|
A failed lock attempt always returns a non-zero error value. No lock
|
|
|
|
is held after an error return (in particular, a failed LK_UPGRADE
|
|
|
|
or LK_FORCEUPGRADE will have released its shared access lock).
|
|
|
|
.El
|