1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/stlportv5/stl/_threads.c Wed Mar 31 12:27:01 2010 +0100
1.3 @@ -0,0 +1,172 @@
1.4 +/*
1.5 + *
1.6 + *
1.7 + * Copyright (c) 1994
1.8 + * Hewlett-Packard Company
1.9 + *
1.10 + * Copyright (c) 1996,1997
1.11 + * Silicon Graphics Computer Systems, Inc.
1.12 + *
1.13 + * Copyright (c) 1997
1.14 + * Moscow Center for SPARC Technology
1.15 + *
1.16 + * Copyright (c) 1999
1.17 + * Boris Fomitchev
1.18 + *
1.19 + * This material is provided "as is", with absolutely no warranty expressed
1.20 + * or implied. Any use is at your own risk.
1.21 + *
1.22 + * Permission to use or copy this software for any purpose is hereby granted
1.23 + * without fee, provided the above notices are retained on all copies.
1.24 + * Permission to modify the code and to distribute modified code is granted,
1.25 + * provided the above notices are retained, and a notice that the code was
1.26 + * modified is included with the above copyright notice.
1.27 + *
1.28 + */
1.29 +#ifndef _STLP_THREADS_C
1.30 +#define _STLP_THREADS_C
1.31 +
1.32 +#ifndef _STLP_INTERNAL_THREADS_H
1.33 +# include <stl/_threads.h>
1.34 +#endif
1.35 +
1.36 +# if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
1.37 +
1.38 +# if defined(_STLP_SGI_THREADS)
1.39 +# include <time.h>
1.40 +# elif defined (_STLP_UNIX)
1.41 +# include <ctime>
1.42 +# if defined (_STLP_USE_NAMESPACES) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
1.43 +using _STLP_VENDOR_CSTD::time_t;
1.44 +# endif
1.45 +# include <sys/time.h>
1.46 +# endif
1.47 +
1.48 +_STLP_BEGIN_NAMESPACE
1.49 +
1.50 +# if (_STLP_STATIC_TEMPLATE_DATA > 0)
1.51 +
1.52 +# ifdef _STLP_THREADS
1.53 +# if !defined(_STLP_ATOMIC_EXCHANGE) && (defined(_STLP_PTHREADS) || defined(_STLP_UITHREADS) || defined(_STLP_OS2THREADS) || defined(_STLP_USE_PTHREAD_SPINLOCK))
1.54 +template<int __dummy>
1.55 +_STLP_STATIC_MUTEX
1.56 +_Swap_lock_struct<__dummy>::_S_swap_lock _STLP_MUTEX_INITIALIZER;
1.57 +# endif
1.58 +# endif //_STLP_THREADS
1.59 +
1.60 +# ifndef _STLP_USE_PTHREAD_SPINLOCK
1.61 +template <int __inst>
1.62 +unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max;
1.63 +
1.64 +template <int __inst>
1.65 +unsigned _STLP_mutex_spin<__inst>::__last = 0;
1.66 +# endif // _STLP_USE_PTHREAD_SPINLOCK
1.67 +
1.68 +# else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
1.69 +
1.70 +# if defined(_STLP_PTHREADS) || defined(_STLP_UITHREADS) || defined(_STLP_OS2THREADS)
1.71 +__DECLARE_INSTANCE(_STLP_STATIC_MUTEX, _Swap_lock_struct<0>::_S_swap_lock,
1.72 + _STLP_MUTEX_INITIALIZER );
1.73 +# endif /* _STLP_PTHREADS */
1.74 +
1.75 +# ifndef _STLP_USE_PTHREAD_SPINLOCK
1.76 +__DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__max, =30);
1.77 +__DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__last, =0);
1.78 +# endif // _STLP_USE_PTHREAD_SPINLOCK
1.79 +
1.80 +# endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
1.81 +
1.82 +#ifndef _STLP_USE_PTHREAD_SPINLOCK
1.83 +
1.84 +#ifdef _STLP_SPARC_SOLARIS_THREADS
1.85 +// underground function in libc.so; we do not want dependance on librt
1.86 +extern "C" int __nanosleep(const struct timespec*, struct timespec*);
1.87 +# define _STLP_NANOSLEEP __nanosleep
1.88 +#else
1.89 +# define _STLP_NANOSLEEP nanosleep
1.90 +#endif
1.91 +
1.92 +template <int __inst>
1.93 +void _STLP_CALL
1.94 +_STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec) {
1.95 +# if defined(_STLP_WIN32THREADS)
1.96 + if (__log_nsec <= 20) {
1.97 + // Note from boost (www.boost.org):
1.98 + // Changed to Sleep(1) from Sleep(0).
1.99 + // According to MSDN, Sleep(0) will never yield
1.100 + // to a lower-priority thread, whereas Sleep(1)
1.101 + // will. Performance seems not to be affected.
1.102 + Sleep(1);
1.103 + } else {
1.104 + Sleep(1 << (__log_nsec - 20));
1.105 + }
1.106 +# elif defined(_STLP_OS2THREADS)
1.107 + if (__log_nsec <= 20) {
1.108 + DosSleep(0);
1.109 + } else {
1.110 + DosSleep(1 << (__log_nsec - 20));
1.111 + }
1.112 +# elif defined (_STLP_UNIX)
1.113 + timespec __ts;
1.114 + /* Max sleep is 2**27nsec ~ 60msec */
1.115 + __ts.tv_sec = 0;
1.116 + __ts.tv_nsec = 1 << __log_nsec;
1.117 + _STLP_NANOSLEEP(&__ts, 0);
1.118 +# endif
1.119 + }
1.120 +
1.121 +
1.122 +template <int __inst>
1.123 +void _STLP_CALL
1.124 +_STLP_mutex_spin<__inst>::_M_do_lock(volatile __stl_atomic_t* __lock)
1.125 +{
1.126 +#if defined(_STLP_ATOMIC_EXCHANGE)
1.127 + if (_Atomic_swap(__lock, 1)) {
1.128 + unsigned __my_spin_max = _STLP_mutex_spin<0>::__max;
1.129 + unsigned __my_last_spins = _STLP_mutex_spin<0>::__last;
1.130 + volatile unsigned __junk = 17; // Value doesn't matter.
1.131 + unsigned __i;
1.132 +
1.133 + for (__i = 0; __i < __my_spin_max; ++__i) {
1.134 + if (__i < __my_last_spins/2 || *__lock) {
1.135 + __junk *= __junk; __junk *= __junk;
1.136 + __junk *= __junk; __junk *= __junk;
1.137 + } else {
1.138 + if (!_Atomic_swap(__lock, 1)) {
1.139 + // got it!
1.140 + // Spinning worked. Thus we're probably not being scheduled
1.141 + // against the other process with which we were contending.
1.142 + // Thus it makes sense to spin longer the next time.
1.143 + _STLP_mutex_spin<0>::__last = __i;
1.144 + _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__high_max;
1.145 + return;
1.146 + }
1.147 + }
1.148 + }
1.149 +
1.150 + // We are probably being scheduled against the other process. Sleep.
1.151 + _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__low_max;
1.152 +
1.153 + for (__i = 0 ;; ++__i) {
1.154 + int __log_nsec = __i + 6;
1.155 +
1.156 + if (__log_nsec > 27) __log_nsec = 27;
1.157 + if (!_Atomic_swap(__lock, 1)) {
1.158 + break;
1.159 + }
1.160 + _S_nsec_sleep(__log_nsec);
1.161 + }
1.162 +
1.163 + } /* first _Atomic_swap */
1.164 +# endif
1.165 +}
1.166 +#endif // _STLP_USE_PTHREAD_SPINLOCK
1.167 +
1.168 +_STLP_END_NAMESPACE
1.169 +
1.170 +# endif /* BUILDING_STLPORT */
1.171 +#endif /* _STLP_THREADS_C */
1.172 +
1.173 +// Local Variables:
1.174 +// mode:C++
1.175 +// End: