@ -31,25 +31,33 @@
* macros at the bottom of the file . Check if your platform can use
* these or needs to override them .
*
* Usually , S_LOCK ( ) is implemented in terms of an even lower - level macro
* TAS ( ) :
* Usually , S_LOCK ( ) is implemented in terms of even lower - level macros
* TAS ( ) and TAS_SPIN ( ) :
*
* int TAS ( slock_t * lock )
* Atomic test - and - set instruction . Attempt to acquire the lock ,
* but do * not * wait . Returns 0 if successful , nonzero if unable
* to acquire the lock .
*
* TAS ( ) is NOT part of the API , and should never be called directly .
* int TAS_SPIN ( slock_t * lock )
* Like TAS ( ) , but this version is used when waiting for a lock
* previously found to be contended . Typically , this is the
* same as TAS ( ) , but on some architectures it ' s better to poll a
* contended lock using an unlocked instruction and retry the
* atomic test - and - set only when it appears free .
*
* CAUTION : on some platforms TAS ( ) may sometimes report failure to acquire
* a lock even when the lock is not locked . For example , on Alpha TAS ( )
* will " fail " if interrupted . Therefore TAS ( ) should always be invoked
* in a retry loop , even if you are certain the lock is free .
* TAS ( ) and TAS_SPIN ( ) are NOT part of the API , and should never be called
* directly .
*
* ANOTHER CAUTION : be sure that TAS ( ) and S_UNLOCK ( ) represent sequence
* points , ie , loads and stores of other values must not be moved across
* a lock or unlock . In most cases it suffices to make the operation be
* done through a " volatile " pointer .
* CAUTION : on some platforms TAS ( ) and / or TAS_SPIN ( ) may sometimes report
* failure to acquire a lock even when the lock is not locked . For example ,
* on Alpha TAS ( ) will " fail " if interrupted . Therefore a retry loop must
* always be used , even if you are certain the lock is free .
*
* ANOTHER CAUTION : be sure that TAS ( ) , TAS_SPIN ( ) , and S_UNLOCK ( ) represent
* sequence points , ie , loads and stores of other values must not be moved
* across a lock or unlock . In most cases it suffices to make the operation
* be done through a " volatile " pointer .
*
* On most supported platforms , TAS ( ) uses a tas ( ) function written
* in assembly language to execute a hardware atomic - test - and - set
@ -727,6 +735,7 @@ typedef unsigned int slock_t;
# include <ia64/sys/inline.h>
# define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
# define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
# endif /* HPUX on IA64, non gcc */
@ -925,6 +934,10 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
# define TAS(lock) tas(lock)
# endif /* TAS */
# if !defined(TAS_SPIN)
# define TAS_SPIN(lock) TAS(lock)
# endif /* TAS_SPIN */
/*
* Platform - independent out - of - line support routines