epoc32/include/stdapis/stlport/stl/_threads.c
branchSymbian2
changeset 2 2fe1408b6811
parent 0 061f57f2323e
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
     1 _threads.c
     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 #  ifdef _STLP_THREADS
       
    50 #  if !defined(_STLP_ATOMIC_EXCHANGE) && (defined(_STLP_PTHREADS) || defined(_STLP_UITHREADS) || defined(_STLP_OS2THREADS) || defined(_STLP_USE_PTHREAD_SPINLOCK))
       
    51 template<int __dummy>
       
    52 _STLP_STATIC_MUTEX
       
    53 _Swap_lock_struct<__dummy>::_S_swap_lock _STLP_MUTEX_INITIALIZER;
       
    54 #  endif
       
    55 #  endif //_STLP_THREADS
       
    56 
       
    57 #  ifndef _STLP_USE_PTHREAD_SPINLOCK
       
    58 template <int __inst>
       
    59 unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max;
       
    60 
       
    61 template <int __inst>
       
    62 unsigned _STLP_mutex_spin<__inst>::__last = 0;
       
    63 #  endif // _STLP_USE_PTHREAD_SPINLOCK
       
    64 
       
    65 # else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
       
    66 
       
    67 #  if defined(_STLP_PTHREADS) || defined(_STLP_UITHREADS) || defined(_STLP_OS2THREADS)
       
    68 __DECLARE_INSTANCE(_STLP_STATIC_MUTEX, _Swap_lock_struct<0>::_S_swap_lock, 
       
    69                    _STLP_MUTEX_INITIALIZER  );
       
    70 #  endif /* _STLP_PTHREADS */
       
    71 
       
    72 #  ifndef _STLP_USE_PTHREAD_SPINLOCK
       
    73 __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__max,  =30);
       
    74 __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__last, =0);
       
    75 #  endif // _STLP_USE_PTHREAD_SPINLOCK
       
    76 
       
    77 # endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
       
    78 
       
    79 #ifndef _STLP_USE_PTHREAD_SPINLOCK
       
    80 
       
    81 #ifdef _STLP_SPARC_SOLARIS_THREADS
       
    82 // underground function in libc.so; we do not want dependance on librt
       
    83 extern "C" int __nanosleep(const struct timespec*, struct timespec*);
       
    84 # define _STLP_NANOSLEEP __nanosleep
       
    85 #else
       
    86 # define _STLP_NANOSLEEP nanosleep
       
    87 #endif
       
    88 
       
    89 template <int __inst>
       
    90 void _STLP_CALL
       
    91 _STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec) {
       
    92 #     if defined(_STLP_WIN32THREADS)
       
    93 	  if (__log_nsec <= 20) {
       
    94         // Note from boost (www.boost.org): 
       
    95         // Changed to Sleep(1) from Sleep(0).
       
    96         // According to MSDN, Sleep(0) will never yield
       
    97         // to a lower-priority thread, whereas Sleep(1)
       
    98         // will. Performance seems not to be affected.
       
    99 	      Sleep(1);
       
   100 	  } else {
       
   101 	      Sleep(1 << (__log_nsec - 20));
       
   102 	  }
       
   103 #    elif defined(_STLP_OS2THREADS)
       
   104       if (__log_nsec <= 20) {
       
   105          DosSleep(0);
       
   106       } else {
       
   107          DosSleep(1 << (__log_nsec - 20));
       
   108       }
       
   109 #     elif defined (_STLP_UNIX)
       
   110           timespec __ts;
       
   111           /* Max sleep is 2**27nsec ~ 60msec      */
       
   112           __ts.tv_sec = 0;
       
   113           __ts.tv_nsec = 1 << __log_nsec;
       
   114           _STLP_NANOSLEEP(&__ts, 0);
       
   115 #     endif
       
   116   }
       
   117 
       
   118 
       
   119 template <int __inst>
       
   120 void  _STLP_CALL
       
   121 _STLP_mutex_spin<__inst>::_M_do_lock(volatile __stl_atomic_t* __lock)
       
   122 {
       
   123 #if defined(_STLP_ATOMIC_EXCHANGE)
       
   124   if (_Atomic_swap(__lock, 1)) {
       
   125     unsigned __my_spin_max = _STLP_mutex_spin<0>::__max;
       
   126     unsigned __my_last_spins = _STLP_mutex_spin<0>::__last;
       
   127     volatile unsigned __junk = 17; 	// Value doesn't matter.
       
   128     unsigned  __i;
       
   129     
       
   130     for (__i = 0; __i < __my_spin_max; ++__i) {
       
   131       if (__i < __my_last_spins/2 || *__lock) {
       
   132         __junk *= __junk; __junk *= __junk;
       
   133         __junk *= __junk; __junk *= __junk;
       
   134       } else {
       
   135         if (!_Atomic_swap(__lock, 1)) {
       
   136           // got it!
       
   137           // Spinning worked.  Thus we're probably not being scheduled
       
   138           // against the other process with which we were contending.
       
   139           // Thus it makes sense to spin longer the next time.
       
   140           _STLP_mutex_spin<0>::__last = __i;
       
   141           _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__high_max;
       
   142 	    return;
       
   143         }
       
   144       }
       
   145     }
       
   146     
       
   147     // We are probably being scheduled against the other process.  Sleep.
       
   148     _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__low_max;
       
   149     
       
   150     for (__i = 0 ;; ++__i) {
       
   151       int __log_nsec = __i + 6;
       
   152       
       
   153       if (__log_nsec > 27) __log_nsec = 27;
       
   154       if (!_Atomic_swap(__lock, 1)) {
       
   155 	  break;
       
   156       }
       
   157       _S_nsec_sleep(__log_nsec);
       
   158     }
       
   159     
       
   160   } /* first _Atomic_swap */
       
   161 # endif
       
   162 }
       
   163 #endif // _STLP_USE_PTHREAD_SPINLOCK
       
   164 
       
   165 _STLP_END_NAMESPACE
       
   166 
       
   167 # endif /* BUILDING_STLPORT */
       
   168 #endif /*  _STLP_THREADS_C */
       
   169 
       
   170 // Local Variables:
       
   171 // mode:C++
       
   172 // End: