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