123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- .TH LOCK 9
- .SH NAME
- lock, canlock, ilock, iunlock, unlock \- spin locks
- .SH SYNOPSIS
- .ta \w'\fLvoid 'u
- .B
- void lock(Lock *l)
- .PP
- .B
- int canlock(Lock *l)
- .PP
- .B
- void unlock(Lock *l)
- .PP
- .B
- void ilock(Lock *l)
- .PP
- .B
- void iunlock(Lock *l)
- .SH DESCRIPTION
- These primitives control access to shared
- resources using spin locks.
- They in turn are used to build higher-level synchronisation mechanisms
- such as those described in
- .IR sleep (9),
- .IR qlock (9)
- and
- .IR qio (9).
- They should be used only to protect short critical sections
- that update shared data structures.
- .PP
- .I Lock
- loops repeatedly attempting acquire the spin lock
- .I l
- until it succeeds.
- .I Lock
- should not be used to lock a structure shared with an interrupt handler
- unless interrupts are disabled by
- .IR splhi (9)
- before attempting the lock;
- it is better to use
- .IR ilock ,
- below.
- .PP
- .I Canlock
- is non-blocking.
- Only one attempt is made for the lock.
- It returns non-zero if the lock was successfully acquired; 0 otherwise.
- .PP
- .I Unlock
- releases the lock
- .IR l .
- A lock must be unlocked only by the locking process.
- .PP
- When called by a process, the functions above temporarily boost its priority
- to the highest priority,
- .BR PriLock ;
- its original priority is restored at the end of the critical section by
- .IR unlock .
- On a uniprocessor, if
- .I l
- is unavailable,
- .I lock
- can reschedule unless interrupts are disabled before entering
- .I lock
- or there is no current process (eg, when executing the scheduler).
- .PP
- .I Ilock
- disables interrupts before attempting to acquire the lock.
- It should be used to lock a resource shared between a process and an interrupt handler.
- On a uniprocessor, disabling interrupts is sufficient to exclude an interrupt handler
- from the critical section,
- and on a multiprocessor the spin lock excludes an interrupt handler running on another processor.
- .I Ilock
- never reschedules the caller, nor must a caller allow itself to be rescheduled
- (eg, by calling
- .IR sleep (9))
- before releasing the lock.
- .PP
- .I Iunlock
- releases a lock previously got by
- .IR ilock .
- .SH SOURCE
- .B /sys/src/9/port/taslock.c
- .br
- .B /sys/src/9/*/l.s
- .SH SEE ALSO
- .IR qlock (9)
- .SH DIAGNOSTICS
- The lock functions
- guard against the possibility of never acquiring the lock by capping the number of lock attempts.
- If the limit is reached, a message of
- the following form is written on the console:
- .IP
- .EX
- lock loop on \fIlock-address\fP key \fIkey-value\fP pc \fIcaller-pc\fP held by pc \fIlock-pc\fP
- .EE
- .PP
- Most lock loops represent deadlocks caused by failing to unlock a resource,
- attempting to lock (eg, by recursive call) a resource already held by the process,
- inconsistent locking and unlocking of nested resources, using a spin-lock
- to guard code that reschedules, using
- .I lock
- not
- .I ilock
- to interlock with an interrupt routine, and similar blunders.
|