ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

_threads.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1997-1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 // WARNING: This is an internal header file, included by other C++
00020 // standard library headers.  You should not attempt to use this header
00021 // file directly.
00022 
00023 
00024 #ifndef _STLP_INTERNAL_THREADS_H
00025 #define _STLP_INTERNAL_THREADS_H
00026 
00027 // Supported threading models are native SGI, pthreads, uithreads
00028 // (similar to pthreads, but based on an earlier draft of the Posix
00029 // threads standard), and Win32 threads.  Uithread support by Jochen
00030 // Schlick, 1999, and Solaris threads generalized to them.
00031 
00032 #ifndef _STLP_INTERNAL_CSTDDEF
00033 #  include <stl/_cstddef.h>
00034 #endif
00035 
00036 #ifndef _STLP_INTERNAL_CSTDLIB
00037 #  include <stl/_cstdlib.h>
00038 #endif
00039 
00040 // On SUN and Mac OS X gcc, zero-initialization works just fine...
00041 #if defined (__sun) || (defined (__GNUC__) && defined(__APPLE__))
00042 #  define _STLP_MUTEX_INITIALIZER
00043 #endif
00044 
00045 /* This header defines the following atomic operation that platform should
00046  * try to support as much as possible. Atomic operation are exposed as macro
00047  * in order to easily test for their existance. They are:
00048  * __stl_atomic_t _STLP_ATOMIC_INCREMENT(volatile __stl_atomic_t* __ptr) :
00049  * increment *__ptr by 1 and returns the new value
00050  * __stl_atomic_t _STLP_ATOMIC_DECREMENT(volatile __stl_atomic_t* __ptr) :
00051  * decrement  *__ptr by 1 and returns the new value
00052  * __stl_atomic_t _STLP_ATOMIC_EXCHANGE(volatile __stl_atomic_t* __target, __stl_atomic_t __val) :
00053  * assign __val to *__target and returns former *__target value
00054  * void* _STLP_ATOMIC_EXCHANGE_PTR(void* volatile* __target, void* __ptr) :
00055  * assign __ptr to *__target and returns former *__target value
00056  */
00057 
00058 #if defined (_STLP_THREADS)
00059 
00060 #  if defined (_STLP_SGI_THREADS)
00061 
00062 #    include <mutex.h>
00063 // Hack for SGI o32 compilers.
00064 #    if !defined(__add_and_fetch) && \
00065         (__mips < 3 || !(defined (_ABIN32) || defined(_ABI64)))
00066 #      define __add_and_fetch(__l,__v) add_then_test((unsigned long*)__l,__v)
00067 #      define __test_and_set(__l,__v)  test_and_set(__l,__v)
00068 #    endif /* o32 */
00069 
00070 #    if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
00071 #      define _STLP_ATOMIC_EXCHANGE(__p, __q) test_and_set(__p, __q)
00072 #    else
00073 #      define _STLP_ATOMIC_EXCHANGE(__p, __q) __test_and_set((unsigned long*)__p, (unsigned long)__q)
00074 #    endif
00075 
00076 #    define _STLP_ATOMIC_INCREMENT(__x) __add_and_fetch(__x, 1)
00077 #    define _STLP_ATOMIC_DECREMENT(__x) __add_and_fetch(__x, (size_t) -1)
00078 typedef long __stl_atomic_t;
00079 
00080 #  elif defined (_STLP_PTHREADS)
00081 
00082 #    include <pthread.h>
00083 #    if !defined (_STLP_USE_PTHREAD_SPINLOCK)
00084 #      if defined (PTHREAD_MUTEX_INITIALIZER) && !defined (_STLP_MUTEX_INITIALIZER) && defined (_REENTRANT)
00085 #        define _STLP_MUTEX_INITIALIZER = { PTHREAD_MUTEX_INITIALIZER }
00086 #      endif
00087 //HPUX variants have (on some platforms optional) non-standard "DCE" pthreads impl
00088 #      if defined (_DECTHREADS_) && (defined (_PTHREAD_USE_D4) || defined (__hpux)) && !defined (_CMA_SUPPRESS_EXTERNALS_)
00089 #        define _STLP_PTHREAD_ATTR_DEFAULT pthread_mutexattr_default
00090 #      else
00091 #        define _STLP_PTHREAD_ATTR_DEFAULT 0
00092 #      endif
00093 #    else
00094 #      if defined (__OpenBSD__)
00095 #        include <spinlock.h>
00096 #      endif
00097 #    endif
00098 
00099 #    if defined (__GNUC__) && defined (__i386__)
00100 #      if !defined (_STLP_ATOMIC_INCREMENT)
00101 inline long _STLP_atomic_increment_gcc_x86(long volatile* p) {
00102   long result;
00103   __asm__ __volatile__
00104     ("lock; xaddl  %1, %0;"
00105     :"=m" (*p), "=r" (result)
00106     :"m" (*p),  "1"  (1)
00107     :"cc");
00108   return result + 1;
00109 }
00110 #        define _STLP_ATOMIC_INCREMENT(__x) (_STLP_atomic_increment_gcc_x86((long volatile*)__x))
00111 #      endif
00112 
00113 #      if !defined (_STLP_ATOMIC_DECREMENT)
00114 inline long _STLP_atomic_decrement_gcc_x86(long volatile* p) {
00115   long result;
00116   __asm__ __volatile__
00117     ("lock; xaddl  %1, %0;"
00118     :"=m" (*p), "=r" (result)
00119     :"m" (*p),  "1"  (-1)
00120     :"cc");
00121   return result - 1;
00122 }
00123 #        define _STLP_ATOMIC_DECREMENT(__x) (_STLP_atomic_decrement_gcc_x86((long volatile*)__x))
00124 #      endif
00125 typedef long __stl_atomic_t;
00126 #    else
00127 typedef size_t __stl_atomic_t;
00128 #    endif /* if defined(__GNUC__) && defined(__i386__) */
00129 
00130 #  elif defined (_STLP_WIN32THREADS)
00131 
00132 #    if !defined (_STLP_ATOMIC_INCREMENT)
00133 #      if !defined (_STLP_NEW_PLATFORM_SDK)
00134 #        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__CONST_CAST(long*, __x))
00135 #        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__CONST_CAST(long*, __x))
00136 #        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__CONST_CAST(long*, __x), __y)
00137 #      else
00138 #        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__x)
00139 #        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__x)
00140 #        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__x, __y)
00141 #      endif
00142 #      define _STLP_ATOMIC_EXCHANGE_PTR(__x, __y)     STLPInterlockedExchangePointer(__x, __y)
00143 #    endif
00144 typedef long __stl_atomic_t;
00145 
00146 #  elif defined (__DECC) || defined (__DECCXX)
00147 
00148 #    include <machine/builtins.h>
00149 #    define _STLP_ATOMIC_EXCHANGE __ATOMIC_EXCH_LONG
00150 #    define _STLP_ATOMIC_INCREMENT(__x) __ATOMIC_ADD_LONG(__x, 1)
00151 #    define _STLP_ATOMIC_DECREMENT(__x) __ATOMIC_ADD_LONG(__x, -1)
00152 typedef long __stl_atomic_t;
00153 
00154 #  elif defined (_STLP_SPARC_SOLARIS_THREADS)
00155 
00156 typedef long __stl_atomic_t;
00157 #    include <stl/_sparc_atomic.h>
00158 
00159 #  elif defined (_STLP_UITHREADS)
00160 
00161 // this inclusion is potential hazard to bring up all sorts
00162 // of old-style headers. Let's assume vendor already know how
00163 // to deal with that.
00164 #    ifndef _STLP_INTERNAL_CTIME
00165 #      include <stl/_ctime.h>
00166 #    endif
00167 #    if defined (_STLP_USE_NAMESPACES) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
00168 using _STLP_VENDOR_CSTD::time_t;
00169 #    endif
00170 #    include <synch.h>
00171 #    ifndef _STLP_INTERNAL_CSTDIO
00172 #      include <stl/_cstdio.h>
00173 #    endif
00174 #    ifndef _STLP_INTERNAL_CWCHAR
00175 #      include <stl/_cwchar.h>
00176 #    endif
00177 typedef size_t __stl_atomic_t;
00178 
00179 #  elif defined (_STLP_BETHREADS)
00180 
00181 #    include <OS.h>
00182 #    include <cassert>
00183 #    include <stdio.h>
00184 #    define _STLP_MUTEX_INITIALIZER = { 0 }
00185 typedef size_t __stl_atomic_t;
00186 
00187 #  elif defined (_STLP_NWTHREADS)
00188 
00189 #    include <nwthread.h>
00190 #    include <nwsemaph.h>
00191 typedef size_t __stl_atomic_t;
00192 
00193 #  elif defined(_STLP_OS2THREADS)
00194 
00195 #    if defined (__GNUC__)
00196 #      define INCL_DOSSEMAPHORES
00197 #      include <os2.h>
00198 #    else
00199 // This section serves to replace os2.h for VisualAge C++
00200   typedef unsigned long ULONG;
00201 #      if !defined (__HEV__)  /* INCL_SEMAPHORE may also define HEV */
00202 #        define __HEV__
00203   typedef ULONG HEV;
00204   typedef HEV*  PHEV;
00205 #      endif
00206   typedef ULONG APIRET;
00207   typedef ULONG HMTX;
00208   typedef HMTX*  PHMTX;
00209   typedef const char*  PCSZ;
00210   typedef ULONG BOOL32;
00211   APIRET _System DosCreateMutexSem(PCSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
00212   APIRET _System DosRequestMutexSem(HMTX hmtx, ULONG ulTimeout);
00213   APIRET _System DosReleaseMutexSem(HMTX hmtx);
00214   APIRET _System DosCloseMutexSem(HMTX hmtx);
00215 #      define _STLP_MUTEX_INITIALIZER = { 0 }
00216 #    endif /* GNUC */
00217 typedef size_t __stl_atomic_t;
00218 
00219 #  else
00220 
00221 typedef size_t __stl_atomic_t;
00222 
00223 #  endif
00224 
00225 #else
00226 /* no threads */
00227 #  define _STLP_ATOMIC_INCREMENT(__x) ++(*__x)
00228 #  define _STLP_ATOMIC_DECREMENT(__x) --(*__x)
00229 /* We do not grant other atomic operations as they are useless if STLport do not have
00230  * to be thread safe
00231  */
00232 typedef size_t __stl_atomic_t;
00233 #endif
00234 
00235 #if !defined (_STLP_MUTEX_INITIALIZER)
00236 #  if defined(_STLP_ATOMIC_EXCHANGE)
00237 #    define _STLP_MUTEX_INITIALIZER = { 0 }
00238 #  elif defined(_STLP_UITHREADS)
00239 #    define _STLP_MUTEX_INITIALIZER = { DEFAULTMUTEX }
00240 #  else
00241 #    define _STLP_MUTEX_INITIALIZER
00242 #  endif
00243 #endif
00244 
00245 _STLP_BEGIN_NAMESPACE
00246 
00247 #if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK)
00248 // Helper struct.  This is a workaround for various compilers that don't
00249 // handle static variables in inline functions properly.
00250 template <int __inst>
00251 struct _STLP_mutex_spin {
00252   enum { __low_max = 30, __high_max = 1000 };
00253   // Low if we suspect uniprocessor, high for multiprocessor.
00254   static unsigned __max;
00255   static unsigned __last;
00256   static void _STLP_CALL _M_do_lock(volatile __stl_atomic_t* __lock);
00257   static void _STLP_CALL _S_nsec_sleep(int __log_nsec, unsigned int& __iteration);
00258 };
00259 #endif // !_STLP_USE_PTHREAD_SPINLOCK
00260 
00261 // Locking class.  Note that this class *does not have a constructor*.
00262 // It must be initialized either statically, with _STLP_MUTEX_INITIALIZER,
00263 // or dynamically, by explicitly calling the _M_initialize member function.
00264 // (This is similar to the ways that a pthreads mutex can be initialized.)
00265 // There are explicit member functions for acquiring and releasing the lock.
00266 
00267 // There is no constructor because static initialization is essential for
00268 // some uses, and only a class aggregate (see section 8.5.1 of the C++
00269 // standard) can be initialized that way.  That means we must have no
00270 // constructors, no base classes, no virtual functions, and no private or
00271 // protected members.
00272 
00273 // For non-static cases, clients should use  _STLP_mutex.
00274 
00275 struct _STLP_CLASS_DECLSPEC _STLP_mutex_base {
00276 #if defined (_STLP_ATOMIC_EXCHANGE) || defined (_STLP_SGI_THREADS)
00277   // It should be relatively easy to get this to work on any modern Unix.
00278   volatile __stl_atomic_t _M_lock;
00279 #endif
00280 
00281 #if defined (_STLP_THREADS)
00282 #  if defined (_STLP_ATOMIC_EXCHANGE)
00283   inline void _M_initialize() { _M_lock = 0; }
00284   inline void _M_destroy() {}
00285 
00286   void _M_acquire_lock() {
00287     _STLP_mutex_spin<0>::_M_do_lock(&_M_lock);
00288   }
00289 
00290   inline void _M_release_lock() {
00291     volatile __stl_atomic_t* __lock = &_M_lock;
00292 #    if defined(_STLP_SGI_THREADS) && defined(__GNUC__) && __mips >= 3
00293     asm("sync");
00294     *__lock = 0;
00295 #    elif defined(_STLP_SGI_THREADS) && __mips >= 3 && \
00296          (defined (_ABIN32) || defined(_ABI64))
00297     __lock_release(__lock);
00298 #    elif defined (_STLP_SPARC_SOLARIS_THREADS)
00299 #      if defined (__WORD64) || defined (__arch64__) || defined (__sparcv9) || defined (__sparcv8plus)
00300     asm("membar #StoreStore ; membar #LoadStore");
00301 #      else
00302     asm(" stbar ");
00303 #      endif
00304     *__lock = 0;
00305 #    else
00306     *__lock = 0;
00307     // This is not sufficient on many multiprocessors, since
00308     // writes to protected variables and the lock may be reordered.
00309 #    endif
00310   }
00311 #  elif defined (_STLP_PTHREADS)
00312 #    if defined (_STLP_USE_PTHREAD_SPINLOCK)
00313 #      if !defined (__OpenBSD__)
00314   pthread_spinlock_t _M_lock;
00315   inline void _M_initialize() { pthread_spin_init( &_M_lock, 0 ); }
00316   inline void _M_destroy() { pthread_spin_destroy( &_M_lock ); }
00317 
00318   // sorry, but no static initializer for pthread_spinlock_t;
00319   // this will not work for compilers that has problems with call
00320   // constructor of static object...
00321 
00322   // _STLP_mutex_base()
00323   //   { pthread_spin_init( &_M_lock, 0 ); }
00324 
00325   // ~_STLP_mutex_base()
00326   //   { pthread_spin_destroy( &_M_lock ); }
00327 
00328   inline void _M_acquire_lock() { pthread_spin_lock( &_M_lock ); }
00329   inline void _M_release_lock() { pthread_spin_unlock( &_M_lock ); }
00330 #      else // __OpenBSD__
00331   spinlock_t _M_lock;
00332   inline void _M_initialize() { _SPINLOCK_INIT( &_M_lock ); }
00333   inline void _M_destroy() { }
00334   inline void _M_acquire_lock() { _SPINLOCK( &_M_lock ); }
00335   inline void _M_release_lock() { _SPINUNLOCK( &_M_lock ); }
00336 #      endif // __OpenBSD__
00337 #    else // !_STLP_USE_PTHREAD_SPINLOCK
00338   pthread_mutex_t _M_lock;
00339   inline void _M_initialize()
00340   { pthread_mutex_init(&_M_lock,_STLP_PTHREAD_ATTR_DEFAULT); }
00341   inline void _M_destroy()
00342   { pthread_mutex_destroy(&_M_lock); }
00343   inline void _M_acquire_lock() {
00344 #      if defined ( __hpux ) && ! defined (PTHREAD_MUTEX_INITIALIZER)
00345     if (!_M_lock.field1)  _M_initialize();
00346 #      endif
00347     pthread_mutex_lock(&_M_lock);
00348   }
00349   inline void _M_release_lock() { pthread_mutex_unlock(&_M_lock); }
00350 #    endif // !_STLP_USE_PTHREAD_SPINLOCK
00351 
00352 #  elif defined (_STLP_UITHREADS)
00353   mutex_t _M_lock;
00354   inline void _M_initialize()
00355   { mutex_init(&_M_lock, 0, NULL); }
00356   inline void _M_destroy()
00357   { mutex_destroy(&_M_lock); }
00358   inline void _M_acquire_lock() { mutex_lock(&_M_lock); }
00359   inline void _M_release_lock() { mutex_unlock(&_M_lock); }
00360 
00361 #  elif defined (_STLP_OS2THREADS)
00362   HMTX _M_lock;
00363   inline void _M_initialize() { DosCreateMutexSem(NULL, &_M_lock, 0, false); }
00364   inline void _M_destroy() { DosCloseMutexSem(_M_lock); }
00365   inline void _M_acquire_lock() {
00366     if (!_M_lock) _M_initialize();
00367     DosRequestMutexSem(_M_lock, SEM_INDEFINITE_WAIT);
00368   }
00369   inline void _M_release_lock() { DosReleaseMutexSem(_M_lock); }
00370 #  elif defined (_STLP_BETHREADS)
00371   sem_id sem;
00372   inline void _M_initialize() {
00373     sem = create_sem(1, "STLPort");
00374     assert(sem > 0);
00375   }
00376   inline void _M_destroy() {
00377     int t = delete_sem(sem);
00378     assert(t == B_NO_ERROR);
00379   }
00380   inline void _M_acquire_lock();
00381   inline void _M_release_lock() {
00382     status_t t = release_sem(sem);
00383     assert(t == B_NO_ERROR);
00384   }
00385 #  elif defined (_STLP_NWTHREADS)
00386   LONG _M_lock;
00387   inline void _M_initialize()
00388   { _M_lock = OpenLocalSemaphore(1); }
00389   inline void _M_destroy()
00390   { CloseLocalSemaphore(_M_lock); }
00391   inline void _M_acquire_lock()
00392   { WaitOnLocalSemaphore(_M_lock); }
00393   inline void _M_release_lock() { SignalLocalSemaphore(_M_lock); }
00394 #  else      //*ty 11/24/2001 - added configuration check
00395 #    error "Unknown thread facility configuration"
00396 #  endif
00397 #else /* No threads */
00398   inline void _M_initialize() {}
00399   inline void _M_destroy() {}
00400   inline void _M_acquire_lock() {}
00401   inline void _M_release_lock() {}
00402 #endif // _STLP_PTHREADS
00403 };
00404 
00405 // Locking class.  The constructor initializes the lock, the destructor destroys it.
00406 // Well - behaving class, does not need static initializer
00407 
00408 class _STLP_CLASS_DECLSPEC _STLP_mutex : public _STLP_mutex_base {
00409   public:
00410     inline _STLP_mutex () { _M_initialize(); }
00411     inline ~_STLP_mutex () { _M_destroy(); }
00412   private:
00413     _STLP_mutex(const _STLP_mutex&);
00414     void operator=(const _STLP_mutex&);
00415 };
00416 
00417 // A locking class that uses _STLP_STATIC_MUTEX.  The constructor takes
00418 // a reference to an _STLP_STATIC_MUTEX, and acquires a lock.  The destructor
00419 // releases the lock.
00420 // It's not clear that this is exactly the right functionality.
00421 // It will probably change in the future.
00422 
00423 struct _STLP_CLASS_DECLSPEC _STLP_auto_lock {
00424   _STLP_auto_lock(_STLP_STATIC_MUTEX& __lock) : _M_lock(__lock)
00425   { _M_lock._M_acquire_lock(); }
00426   ~_STLP_auto_lock()
00427   { _M_lock._M_release_lock(); }
00428 
00429 private:
00430   _STLP_STATIC_MUTEX& _M_lock;
00431   void operator=(const _STLP_auto_lock&);
00432   _STLP_auto_lock(const _STLP_auto_lock&);
00433 };
00434 
00435 /*
00436  * Class _Refcount_Base provides a type, __stl_atomic_t, a data member,
00437  * _M_ref_count, and member functions _M_incr and _M_decr, which perform
00438  * atomic preincrement/predecrement.  The constructor initializes
00439  * _M_ref_count.
00440  */
00441 class _STLP_CLASS_DECLSPEC _Refcount_Base {
00442   // The data member _M_ref_count
00443 #if defined (__DMC__)
00444 public:
00445 #endif
00446   _STLP_VOLATILE __stl_atomic_t _M_ref_count;
00447 
00448 #if defined (_STLP_THREADS) && \
00449    (!defined (_STLP_ATOMIC_INCREMENT) || !defined (_STLP_ATOMIC_DECREMENT) || \
00450     defined (_STLP_WIN95_LIKE))
00451 #  define _STLP_USE_MUTEX
00452   _STLP_mutex _M_mutex;
00453 #endif
00454 
00455   public:
00456   // Constructor
00457   _Refcount_Base(__stl_atomic_t __n) : _M_ref_count(__n) {}
00458 #if defined (__BORLANDC__)
00459   ~_Refcount_Base(){};
00460 #endif
00461 
00462   // _M_incr and _M_decr
00463 #if defined (_STLP_THREADS)
00464 #  if !defined (_STLP_USE_MUTEX)
00465    __stl_atomic_t _M_incr() { return _STLP_ATOMIC_INCREMENT(&_M_ref_count); }
00466    __stl_atomic_t _M_decr() { return _STLP_ATOMIC_DECREMENT(&_M_ref_count); }
00467 #  else
00468 #    undef _STLP_USE_MUTEX
00469   __stl_atomic_t _M_incr() {
00470     _STLP_auto_lock l(_M_mutex);
00471     return ++_M_ref_count;
00472   }
00473   __stl_atomic_t _M_decr() {
00474     _STLP_auto_lock l(_M_mutex);
00475     return --_M_ref_count;
00476   }
00477 #  endif
00478 #else  /* No threads */
00479   __stl_atomic_t _M_incr() { return ++_M_ref_count; }
00480   __stl_atomic_t _M_decr() { return --_M_ref_count; }
00481 #endif
00482 };
00483 
00484 /* Atomic swap on __stl_atomic_t
00485  * This is guaranteed to behave as though it were atomic only if all
00486  * possibly concurrent updates use _Atomic_swap.
00487  * In some cases the operation is emulated with a lock.
00488  * Idem for _Atomic_swap_ptr
00489  */
00490 /* Helper struct to handle following cases:
00491  * - on platforms where sizeof(__stl_atomic_t) == sizeof(void*) atomic
00492  *   exchange can be done on pointers
00493  * - on platform without atomic operation swap is done in a critical section,
00494  *   portable but inefficient.
00495  */
00496 template <int __use_ptr_atomic_swap>
00497 class _Atomic_swap_struct {
00498 public:
00499 #if defined (_STLP_THREADS) && \
00500     !defined (_STLP_ATOMIC_EXCHANGE) && \
00501     (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
00502      defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
00503 #  define _STLP_USE_ATOMIC_SWAP_MUTEX
00504   static _STLP_STATIC_MUTEX _S_swap_lock;
00505 #endif
00506 
00507   static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
00508 #if defined (_STLP_THREADS)
00509 #  if defined (_STLP_ATOMIC_EXCHANGE)
00510   return _STLP_ATOMIC_EXCHANGE(__p, __q);
00511 #  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
00512   _S_swap_lock._M_acquire_lock();
00513   __stl_atomic_t __result = *__p;
00514   *__p = __q;
00515   _S_swap_lock._M_release_lock();
00516   return __result;
00517 #  else
00518 #    error Missing atomic swap implementation
00519 #  endif
00520 #else
00521   /* no threads */
00522   __stl_atomic_t __result = *__p;
00523   *__p = __q;
00524   return __result;
00525 #endif // _STLP_THREADS
00526   }
00527 
00528   static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
00529 #if defined (_STLP_THREADS)
00530 #  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
00531   return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
00532 #  elif defined (_STLP_ATOMIC_EXCHANGE)
00533   _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
00534   return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
00535                                                          __REINTERPRET_CAST(__stl_atomic_t, __q))
00536                             );
00537 #  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
00538   _S_swap_lock._M_acquire_lock();
00539   void *__result = *__p;
00540   *__p = __q;
00541   _S_swap_lock._M_release_lock();
00542   return __result;
00543 #  else
00544 #    error Missing pointer atomic swap implementation
00545 #  endif
00546 #else
00547   /* no thread */
00548   void *__result = *__p;
00549   *__p = __q;
00550   return __result;
00551 #endif
00552   }
00553 };
00554 
00555 _STLP_TEMPLATE_NULL
00556 class _Atomic_swap_struct<0> {
00557 public:
00558 #if defined (_STLP_THREADS) && \
00559     (!defined (_STLP_ATOMIC_EXCHANGE) || !defined (_STLP_ATOMIC_EXCHANGE_PTR)) && \
00560     (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
00561      defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
00562 #  define _STLP_USE_ATOMIC_SWAP_MUTEX
00563   static _STLP_STATIC_MUTEX _S_swap_lock;
00564 #endif
00565 
00566   static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
00567 #if defined (_STLP_THREADS)
00568 #  if defined (_STLP_ATOMIC_EXCHANGE)
00569   return _STLP_ATOMIC_EXCHANGE(__p, __q);
00570 #  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
00571   /* This should be portable, but performance is expected
00572    * to be quite awful.  This really needs platform specific
00573    * code.
00574    */
00575   _S_swap_lock._M_acquire_lock();
00576   __stl_atomic_t __result = *__p;
00577   *__p = __q;
00578   _S_swap_lock._M_release_lock();
00579   return __result;
00580 #  else
00581 #    error Missing atomic swap implementation
00582 #  endif
00583 #else
00584   /* no threads */
00585   __stl_atomic_t __result = *__p;
00586   *__p = __q;
00587   return __result;
00588 #endif // _STLP_THREADS
00589   }
00590 
00591   static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
00592 #if defined (_STLP_THREADS)
00593 #  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
00594   return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
00595 #  elif defined (_STLP_ATOMIC_EXCHANGE)
00596   _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
00597   return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
00598                                                          __REINTERPRET_CAST(__stl_atomic_t, __q))
00599                             );
00600 #  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
00601   _S_swap_lock._M_acquire_lock();
00602   void *__result = *__p;
00603   *__p = __q;
00604   _S_swap_lock._M_release_lock();
00605   return __result;
00606 #  else
00607 #    error Missing pointer atomic swap implementation
00608 #  endif
00609 #else
00610   /* no thread */
00611   void *__result = *__p;
00612   *__p = __q;
00613   return __result;
00614 #endif
00615   }
00616 };
00617 
00618 #if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
00619 #  pragma warning (push)
00620 #  pragma warning (disable : 4189) //__use_ptr_atomic_swap initialized but not used
00621 #endif
00622 
00623 inline __stl_atomic_t _STLP_CALL _Atomic_swap(_STLP_VOLATILE __stl_atomic_t * __p, __stl_atomic_t __q) {
00624   const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
00625   return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap(__p, __q);
00626 }
00627 
00628 inline void* _STLP_CALL _Atomic_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
00629   const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
00630   return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap_ptr(__p, __q);
00631 }
00632 
00633 #if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
00634 #  pragma warning (pop)
00635 #endif
00636 
00637 #if defined (_STLP_BETHREADS)
00638 template <int __inst>
00639 struct _STLP_beos_static_lock_data {
00640   static bool is_init;
00641   struct mutex_t : public _STLP_mutex {
00642     mutex_t()
00643     { _STLP_beos_static_lock_data<0>::is_init = true; }
00644     ~mutex_t()
00645     { _STLP_beos_static_lock_data<0>::is_init = false; }
00646   };
00647   static mutex_t mut;
00648 };
00649 
00650 template <int __inst>
00651 bool _STLP_beos_static_lock_data<__inst>::is_init = false;
00652 template <int __inst>
00653 typename _STLP_beos_static_lock_data<__inst>::mutex_t _STLP_beos_static_lock_data<__inst>::mut;
00654 
00655 inline void _STLP_mutex_base::_M_acquire_lock() {
00656   if (sem == 0) {
00657     // we need to initialise on demand here
00658     // to prevent race conditions use our global
00659     // mutex if it's available:
00660     if (_STLP_beos_static_lock_data<0>::is_init) {
00661       _STLP_auto_lock al(_STLP_beos_static_lock_data<0>::mut);
00662       if (sem == 0) _M_initialize();
00663     }
00664     else {
00665       // no lock available, we must still be
00666       // in startup code, THERE MUST BE ONE THREAD
00667       // ONLY active at this point.
00668       _M_initialize();
00669     }
00670   }
00671   status_t t;
00672   t = acquire_sem(sem);
00673   assert(t == B_NO_ERROR);
00674 }
00675 #endif
00676 
00677 _STLP_END_NAMESPACE
00678 
00679 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
00680 #  include <stl/_threads.c>
00681 #endif
00682 
00683 #endif /* _STLP_INTERNAL_THREADS_H */
00684 
00685 // Local Variables:
00686 // mode:C++
00687 // End:

Generated on Sun May 27 2012 04:29:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.