NAME
lock
,
simple_lock_init
,
simple_lock
,
simple_lock_try
,
simple_unlock
, lockinit
,
lockmgr
, lockstatus
,
lockmgr_printinfo
, —
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
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);
DESCRIPTION
The lock
functions provide synchronisation
in the kernel by preventing multiple processes 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 processing, release the simplelock and re-enable the interrupt. This procedure is necessary to avoid deadlock between the interrupt handler and other processes 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 exclusive-access and shared-access locks, with recursive exclusive-access locks within a single process. It also allows upgrading a shared-access lock to an exclusive-access lock, as well as downgrading an exclusive-access lock to a shared-access lock.
If the kernel option LOCKDEBUG is enabled, additional facilities are provided to record additional lock information. These facilities are provided 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.
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 that the calling process 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 process 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 process must be the one that last acquired the simplelock. If the calling process does not hold the simplelock, the simplelock will be released but the kernel behaviour is undefined.
The functions which operate on locks are:
lockinit
(lock, prio, wmesg, timo, flags)- The lock lock is initialised according to the
parameters provided. Arguments are as follows:
- lock
- The lock.
- prio
- The process priority when it is woken up after sleeping on the lock.
- wmesg
- A sleep message used when a process goes to sleep waiting for the lock, so that the exact reason it is sleeping 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
- Processes should not sleep when attempting to acquire the lock.
- LK_CANRECURSE
- Processes can acquire the lock recursively.
lockmgr
(lock, flags, slock)- Set, change or release a lock according to the parameters provided.
Arguments are as follows:
- lock
- The lock.
- 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 process 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 process holding an exclusive-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_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_RECURSEFAIL
- Attempt at recursive lock fails.
- slock
- This argument exists for legacy reasons, it is now ignored.
lockstatus
(lock)- Determine the status of lock lock. Returns LK_EXCLUSIVE or LK_SHARED for exclusive-access and shared-access locks respectively.
lockmgr_printinfo
(lock)- Print out information about state of lock lock.
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. Locks will always succeed unless one of the following is true:
- [
EBUSY
] - LK_NOWAIT is set and a sleep would be required.
- [
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 OpenBSD source tree where actual code implementing or utilising the locking framework can be found. All pathnames 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.
SEE ALSO
HISTORY
The kernel locking API first appeared in 4.4BSD--lite2. It was progressively deprecated in favor of rwlock(9).