lock(9)
- NetBSD Manual Pages
LOCK(9) NetBSD Kernel Developer's Manual LOCK(9)
NAME
lock, simple_lock_init, simple_lock, simple_lock_try, simple_unlock,
simple_lock_freecheck, simple_lock_dump, lockinit, lockmgr, lockstatus,
lockmgr_printinfo, transferlockers, spinlockinit, spinlockmgr -- kernel
lock functions
SYNOPSIS
#include <sys/lock.h>
void
simple_lock_init(struct simplelock *slock);
void
simple_lock(struct simplelock *slock);
int
simple_lock_try(struct simplelock *slock);
void
simple_unlock(struct simplelock *slock);
void
simple_lock_freecheck(void *start, void *end);
void
simple_lock_dump(void);
void
lockinit(struct lock *lock, int prio, const char *wmesg, int timo,
int flags);
int
lockmgr(struct lock *lock, u_int flags, struct simplelock *slock);
int
lockstatus(struct lock *lock);
void
lockmgr_printinfo(struct lock *lock);
void
transferlockers(struct lock *from, struct lock *to);
void
spinlockinit(struct lock *lock, const char *wmesg, int flags);
int
spinlockmgr(struct lock *lock, u_int flags, struct simplelock *slock);
DESCRIPTION
The lock functions provide synchronisation in the kernel by preventing
multiple threads from simultaneously executing critical sections of code
accessing shared data. A number of different locks are available:
struct simplelock
Provides a simple spinning mutex. A processor will busy-wait
while trying to acquire a simplelock. The simplelock operations
are implemented with machine-dependent locking primitives.
Simplelocks are usually used only by the high-level lock manager
and to protect short, critical sections of code. Simplelocks
are the only locks that can be used inside an interrupt handler.
For a simplelock to be used in an interrupt handler, care must
be taken to disable the interrupt, acquire the lock, do any pro-
cessing, release the simplelock and re-enable the interrupt.
This procedure is necessary to avoid deadlock between the inter-
rupt handler and other threads executing on the same processor.
struct lock
Provides a high-level lock supporting sleeping/spinning until
the lock can be acquired. The lock manager supplies both exclu-
sive-access and shared-access locks, with recursive exclusive-
access locks within a single thread. It also allows upgrading a
shared-access lock to an exclusive-access lock, as well as down-
grading an exclusive-access lock to a shared-access lock.
If the kernel option LOCKDEBUG is enabled, additional facilities are pro-
vided to record additional lock information. These facilities are pro-
vided to assist in determining deadlock occurrences.
FUNCTIONS
The functions which operate on simplelocks are:
simple_lock_init(slock)
The simplelock slock 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 exam-
ple,
struct simplelock slock = SIMPLELOCK_INITIALIZER;
simple_lock(slock)
The simplelock slock is locked. If the simplelock is held then
execution will spin until the simplelock is acquired. Care must
be taken to ensure 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.
simple_lock_try(slock)
Try to acquire the simplelock slock without spinning. If the
simplelock is held by another thread then the return value is 0.
If the simplelock was acquired successfully then the return
value is 1.
simple_unlock(slock)
The simplelock slock 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.
simple_lock_freecheck(start, end)
Check that all simplelocks in the address range start to end are
not held. If a simplelock within the range is found, the kernel
enters the debugger. This function is available only with ker-
nel option LOCKDEBUG. It provides a mechanism for basic simple-
lock consistency checks.
simple_lock_dump(void)
Dump the state of all simplelocks in the kernel. This function
is available only with kernel option LOCKDEBUG.
The functions which operate on locks are:
lockinit(lock, prio, wmesg, timo, flags)
The lock lock is initialised according to the parameters pro-
vided. Arguments are as follows:
lock The lock.
prio The thread priority when it is woken up after sleeping
on the lock.
wmesg A sleep message used when a thread goes to sleep wait-
ing for the lock, so that the exact reason it is sleep-
ing can easily be identified.
timo The maximum sleep time. Used by tsleep(9).
flags Flags to specify the lock behaviour permanently over
the lifetime of the lock. Valid lock flags are:
LK_NOWAIT
Threads should not sleep when attempting to
acquire the lock.
LK_SLEEPFAIL
Threads should sleep, then return failure when
acquiring the lock.
LK_CANRECURSE
Threads can acquire the lock recursively.
lockmgr(lock, flags, slock)
Set, change or release a lock according to the parameters pro-
vided. Arguments are as follows:
lock The lock.
slock Simplelock interlock. If the flag LK_INTERLOCK is set
in flags, slock is a simplelock held by the caller.
When the lock lock is acquired, the simplelock is
released. If the flag LK_INTERLOCK is not set, slock
is ignored.
flags Flags to specify the lock request type. In addition to
the flags specified above, the following flags are
valid:
LK_SHARED
Get one of many possible shared-access locks.
If a thread holding an exclusive-access lock
requests a shared-access lock, the exclusive-
access lock is downgraded to a shared-access
lock.
LK_EXCLUSIVE
Stop further shared-access locks, when they
are cleared, grant a pending upgrade if it
exists, then grant an exclusive-access lock.
Only one exclusive-access lock may exist at a
time, except that a thread holding an exclu-
sive-access lock may get additional exclusive-
access locks if it explicitly sets the
LK_CANRECURSE flag in the lock request, or if
the LK_CANRECURSE flag was set when the lock
was initialised.
LK_UPGRADE
The thread must hold a shared-access lock that
it wants to have upgraded to an exclusive-
access lock. Other threads may get exclusive
access to the protected resource between the
time that the upgrade is requested and the
time that it is granted.
LK_EXCLUPGRADE
The thread must hold a shared-access lock that
it wants to have upgraded to an exclusive-
access lock. If the request succeeds, no
other threads will have acquired exclusive
access to the protected 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.
LK_DOWNGRADE
The thread must hold an exclusive-access lock
that it wants to have downgraded to a shared-
access lock. If the thread holds multiple
(recursive) exclusive-access locks, they will
all be downgraded to shared-access locks.
LK_RELEASE
Release one instance of a lock.
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.
LK_REENABLE
Lock is to be re-enabled after drain. The
LK_REENABLE flag may be set only at the
release of a lock obtained by a drain.
LK_SETRECURSE
Other locks while we have it OK.
LK_RECURSEFAIL
Attempt at recursive lock fails.
LK_SPIN Lock spins instead of sleeping.
LK_INTERLOCK
Unlock the simplelock slock when the lock is
acquired.
lockstatus(lock)
Determine the status of lock lock. Returns one of the follow-
ing:
LK_EXCLUSIVE
The current lwp or CPU holds an exclusive-access lock.
LK_EXCLOTHER
The other lwp or CPU holds an exclusive-access lock.
LK_SHARED
Someone holds shared-access lock.
0 Not locked.
lockmgr_printinfo(lock)
Print out information about state of lock lock.
transferlockers(from, to)
Transfer any waiting processes from lock from to lock to.
spinlockinit(lock, wmesg, flags)
The lock lock is initialised as a spinlock according to the
parameters provided. Arguments are as follows:
lock The lock.
wmesg This is a simple name for lock.
flags Flags to specify the lock behaviour. Valid lock flags
are the same as outlined above.
spinlockmgr(lock, flags, slock)
Set, change or release a lock according to the parameters pro-
vided. Arguments are as follows:
lock The spin lock.
flags Flags to specify the lock request type. Valid lock
flags are the same as outlined above.
slock Simplelock interlock. The simplelock slock is set by
the caller. When the lock lock is acquired, the sim-
plelock is released.
RETURN VALUES
Successfully acquired locks return 0. 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). Locks will always succeed unless one of the
following is true:
[EBUSY] LK_FORCEUPGRADE is requested and some other thread has
already requested a lock upgrade or LK_NOWAIT is set
and a sleep would be required.
[ENOLCK] LK_SLEEPFAIL is set and a sleep was done.
[EINTR] PCATCH is set in lock priority and a signal arrives to
interrupt a system call.
[ERESTART] PCATCH is set in lock priority and a signal arrives so
that the system call is restarted.
[EWOULDBLOCK] Non-null lock timeout and timeout expires.
CODE REFERENCES
This section describes places within the NetBSD source tree where actual
code implementing or using the locking framework can be found. All path-
names are relative to /usr/src.
The locking framework itself is implemented within the file
sys/kern/kern_lock.c. Data structures and function prototypes for the
framework are located in sys/sys/lock.h. Machine-dependent simplelock
primitives are implemented within the file
sys/arch/<arch>/include/lock.h.
SEE ALSO
pmap(9), spl(9), tsleep(9), uvm(9)
HISTORY
The kernel locking API first appeared in 4.4BSD-lite2.
NetBSD 4.0 May 25, 2004 NetBSD 4.0
Powered by man-cgi (2024-03-20).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.