Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

hc(1)

gettid(2)

resched_cntl(2)

server_block(2)

client_block(2)

Test_and_Set(3C)

spin_trylock(2)  —  CX/UX

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.  Serialization is frequently achieved by associating a "synchronizing variable" with the shared resource, "locking" the synchronizing 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 variable 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 commonly 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 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 unlocking the spinlock -- an order needed to prevent deadlock.  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; otherwise 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). 

CX/UX Programmer’s Reference Manual

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026