Spin locks (ODDI)
spin_locks.s:.XX "spin locks>ODDI"
spin_locks.s:.XX "locks>spin, ODDI"
spin_locks.s:.XX "locks>simple (mutex), ODDI"
spin_locks.s:.XX "locks>read/write, ODDI"
ODDI provides simple (mutex) spin locks
for protecting
``Critical code section''critical code
regions in drivers.
Note that DDI provides a much richer set of
``Synchronization primitives''synchronization primitives
for drivers; when porting an ODDI driver to DDI,
the fastest approach is to convert all spin lock calls
to DDI simple spin locks,
but you may be able to improve the driver
by using other synchronization primitives in some cases.
ODDI spin locking functions
Function
|
Description
|
clockb(D3oddi),
cunlockb(D3oddi)
|
conditionally lock critical code sections
|
lockb(D3oddi),
lockb5(D3oddi),
unlockb(D3oddi)
|
general locking functions
|
ilockb(D3oddi),
iunlockb(D3oddi)
|
block interrupts for short critical code sections
|
mdi_trylock(D3mdi),
spin_locks.s:.XX "locks>trylock, ODDI"
mdi_tryunlock(D3mdi),
mdi_tryunlock_init(D3mdi)
|
MDI trylock functions
|
MPSTR_QLOCK(D3str),
MPSTR_QRELE(D3str)
|
lock STREAMS queue
|
MPSTR_STPLOCK(D3str),
MPSTR_STPRELE(D3str)
|
lock Stream head
|
tc_tlock(D3oddi),
tc_tunlock(D3oddi),
tc_ctlock(D3oddi),
tc_ctunlock(D3oddi)
|
mutual exclusion to a tty structure
|
Note the following about using the locking functions:
-
Any driver data that might be modified
by more than one CPU
must be locked for access by one processor at a time.
-
Any lock that is held when
sleep(D3oddi)
is called is released by the kernel at that time.
When a process resumes as a result of a
wakeup(D3oddi)
call, the lock is then reacquired by the kernel
in the same order as it was originally acquired.
-
A lock should be held for as short a time as possible
to avoid degrading system performance.
When a lock is acquired, all interrupts
(including clock interrupts) to that CPU are disabled,
and a process on another CPU might be blocked
waiting for that lock.
-
For simple arithmetic and bit manipulation operations
that must be executed atomically,
use the quick locks documented on the
atomic(D3oddi)
manual page.
-
No
spl(D3oddi)
calls should be issued between
a locking function and its corresponding unlock function.
-
Code that uses the locking functions
will run on a uniprocessor configuration
without modification.
-
You must use the unlocking function that corresponds to
the locking function,
and the unlocking function must not be called
before the locking function.
-
Locks must be unlocked in exactly the reverse order
of which they were locked.
This is called the ``canonical ordering of locks''.
For example,
if a lock named lock1 is acquired
and then a second lock named lock2 is acquired,
the first unlocking call must release lock2.
When using multiple locks in a driver,
you must check all pathways through your driver
to ensure that lock acquisition and lock release
happen in the correct order.
Also verify that lock1 and lock2 relate
to only one specific area of code;
no other critical code can issue an unlcoking call
to release those locks in a different order.
-
Locking calls can panic the operating system
if they make an extremely large number of attempts to acquire a lock
or if the lock stack overflows.
-
Unlocking calls can panic the operating system
if they are not releasing
the most recently acquired lock of that type
or if the process that calls the unlocking function
does not own the lock
because of a previous call to the locking function.
-
The locking functions leave all interrupts blocked
when they reeturn.
If the critical code section takes longer
than a clock tick to execute,
they system clock may lose time.
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005