/home/ntakagi/work/STLport-5.1.5/stlport/stl/_threads.cGo to the documentation of this file.00001 /* 00002 * 00003 * 00004 * Copyright (c) 1994 00005 * Hewlett-Packard Company 00006 * 00007 * Copyright (c) 1996,1997 00008 * Silicon Graphics Computer Systems, Inc. 00009 * 00010 * Copyright (c) 1997 00011 * Moscow Center for SPARC Technology 00012 * 00013 * Copyright (c) 1999 00014 * Boris Fomitchev 00015 * 00016 * This material is provided "as is", with absolutely no warranty expressed 00017 * or implied. Any use is at your own risk. 00018 * 00019 * Permission to use or copy this software for any purpose is hereby granted 00020 * without fee, provided the above notices are retained on all copies. 00021 * Permission to modify the code and to distribute modified code is granted, 00022 * provided the above notices are retained, and a notice that the code was 00023 * modified is included with the above copyright notice. 00024 * 00025 */ 00026 #ifndef _STLP_THREADS_C 00027 #define _STLP_THREADS_C 00028 00029 #ifndef _STLP_INTERNAL_THREADS_H 00030 # include <stl/_threads.h> 00031 #endif 00032 00033 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) 00034 00035 #if defined (_STLP_SGI_THREADS) 00036 # include <time.h> 00037 #elif defined (_STLP_UNIX) 00038 # ifndef _STLP_INTERNAL_CTIME 00039 # include <stl/_ctime.h> 00040 # endif 00041 # if defined (_STLP_USE_NAMESPACES) && !defined (_STLP_VENDOR_GLOBAL_CSTD) 00042 using _STLP_VENDOR_CSTD::time_t; 00043 # endif 00044 # include <sys/time.h> 00045 #endif 00046 00047 _STLP_BEGIN_NAMESPACE 00048 00049 #if (_STLP_STATIC_TEMPLATE_DATA > 0) 00050 00051 # if defined (_STLP_USE_ATOMIC_SWAP_MUTEX) 00052 template<int __32bits> 00053 _STLP_STATIC_MUTEX 00054 _Atomic_swap_struct<__32bits>::_S_swap_lock _STLP_MUTEX_INITIALIZER; 00055 # undef _STLP_USE_ATOMIC_SWAP_MUTEX 00056 # endif 00057 00058 # if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) 00059 template <int __inst> 00060 unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max; 00061 00062 template <int __inst> 00063 unsigned _STLP_mutex_spin<__inst>::__last = 0; 00064 # endif // _STLP_USE_PTHREAD_SPINLOCK 00065 00066 #else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */ 00067 00068 # if defined (_STLP_USE_ATOMIC_SWAP_MUTEX) 00069 __DECLARE_INSTANCE(_STLP_STATIC_MUTEX, _Atomic_swap_struct<sizeof(__stl_atomic_t) == sizeof(void*)>::_S_swap_lock, 00070 _STLP_MUTEX_INITIALIZER ); 00071 # undef _STLP_USE_ATOMIC_SWAP_MUTEX 00072 # endif /* _STLP_PTHREADS */ 00073 00074 # if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) 00075 __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__max, =30); 00076 __DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__last, =0); 00077 # endif // _STLP_USE_PTHREAD_SPINLOCK 00078 00079 #endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */ 00080 00081 #if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) 00082 00083 # if defined (_STLP_SPARC_SOLARIS_THREADS) 00084 // underground function in libc.so; we do not want dependance on librt 00085 extern "C" int __nanosleep(const struct timespec*, struct timespec*); 00086 # define _STLP_NANOSLEEP __nanosleep 00087 # else 00088 # define _STLP_NANOSLEEP nanosleep 00089 # endif 00090 00091 template <int __inst> 00092 void _STLP_CALL 00093 _STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec) { 00094 # if defined (_STLP_WIN32THREADS) 00095 if (__log_nsec <= 20) { 00096 // Note from boost (www.boost.org): 00097 // Changed to Sleep(1) from Sleep(0). 00098 // According to MSDN, Sleep(0) will never yield 00099 // to a lower-priority thread, whereas Sleep(1) 00100 // will. Performance seems not to be affected. 00101 Sleep(1); 00102 } else { 00103 Sleep(1 << (__log_nsec - 20)); 00104 } 00105 # elif defined(_STLP_OS2THREADS) 00106 if (__log_nsec <= 20) { 00107 DosSleep(0); 00108 } else { 00109 DosSleep(1 << (__log_nsec - 20)); 00110 } 00111 # elif defined (_STLP_UNIX) 00112 timespec __ts; 00113 /* Max sleep is 2**27nsec ~ 60msec */ 00114 __ts.tv_sec = 0; 00115 __ts.tv_nsec = 1 << __log_nsec; 00116 _STLP_NANOSLEEP(&__ts, 0); 00117 # endif 00118 } 00119 00120 template <int __inst> 00121 void _STLP_CALL 00122 _STLP_mutex_spin<__inst>::_M_do_lock(volatile __stl_atomic_t* __lock) { 00123 # if defined(_STLP_ATOMIC_EXCHANGE) 00124 if (_Atomic_swap(__lock, 1)) { 00125 unsigned __my_spin_max = _STLP_mutex_spin<0>::__max; 00126 unsigned __my_last_spins = _STLP_mutex_spin<0>::__last; 00127 volatile unsigned __junk = 17; // Value doesn't matter. 00128 unsigned __i; 00129 00130 for (__i = 0; __i < __my_spin_max; ++__i) { 00131 if (__i < __my_last_spins/2 || *__lock) { 00132 __junk *= __junk; __junk *= __junk; 00133 __junk *= __junk; __junk *= __junk; 00134 } else { 00135 if (!_Atomic_swap(__lock, 1)) { 00136 // got it! 00137 // Spinning worked. Thus we're probably not being scheduled 00138 // against the other process with which we were contending. 00139 // Thus it makes sense to spin longer the next time. 00140 _STLP_mutex_spin<0>::__last = __i; 00141 _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__high_max; 00142 return; 00143 } 00144 } 00145 } 00146 00147 // We are probably being scheduled against the other process. Sleep. 00148 _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__low_max; 00149 00150 for (__i = 0 ;; ++__i) { 00151 int __log_nsec = __i + 6; 00152 00153 if (__log_nsec > 27) __log_nsec = 27; 00154 if (!_Atomic_swap(__lock, 1)) { 00155 break; 00156 } 00157 _S_nsec_sleep(__log_nsec); 00158 } 00159 } /* first _Atomic_swap */ 00160 # endif 00161 } 00162 #endif // _STLP_USE_PTHREAD_SPINLOCK 00163 00164 _STLP_END_NAMESPACE 00165 00166 #endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */ 00167 #endif /* _STLP_THREADS_C */ 00168 00169 // Local Variables: 00170 // mode:C++ 00171 // End:
Generated on Mon Mar 10 15:32:41 2008 by ![]() |