spin_trylock(2) CX/UX spin_trylock(2)
NAME
spin_init, spin_trylock, spin_islock, spin_unlock - busy-
wait mutual exclusion
SYNOPSIS
#include <sys/types.h>
#include <sys/thread_synch.h>
void spin_init (m)
struct spin_mutex *m;
int spin_trylock (m)
struct spin_mutex *m;
int spin_islock (m)
struct spin_mutex *m;
void spin_unlock (m)
struct spin_mutex *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
spin_mutex
struct spin_mutex {};
defined in <sys/thread_synch.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 spin_init 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 spin_trylock 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 spin_islock macro returns true if spinlock m is in the
locked state; otherwise false. It does not attempt to lock
the spinlock.
The spin_unlock 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 resched_cntl(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 spin_acquire(_m,_r) \
02 { \
03 resched_lock(_r); \
04 while (! spin_trylock(_m)) { \
05 resched_unlock(_r); \
06 while (spin_islock(_m)); \
07 resched_lock(_r); \
08 } \
09 }
11 #define spin_release(_m,_r) \
12 { \
13 spin_unlock(_m); \
14 resched_unlock(_r); \
15 }
When a thread finds the spinlock locked, it waits for the
lock to clear with spin_islock in line 6. In a shared-bus
multiprocessor with private, coherent, data caches, this
sequence is much more efficient than polling directly with
spin_trylock. spin_trylock contains an atomic test-and-set
instruction that bypasses the data cache to manipulate
memory across the shared bus. Spin_islock 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
Spin_init and spin_unlock do not return values.
spin_trylock returns true if it locked the spinlock; other-
wise false. Spin_islock returns true if the spinlock is in
the locked state; otherwise false.
SEE ALSO
CX/UX Programmer's Guide.
hc(1).
gettid(2), resched_cntl(2), server_block(2), and
client_block(2).
Test_and_Set(3C).
Page 3 CX/UX Programmer's Reference Manual