home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / quartz / quartz10.lha / src / presto / spinlock_impl.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  3.6 KB  |  164 lines

  1.  
  2. // Spinlock inline implementations
  3. // Must follow defs for threads, but precede everything else.
  4. //
  5. // Modification History:
  6. //
  7. // 28-Dec-1989  JEF
  8. // Add class HC_Spinlock (for sequent symmetry only).  This variation of
  9. // a spinlock works well when there is high contention for the lock.
  10. // After original by raj.
  11. //
  12. #if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
  13.  
  14. /*
  15.  * Optimized version of S_LOCK to only make the procedure call
  16.  * if the lock is held.  Would really like to use S_LOCK here,
  17.  * but (potentially) inline functions can't handle loops.
  18.  */
  19.  
  20. SPINLOCK_INLINE 
  21. void
  22. Spinlock::lock()
  23. {
  24. #ifdef    ns32000
  25.     char    *lock_alm = &_alm_base[ALM_HASH(sl_lock)]; 
  26. #endif
  27.  
  28.     //
  29.     // Must mark ourselves in the lock even before we acquire it.
  30.     // Otherwise, we could hold the lock and be preempted.  If we
  31.     // were holding the lock on something that the preemption code
  32.     // needed (or someone else, in order to ensure we run), we would
  33.     // deadlock.  Must make lock acquisition and thread in spin cs
  34.     // marking atomic.
  35.     //
  36.  
  37. #ifndef NO_PREEMPT
  38.     thisthread->holdingspinlock();
  39. #endif  NO_PREEMPT
  40.  
  41. #ifdef ns32000
  42.     if (sl_lock == L_LOCKED)        // u lose
  43.         (void)s_lock(&sl_lock);
  44.     else if (*lock_alm & ALM_LOCKED)    // u lose
  45.         (void)s_lock(&sl_lock);
  46.     else if (sl_lock == L_LOCKED) {        // u lose (race condition)
  47.         *lock_alm = ALM_UNLOCKED;
  48.         (void)s_lock(&sl_lock);
  49.     } else    {                // u win
  50.         sl_lock = L_LOCKED;
  51.         *lock_alm = ALM_UNLOCKED;
  52.     }
  53. #else
  54.     //
  55.     // No ALM's in Symmetry.  We use S_LOCK() and to avoid
  56.     // another out-of-line call.  Since C++ doesn't understand
  57.     // asm-functions, must use "CC +hasmdefs.h".
  58.     //
  59.     // On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
  60.     // Should probably be inline.
  61.     //
  62. //cout << "regular old spinlock.lock\n"; cout.flush ();
  63. #ifdef PROFILE
  64.     SLLock(sl_q);
  65. #endif
  66.     (void) S_LOCK(&sl_lock);
  67. #endif
  68. }
  69.  
  70.  
  71. SPINLOCK_INLINE
  72. void
  73. Spinlock::unlock()
  74. {
  75.  
  76. //cout << "regular old spinlock.unlock\n"; cout.flush ();
  77.     (void) S_UNLOCK(&sl_lock);
  78. #ifdef PROFILE
  79.     SLUnlock(sl_q);
  80. #endif
  81. #ifndef NO_PREEMPT
  82.     thisthread->releasingspinlock();
  83. #endif  NO_PREEMPT
  84.  
  85. }
  86.  
  87. SPINLOCK_INLINE
  88. Spinlock::~Spinlock()
  89. {
  90.     //
  91.     // We should abort if the lock is not free. (?) XXX
  92.     // For now just unlock it for backward compatibility.
  93.     //
  94.     if (testlock())
  95.         unlock();
  96. #ifdef PROFILE
  97.     SLDispose(sl_q);
  98. #endif
  99.         
  100. }
  101.  
  102.  
  103. #endif DO_SPINLOCK_INLINE || SPINLOCK_C
  104.  
  105.  
  106.  
  107. //
  108. //  HC_Spinlock inline implementations.
  109. //
  110. #ifdef i386
  111.  
  112. SPINLOCK_INLINE 
  113. void
  114. HC_Spinlock::lock()
  115. {
  116.     //
  117.     // Must mark ourselves in the lock even before we acquire it.
  118.     // Otherwise, we could hold the lock and be preempted.  If we
  119.     // were holding the lock on something that the preemption code
  120.     // needed (or someone else, in order to ensure we run), we would
  121.     // deadlock.  Must make lock acquisition and thread in spin cs
  122.     // marking atomic.
  123.     //
  124. #ifndef NO_PREEMPT
  125.     thisthread->holdingspinlock();
  126. #endif  NO_PREEMPT
  127.  
  128.     //
  129.     // HC_S_LOCK is an inline straight C asm function defined in
  130.     // hc_slock_asm.h, which is pulled into the C++ C output via
  131.     // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
  132.         //
  133. //cout << "high contention spinlock.lock\n"; cout.flush ();
  134. #ifdef PROFILE
  135.     SLLock(sl_q);
  136. #endif
  137.     (void) HC_S_LOCK(&sl_lock);
  138. }
  139.  
  140.  
  141. inline
  142. void
  143. HC_Spinlock::unlock()
  144. {
  145.     //
  146.     // HC_S_UNLOCK is an inline straight C asm function defined in
  147.     // hc_slock_asm.h, which is pulled into the C++ C output via
  148.     // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
  149.         //
  150.  
  151. //cout << "high contention spinlock.unlock\n"; cout.flush ();
  152.  
  153.     (void) HC_S_UNLOCK(&sl_lock);
  154. #ifdef PROFILE
  155.     SLUnlock(sl_q);
  156. #endif
  157.  
  158. #ifndef NO_PREEMPT
  159.     thisthread->releasingspinlock();
  160. #endif  NO_PREEMPT
  161. }
  162.  
  163. #endif i386
  164.