_threads.c

来自「stl的源码」· C语言 代码 · 共 168 行

C
168
字号
/* * * * 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 librtextern "C" int __nanosleep(const struct timespec*, struct timespec*);#    define _STLP_NANOSLEEP __nanosleep#  else#    define _STLP_NANOSLEEP nanosleep#  endiftemplate <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:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?