X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Fstl%2Fstl%2F_threads.c;fp=include%2Fc%2B%2B%2Fstl%2Fstl%2F_threads.c;h=40641e84eca69e4e41b8d36f30a075ba66270bae;hp=0000000000000000000000000000000000000000;hb=173d8903eb9d51a4ea7d7fa3e52dc86c9bb6d4f1;hpb=b024710fe2b60cd4a42a8993b61333d6cdb56ca3 diff --git a/include/c++/stl/stl/_threads.c b/include/c++/stl/stl/_threads.c new file mode 100644 index 0000000..40641e8 --- /dev/null +++ b/include/c++/stl/stl/_threads.c @@ -0,0 +1,171 @@ +/* + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Copyright (c) 1997 + * Moscow Center for SPARC Technology + * + * Copyright (c) 1999 + * Boris Fomitchev + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ +#ifndef _STLP_THREADS_C +#define _STLP_THREADS_C + +#ifndef _STLP_INTERNAL_THREADS_H +# include +#endif + +#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) + +#if defined (_STLP_SGI_THREADS) +# include +#elif defined (_STLP_UNIX) +# ifndef _STLP_INTERNAL_CTIME +# include +# endif +# if defined (_STLP_USE_NAMESPACES) && !defined (_STLP_VENDOR_GLOBAL_CSTD) +using _STLP_VENDOR_CSTD::time_t; +# endif +# include +#endif + +_STLP_BEGIN_NAMESPACE + +#if (_STLP_STATIC_TEMPLATE_DATA > 0) + +# if defined (_STLP_USE_ATOMIC_SWAP_MUTEX) +template +_STLP_STATIC_MUTEX +_Atomic_swap_struct<__32bits>::_S_swap_lock _STLP_MUTEX_INITIALIZER; +# undef _STLP_USE_ATOMIC_SWAP_MUTEX +# endif + +# if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) +template +unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max; + +template +unsigned _STLP_mutex_spin<__inst>::__last = 0; +# endif // _STLP_USE_PTHREAD_SPINLOCK + +#else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */ + +# if defined (_STLP_USE_ATOMIC_SWAP_MUTEX) +__DECLARE_INSTANCE(_STLP_STATIC_MUTEX, _Atomic_swap_struct::_S_swap_lock, + _STLP_MUTEX_INITIALIZER ); +# undef _STLP_USE_ATOMIC_SWAP_MUTEX +# endif /* _STLP_PTHREADS */ + +# if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) +__DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__max, =30); +__DECLARE_INSTANCE(unsigned, _STLP_mutex_spin<0>::__last, =0); +# endif // _STLP_USE_PTHREAD_SPINLOCK + +#endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */ + +#if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK) + +# if defined (_STLP_SPARC_SOLARIS_THREADS) +// underground function in libc.so; we do not want dependance on librt +extern "C" int __nanosleep(const struct timespec*, struct timespec*); +# define _STLP_NANOSLEEP __nanosleep +# else +# define _STLP_NANOSLEEP nanosleep +# endif + +template +void _STLP_CALL +_STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec) { +# if defined (_STLP_WIN32THREADS) + if (__log_nsec <= 20) { + // Note from boost (www.boost.org): + // Changed to Sleep(1) from Sleep(0). + // According to MSDN, Sleep(0) will never yield + // to a lower-priority thread, whereas Sleep(1) + // will. Performance seems not to be affected. + Sleep(1); + } else { + Sleep(1 << (__log_nsec - 20)); + } +# elif defined(_STLP_OS2THREADS) + if (__log_nsec <= 20) { + DosSleep(0); + } else { + DosSleep(1 << (__log_nsec - 20)); + } +# elif defined (_STLP_UNIX) + timespec __ts; + /* Max sleep is 2**27nsec ~ 60msec */ + __ts.tv_sec = 0; + __ts.tv_nsec = 1 << __log_nsec; + _STLP_NANOSLEEP(&__ts, 0); +# endif +} + +template +void _STLP_CALL +_STLP_mutex_spin<__inst>::_M_do_lock(volatile __stl_atomic_t* __lock) { +# if defined(_STLP_ATOMIC_EXCHANGE) + if (_Atomic_swap(__lock, 1)) { + unsigned __my_spin_max = _STLP_mutex_spin<0>::__max; + unsigned __my_last_spins = _STLP_mutex_spin<0>::__last; + volatile unsigned __junk = 17; // Value doesn't matter. + unsigned __i; + + for (__i = 0; __i < __my_spin_max; ++__i) { + if (__i < __my_last_spins/2 || *__lock) { + __junk *= __junk; __junk *= __junk; + __junk *= __junk; __junk *= __junk; + } else { + if (!_Atomic_swap(__lock, 1)) { + // got it! + // Spinning worked. Thus we're probably not being scheduled + // against the other process with which we were contending. + // Thus it makes sense to spin longer the next time. + _STLP_mutex_spin<0>::__last = __i; + _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__high_max; + return; + } + } + } + + // We are probably being scheduled against the other process. Sleep. + _STLP_mutex_spin<0>::__max = _STLP_mutex_spin<0>::__low_max; + + for (__i = 0 ;; ++__i) { + int __log_nsec = __i + 6; + + if (__log_nsec > 27) __log_nsec = 27; + if (!_Atomic_swap(__lock, 1)) { + break; + } + _S_nsec_sleep(__log_nsec); + } + } /* first _Atomic_swap */ +# endif +} +#endif // _STLP_USE_PTHREAD_SPINLOCK + +_STLP_END_NAMESPACE + +#endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */ +#endif /* _STLP_THREADS_C */ + +// Local Variables: +// mode:C++ +// End: