spin_trylock(2) CX/UX spin_trylock(2)
NAME
spininit, spintrylock, spinislock, spinunlock - busy-
wait mutual exclusion
SYNOPSIS
#include <sys/types.h>
#include <sys/threadsynch.h>
void spininit (m)
struct spinmutex *m;
int spintrylock (m)
struct spinmutex *m;
int spinislock (m)
struct spinmutex *m;
void spinunlock (m)
struct spinmutex *m;
DESCRIPTION
Access to a shared resource must often be serialized. Seri-
alization is frequently achieved by associating a "synchron-
izing variable" with the shared resource, "locking" the syn-
chronizing variable before accessing the shared resource,
and "unlocking" the variable when the accesses are complete.
The lock and unlock operations guarantee that at most one
cooperating thread of execution has access to the shared
resource at a time. If a thread finds that a synchronizing
variable is already locked, it must delay until the variable
is unlocked. If the expected delay is small, less than
approximately two context switches, it is more efficient to
poll the synchronizing variable than it is to block the
thread. This form of synchronization is called busy-wait
mutual exclusion. It requires that the synchronizing vari-
able be accessible directly from user mode, and that the
lock and unlock operations have very low overhead (on the
order of a few microseconds).
Busy-wait mutual exclusion synchronizing variables are com-
monly called "spinlocks". CX/UX uses the structure name
spinmutex
struct spinmutex {};
defined in <sys/threadsynch.h>. Spinlocks are allocated by
the application and reside in a shared portion of the
application's address space. Spinlocks are only operated on
by the primitives above.
The spininit macro initializes the spinlock at location m
to the "unlocked" state. Spinlocks must be initialized
Page 1 CX/UX Programmer's Reference Manual
spin_trylock(2) CX/UX spin_trylock(2)
before they are used.
The spintrylock routine attempts to lock spinlock m. If it
succeeds it returns true; otherwise false. It does not
block its caller. The hc(1) compiler generates in line code
for this routine when the -F option is used.
The spinislock macro returns true if spinlock m is in the
locked state; otherwise false. It does not attempt to lock
the spinlock.
The spinunlock macro unlocks spinlock m.
EXAMPLES
To keep spinlock hold times small and predictable, threads
may wish to disable CPU rescheduling around a critical
region. (See reschedcntl(2). Threads may also wish
prevent page faults in a critical region, see plock(2) and
shmctl(2).) The following pseudo-code fragments acquire and
release both rescheduling locks and spinlocks. They contain
NO system calls and NO procedure calls when the -F option is
used with hc(1). _m points to a spinlock, and _r points to
the calling thread's rescheduling variable.
01 #define spinacquire(m,r) \
02 { \
03 reschedlock(r); \
04 while (! spintrylock(m)) { \
05 reschedunlock(r); \
06 while (spinislock(m)); \
07 reschedlock(r); \
08 } \
09 }
11 #define spinrelease(m,r) \
12 { \
13 spinunlock(m); \
14 reschedunlock(r); \
15 }
When a thread finds the spinlock locked, it waits for the
lock to clear with spinislock in line 6. In a shared-bus
multiprocessor with private, coherent, data caches, this
sequence is much more efficient than polling directly with
spintrylock. spintrylock contains an atomic test-and-set
instruction that bypasses the data cache to manipulate
memory across the shared bus. Spinislock reads from the
data cache and therefore generates very little bus traffic.
Note that CPU rescheduling is disabled in line 3 before
locking the spinlock and re-enabled in line 14 after unlock-
ing the spinlock -- an order needed to prevent deadlock.
Page 2 CX/UX Programmer's Reference Manual
spin_trylock(2) CX/UX spin_trylock(2)
CPU rescheduling is also re-enabled for the spin in line 6,
so as not to prevent rescheduling any longer than necessary.
RETURN VALUE
Spininit and spinunlock do not return values.
spintrylock returns true if it locked the spinlock; other-
wise false. Spinislock returns true if the spinlock is in
the locked state; otherwise false.
SEE ALSO
CX/UX Programmer's Guide.
hc(1).
gettid(2), reschedcntl(2), serverblock(2), and
clientblock(2).
TestandSet(3C).
Page 3 CX/UX Programmer's Reference Manual