epoc32/include/stdapis/stlport/stl/_threads.c
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
parent 0 061f57f2323e
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     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: