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               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



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