summaryrefslogtreecommitdiffstats
path: root/5/sources/cxx-stl/stlport/stlport/stl/_threads.c
diff options
context:
space:
mode:
Diffstat (limited to '5/sources/cxx-stl/stlport/stlport/stl/_threads.c')
-rw-r--r--5/sources/cxx-stl/stlport/stlport/stl/_threads.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/5/sources/cxx-stl/stlport/stlport/stl/_threads.c b/5/sources/cxx-stl/stlport/stlport/stl/_threads.c
new file mode 100644
index 0000000..ea3c0b9
--- /dev/null
+++ b/5/sources/cxx-stl/stlport/stlport/stl/_threads.c
@@ -0,0 +1,167 @@
+/*
+ *
+ *
+ * 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 <stl/_threads.h>
+#endif
+
+#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
+
+#if defined (_STLP_SGI_THREADS)
+# include <time.h>
+#elif defined (_STLP_UNIX)
+# ifndef _STLP_INTERNAL_CTIME
+# include <stl/_ctime.h>
+# endif
+# if defined (_STLP_USE_NAMESPACES) && !defined (_STLP_VENDOR_GLOBAL_CSTD)
+using _STLP_VENDOR_CSTD::time_t;
+# endif
+# include <sys/time.h>
+#endif
+
+_STLP_BEGIN_NAMESPACE
+
+#if defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
+template<int __32bits>
+_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 <int __inst>
+unsigned _STLP_mutex_spin<__inst>::__max = _STLP_mutex_spin<__inst>::__low_max;
+
+template <int __inst>
+unsigned _STLP_mutex_spin<__inst>::__last = 0;
+#endif // _STLP_USE_PTHREAD_SPINLOCK
+
+#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 <int __inst>
+void _STLP_CALL
+_STLP_mutex_spin<__inst>::_S_nsec_sleep(int __log_nsec, unsigned int& __iteration) {
+# if defined (_STLP_WIN32THREADS)
+# if defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+ if (__iteration <= 4000) {
+ // Use SwitchToThread because
+ // 1) Sleep(1) often takes ~15 ms
+ // 2) SwitchToThread yields to lower-priority threads
+ // 4000 is enough to avoid Sleep and is used just to prevent infinite looping
+ // This number is advised spin count for Heap management by Microsoft
+ SwitchToThread();
+ } else {
+# endif
+ if (__log_nsec <= 21) {
+ /* Note from boost (www.boost.org):
+ * Changed from Sleep(0) to Sleep(1).
+ * 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));
+ }
+# if defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+ __iteration = 0; //reset to avoid sleeps sequence
+ }
+# endif
+# 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 <int __inst>
+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, __i);
+ }
+ } /* 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: