home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _threads.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  4KB  |  153 lines

  1. /*
  2.  *
  3.  *
  4.  * Copyright (c) 1994
  5.  * Hewlett-Packard Company
  6.  *
  7.  * Copyright (c) 1996,1997
  8.  * Silicon Graphics Computer Systems, Inc.
  9.  *
  10.  * Copyright (c) 1997
  11.  * Moscow Center for SPARC Technology
  12.  *
  13.  * Copyright (c) 1999 
  14.  * Boris Fomitchev
  15.  *
  16.  * This material is provided "as is", with absolutely no warranty expressed
  17.  * or implied. Any use is at your own risk.
  18.  *
  19.  * Permission to use or copy this software for any purpose is hereby granted 
  20.  * without fee, provided the above notices are retained on all copies.
  21.  * Permission to modify the code and to distribute modified code is granted,
  22.  * provided the above notices are retained, and a notice that the code was
  23.  * modified is included with the above copyright notice.
  24.  *
  25.  */
  26. #ifndef _STLP_THREADS_C
  27. #define _STLP_THREADS_C
  28.  
  29. #ifndef _STLP_INTERNAL_THREADS_H
  30. # include <stl/_threads.h>
  31. #endif
  32.  
  33. # if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
  34.  
  35. # if defined(_STLP_SGI_THREADS)
  36. #  include <time.h>
  37. # elif defined (_STLP_UNIX)
  38. #  include <ctime>
  39. # if defined (_STLP_USE_NAMESPACES) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
  40. using _STLP_VENDOR_CSTD::time_t;
  41. # endif
  42. #  include <sys/time.h>
  43. # endif
  44.  
  45. _STLP_BEGIN_NAMESPACE
  46.  
  47. # if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
  48.  
  49. #  if !defined ( _STLP_ATOMIC_EXCHANGE ) && (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS))
  50. template<int __dummy>
  51. _STLP_STATIC_MUTEX
  52. _Swap_lock_struct<__dummy>::_S_swap_lock _STLP_MUTEX_INITIALIZER;
  53. #  endif
  54.  
  55. template <int __inst>
  56. unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max;
  57.  
  58. template <int __inst>
  59. unsigned _STLP_mutex_spin<__inst>::__last = 0;
  60.  
  61. # else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  62.  
  63. #  if defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS)  || defined (_STLP_OS2THREADS)
  64. __DECLARE_INSTANCE(_STLP_STATIC_MUTEX, _Swap_lock_struct<0>::_S_swap_lock, 
  65.                    _STLP_MUTEX_INITIALIZER  );
  66. #  endif /* _STLP_PTHREADS */
  67.  
  68. __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__max,  =30);
  69. __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__last, =0);
  70.  
  71. # endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  72.  
  73. #ifdef _STLP_SPARC_SOLARIS_THREADS
  74. // underground function in libc.so; we do not want dependance on librt
  75. extern "C" int __nanosleep(const struct timespec*, struct timespec*);
  76. # define _STLP_NANOSLEEP __nanosleep
  77. #else
  78. # define _STLP_NANOSLEEP nanosleep
  79. #endif
  80.  
  81. template <int __inst>
  82. void _STLP_CALL
  83. _STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec) {
  84. #     if defined(_STLP_WIN32THREADS)
  85.       if (__log_nsec <= 20) {
  86.           Sleep(0);
  87.       } else {
  88.           Sleep(1 << (__log_nsec - 20));
  89.       }
  90. #     elif defined (_STLP_UNIX)
  91.           timespec __ts;
  92.           /* Max sleep is 2**27nsec ~ 60msec      */
  93.           __ts.tv_sec = 0;
  94.           __ts.tv_nsec = 1 << __log_nsec;
  95.           _STLP_NANOSLEEP(&__ts, 0);
  96. #     endif
  97.   }
  98.  
  99.  
  100. template <int __inst>
  101. void  _STLP_CALL
  102. _STLP_mutex_spin<__inst>::_M_do_lock(volatile __stl_atomic_t* __lock)
  103. {
  104. #if defined(_STLP_ATOMIC_EXCHANGE)
  105.   if (_Atomic_swap(__lock, 1)) {
  106.     unsigned __my_spin_max = _STLP_mutex_spin<0>::__max;
  107.     unsigned __my_last_spins = _STLP_mutex_spin<0>::__last;
  108.     volatile unsigned __junk = 17;     // Value doesn't matter.
  109.     unsigned  __i;
  110.     
  111.     for (__i = 0; __i < __my_spin_max; ++__i) {
  112.       if (__i < __my_last_spins/2 || *__lock) {
  113.         __junk *= __junk; __junk *= __junk;
  114.         __junk *= __junk; __junk *= __junk;
  115.       } else {
  116.         if (!_Atomic_swap(__lock, 1)) {
  117.           // got it!
  118.           // Spinning worked.  Thus we're probably not being scheduled
  119.           // against the other process with which we were contending.
  120.           // Thus it makes sense to spin longer the next time.
  121.           _STLP_mutex_spin<0>::__last = __i;
  122.           _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__high_max;
  123.         return;
  124.         }
  125.       }
  126.     }
  127.     
  128.     // We are probably being scheduled against the other process.  Sleep.
  129.     _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__low_max;
  130.     
  131.     for (__i = 0 ;; ++__i) {
  132.       int __log_nsec = __i + 6;
  133.       
  134.       if (__log_nsec > 27) __log_nsec = 27;
  135.       if (!_Atomic_swap(__lock, 1)) {
  136.       break;
  137.       }
  138.       _S_nsec_sleep(__log_nsec);
  139.     }
  140.     
  141.   } /* first _Atomic_swap */
  142. # endif
  143. }
  144.  
  145. _STLP_END_NAMESPACE
  146.  
  147. # endif /* BUILDING_STLPORT */
  148. #endif /*  _STLP_THREADS_C */
  149.  
  150. // Local Variables:
  151. // mode:C++
  152. // End:
  153.