19720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/*
29720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Copyright (c) 1997-1999
39720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Silicon Graphics Computer Systems, Inc.
49720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *
59720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Copyright (c) 1999
69720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Boris Fomitchev
79720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *
89720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * This material is provided "as is", with absolutely no warranty expressed
99720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * or implied. Any use is at your own risk.
109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *
119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Permission to use or copy this software for any purpose is hereby granted
129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * without fee, provided the above notices are retained on all copies.
139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Permission to modify the code and to distribute modified code is granted,
149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * provided the above notices are retained, and a notice that the code was
159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * modified is included with the above copyright notice.
169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *
179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// WARNING: This is an internal header file, included by other C++
209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// standard library headers.  You should not attempt to use this header
219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// file directly.
229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_INTERNAL_THREADS_H
259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#define _STLP_INTERNAL_THREADS_H
269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Supported threading models are native SGI, pthreads, uithreads
289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// (similar to pthreads, but based on an earlier draft of the Posix
299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// threads standard), and Win32 threads.  Uithread support by Jochen
309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Schlick, 1999, and Solaris threads generalized to them.
319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_INTERNAL_CSTDDEF
339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  include <stl/_cstddef.h>
349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_INTERNAL_CSTDLIB
379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  include <stl/_cstdlib.h>
389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// On SUN and Mac OS X gcc, zero-initialization works just fine...
419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (__sun) || (defined (__GNUC__) && defined(__APPLE__))
429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_MUTEX_INITIALIZER
439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* This header defines the following atomic operation that platform should
469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * try to support as much as possible. Atomic operation are exposed as macro
479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * in order to easily test for their existance. They are:
489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * __stl_atomic_t _STLP_ATOMIC_INCREMENT(volatile __stl_atomic_t* __ptr) :
499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * increment *__ptr by 1 and returns the new value
509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * __stl_atomic_t _STLP_ATOMIC_DECREMENT(volatile __stl_atomic_t* __ptr) :
519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * decrement  *__ptr by 1 and returns the new value
529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * __stl_atomic_t _STLP_ATOMIC_EXCHANGE(volatile __stl_atomic_t* __target, __stl_atomic_t __val) :
539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * assign __val to *__target and returns former *__target value
549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * void* _STLP_ATOMIC_EXCHANGE_PTR(void* volatile* __target, void* __ptr) :
559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * assign __ptr to *__target and returns former *__target value
569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_SGI_THREADS)
619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <mutex.h>
639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Hack for SGI o32 compilers.
649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if !defined(__add_and_fetch) && \
659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block        (__mips < 3 || !(defined (_ABIN32) || defined(_ABI64)))
669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define __add_and_fetch(__l,__v) add_then_test((unsigned long*)__l,__v)
679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define __test_and_set(__l,__v)  test_and_set(__l,__v)
689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif /* o32 */
699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define _STLP_ATOMIC_EXCHANGE(__p, __q) test_and_set(__p, __q)
729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    else
739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define _STLP_ATOMIC_EXCHANGE(__p, __q) __test_and_set((unsigned long*)__p, (unsigned long)__q)
749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif
759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_ATOMIC_INCREMENT(__x) __add_and_fetch(__x, 1)
779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_ATOMIC_DECREMENT(__x) __add_and_fetch(__x, (size_t) -1)
78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef long __stl_atomic_t;
799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_PTHREADS)
819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <pthread.h>
839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if !defined (_STLP_USE_PTHREAD_SPINLOCK)
849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if defined (PTHREAD_MUTEX_INITIALIZER) && !defined (_STLP_MUTEX_INITIALIZER) && defined (_REENTRANT)
859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_MUTEX_INITIALIZER = { PTHREAD_MUTEX_INITIALIZER }
869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//HPUX variants have (on some platforms optional) non-standard "DCE" pthreads impl
889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if defined (_DECTHREADS_) && (defined (_PTHREAD_USE_D4) || defined (__hpux)) && !defined (_CMA_SUPPRESS_EXTERNALS_)
899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_PTHREAD_ATTR_DEFAULT pthread_mutexattr_default
909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      else
919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_PTHREAD_ATTR_DEFAULT 0
929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    else
949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if defined (__OpenBSD__)
959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        include <spinlock.h>
969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    endif
989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if defined (__GNUC__) && defined (__i386__)
1009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if !defined (_STLP_ATOMIC_INCREMENT)
1019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockinline long _STLP_atomic_increment_gcc_x86(long volatile* p) {
1029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  long result;
1039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __asm__ __volatile__
1049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    ("lock; xaddl  %1, %0;"
1059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"=m" (*p), "=r" (result)
1069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"m" (*p),  "1"  (1)
1079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"cc");
1089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return result + 1;
1099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block}
1109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_INCREMENT(__x) (_STLP_atomic_increment_gcc_x86((long volatile*)__x))
1119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
1129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if !defined (_STLP_ATOMIC_DECREMENT)
1149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockinline long _STLP_atomic_decrement_gcc_x86(long volatile* p) {
1159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  long result;
1169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __asm__ __volatile__
1179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    ("lock; xaddl  %1, %0;"
1189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"=m" (*p), "=r" (result)
1199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"m" (*p),  "1"  (-1)
1209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    :"cc");
1219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return result - 1;
1229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block}
1239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_DECREMENT(__x) (_STLP_atomic_decrement_gcc_x86((long volatile*)__x))
1249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef long __stl_atomic_t;
126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    else
127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
1289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif /* if defined(__GNUC__) && defined(__i386__) */
1299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_WIN32THREADS)
1319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if !defined (_STLP_ATOMIC_INCREMENT)
1339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if !defined (_STLP_NEW_PLATFORM_SDK)
1349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__CONST_CAST(long*, __x))
1359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__CONST_CAST(long*, __x))
1369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__CONST_CAST(long*, __x), __y)
1379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      else
1389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__x)
1399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__x)
1409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__x, __y)
1419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
1429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define _STLP_ATOMIC_EXCHANGE_PTR(__x, __y)     STLPInterlockedExchangePointer(__x, __y)
1439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif
144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef long __stl_atomic_t;
1459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (__DECC) || defined (__DECCXX)
1479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <machine/builtins.h>
1499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_ATOMIC_EXCHANGE __ATOMIC_EXCH_LONG
1509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_ATOMIC_INCREMENT(__x) __ATOMIC_ADD_LONG(__x, 1)
1519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_ATOMIC_DECREMENT(__x) __ATOMIC_ADD_LONG(__x, -1)
152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef long __stl_atomic_t;
1539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  elif defined (_STLP_SPARC_SOLARIS_THREADS)
1559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef long __stl_atomic_t;
1579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <stl/_sparc_atomic.h>
1589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_UITHREADS)
1609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// this inclusion is potential hazard to bring up all sorts
1629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// of old-style headers. Let's assume vendor already know how
1639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// to deal with that.
1649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    ifndef _STLP_INTERNAL_CTIME
1659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      include <stl/_ctime.h>
1669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif
1679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if defined (_STLP_USE_NAMESPACES) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
1689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing _STLP_VENDOR_CSTD::time_t;
1699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif
1709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <synch.h>
171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    ifndef _STLP_INTERNAL_CSTDIO
172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#      include <stl/_cstdio.h>
173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    endif
174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    ifndef _STLP_INTERNAL_CWCHAR
175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#      include <stl/_cwchar.h>
176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#    endif
177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
1789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_BETHREADS)
1809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <OS.h>
1829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <cassert>
1839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <stdio.h>
1849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_MUTEX_INITIALIZER = { 0 }
185e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
1869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_NWTHREADS)
1889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <nwthread.h>
1909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    include <nwsemaph.h>
191e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
1929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined(_STLP_OS2THREADS)
1949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
1959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if defined (__GNUC__)
1969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define INCL_DOSSEMAPHORES
1979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      include <os2.h>
1989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    else
1999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This section serves to replace os2.h for VisualAge C++
2009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef unsigned long ULONG;
2019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if !defined (__HEV__)  /* INCL_SEMAPHORE may also define HEV */
2029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#        define __HEV__
2039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef ULONG HEV;
2049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef HEV*  PHEV;
2059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
2069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef ULONG APIRET;
2079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef ULONG HMTX;
2089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef HMTX*  PHMTX;
2099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef const char*  PCSZ;
2109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  typedef ULONG BOOL32;
2119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  APIRET _System DosCreateMutexSem(PCSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
2129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  APIRET _System DosRequestMutexSem(HMTX hmtx, ULONG ulTimeout);
2139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  APIRET _System DosReleaseMutexSem(HMTX hmtx);
2149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  APIRET _System DosCloseMutexSem(HMTX hmtx);
2159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      define _STLP_MUTEX_INITIALIZER = { 0 }
2169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif /* GNUC */
217e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
218e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
219e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#  else
220e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
221e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
2229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
2249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else
2269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* no threads */
2279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_ATOMIC_INCREMENT(__x) ++(*__x)
2289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_ATOMIC_DECREMENT(__x) --(*__x)
2299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* We do not grant other atomic operations as they are useless if STLport do not have
2309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * to be thread safe
2319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
232e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttypedef size_t __stl_atomic_t;
2339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
2349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if !defined (_STLP_MUTEX_INITIALIZER)
2369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined(_STLP_ATOMIC_EXCHANGE)
2379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_MUTEX_INITIALIZER = { 0 }
2389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined(_STLP_UITHREADS)
2399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_MUTEX_INITIALIZER = { DEFAULTMUTEX }
2409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
2419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    define _STLP_MUTEX_INITIALIZER
2429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
2439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
2449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_BEGIN_NAMESPACE
2469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK)
2489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper struct.  This is a workaround for various compilers that don't
2499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// handle static variables in inline functions properly.
2509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <int __inst>
2519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockstruct _STLP_mutex_spin {
2529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  enum { __low_max = 30, __high_max = 1000 };
2539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // Low if we suspect uniprocessor, high for multiprocessor.
2549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static unsigned __max;
2559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static unsigned __last;
2569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static void _STLP_CALL _M_do_lock(volatile __stl_atomic_t* __lock);
257e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  static void _STLP_CALL _S_nsec_sleep(int __log_nsec, unsigned int& __iteration);
2589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
2599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif // !_STLP_USE_PTHREAD_SPINLOCK
2609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Locking class.  Note that this class *does not have a constructor*.
2629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It must be initialized either statically, with _STLP_MUTEX_INITIALIZER,
2639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// or dynamically, by explicitly calling the _M_initialize member function.
2649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// (This is similar to the ways that a pthreads mutex can be initialized.)
2659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// There are explicit member functions for acquiring and releasing the lock.
2669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// There is no constructor because static initialization is essential for
2689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// some uses, and only a class aggregate (see section 8.5.1 of the C++
2699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// standard) can be initialized that way.  That means we must have no
2709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// constructors, no base classes, no virtual functions, and no private or
2719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// protected members.
2729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// For non-static cases, clients should use  _STLP_mutex.
2749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockstruct _STLP_CLASS_DECLSPEC _STLP_mutex_base {
2769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_ATOMIC_EXCHANGE) || defined (_STLP_SGI_THREADS)
2779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // It should be relatively easy to get this to work on any modern Unix.
2789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  volatile __stl_atomic_t _M_lock;
2799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
2809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
2829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_ATOMIC_EXCHANGE)
2839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() { _M_lock = 0; }
2849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() {}
2859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void _M_acquire_lock() {
2879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    _STLP_mutex_spin<0>::_M_do_lock(&_M_lock);
2889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
2899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
2909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() {
2919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    volatile __stl_atomic_t* __lock = &_M_lock;
2929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if defined(_STLP_SGI_THREADS) && defined(__GNUC__) && __mips >= 3
2939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    asm("sync");
2949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    *__lock = 0;
2959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    elif defined(_STLP_SGI_THREADS) && __mips >= 3 && \
2969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block         (defined (_ABIN32) || defined(_ABI64))
2979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    __lock_release(__lock);
2989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    elif defined (_STLP_SPARC_SOLARIS_THREADS)
2999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if defined (__WORD64) || defined (__arch64__) || defined (__sparcv9) || defined (__sparcv8plus)
3009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    asm("membar #StoreStore ; membar #LoadStore");
3019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      else
3029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    asm(" stbar ");
3039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
3049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    *__lock = 0;
3059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    else
3069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    *__lock = 0;
3079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    // This is not sufficient on many multiprocessors, since
3089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    // writes to protected variables and the lock may be reordered.
3099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif
3109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_PTHREADS)
3129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    if defined (_STLP_USE_PTHREAD_SPINLOCK)
3139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if !defined (__OpenBSD__)
3149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  pthread_spinlock_t _M_lock;
3159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() { pthread_spin_init( &_M_lock, 0 ); }
3169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() { pthread_spin_destroy( &_M_lock ); }
3179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // sorry, but no static initializer for pthread_spinlock_t;
3199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // this will not work for compilers that has problems with call
3209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // constructor of static object...
3219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // _STLP_mutex_base()
3239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  //   { pthread_spin_init( &_M_lock, 0 ); }
3249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // ~_STLP_mutex_base()
3269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  //   { pthread_spin_destroy( &_M_lock ); }
3279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() { pthread_spin_lock( &_M_lock ); }
3299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { pthread_spin_unlock( &_M_lock ); }
3309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      else // __OpenBSD__
3319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  spinlock_t _M_lock;
3329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() { _SPINLOCK_INIT( &_M_lock ); }
3339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() { }
3349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() { _SPINLOCK( &_M_lock ); }
3359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { _SPINUNLOCK( &_M_lock ); }
3369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif // __OpenBSD__
3379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    else // !_STLP_USE_PTHREAD_SPINLOCK
3389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  pthread_mutex_t _M_lock;
3399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize()
3409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { pthread_mutex_init(&_M_lock,_STLP_PTHREAD_ATTR_DEFAULT); }
3419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy()
3429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { pthread_mutex_destroy(&_M_lock); }
3439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() {
3449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      if defined ( __hpux ) && ! defined (PTHREAD_MUTEX_INITIALIZER)
3459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    if (!_M_lock.field1)  _M_initialize();
3469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#      endif
3479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    pthread_mutex_lock(&_M_lock);
3489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { pthread_mutex_unlock(&_M_lock); }
3509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    endif // !_STLP_USE_PTHREAD_SPINLOCK
3519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_UITHREADS)
3539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  mutex_t _M_lock;
3549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize()
3559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { mutex_init(&_M_lock, 0, NULL); }
3569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy()
3579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { mutex_destroy(&_M_lock); }
3589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() { mutex_lock(&_M_lock); }
3599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { mutex_unlock(&_M_lock); }
3609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
3619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_OS2THREADS)
3629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  HMTX _M_lock;
3639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() { DosCreateMutexSem(NULL, &_M_lock, 0, false); }
3649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() { DosCloseMutexSem(_M_lock); }
3659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() {
3669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    if (!_M_lock) _M_initialize();
3679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    DosRequestMutexSem(_M_lock, SEM_INDEFINITE_WAIT);
3689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { DosReleaseMutexSem(_M_lock); }
3709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_BETHREADS)
3719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  sem_id sem;
3729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() {
3739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    sem = create_sem(1, "STLPort");
3749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    assert(sem > 0);
3759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() {
3779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    int t = delete_sem(sem);
3789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    assert(t == B_NO_ERROR);
3799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock();
3819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() {
3829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    status_t t = release_sem(sem);
3839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    assert(t == B_NO_ERROR);
3849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
3859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_NWTHREADS)
3869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  LONG _M_lock;
3879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize()
3889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { _M_lock = OpenLocalSemaphore(1); }
3899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy()
3909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { CloseLocalSemaphore(_M_lock); }
3919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock()
3929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { WaitOnLocalSemaphore(_M_lock); }
3939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() { SignalLocalSemaphore(_M_lock); }
3949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else      //*ty 11/24/2001 - added configuration check
3959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    error "Unknown thread facility configuration"
3969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
3979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else /* No threads */
3989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_initialize() {}
3999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_destroy() {}
4009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_acquire_lock() {}
4019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  inline void _M_release_lock() {}
4029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif // _STLP_PTHREADS
4039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
4049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Locking class.  The constructor initializes the lock, the destructor destroys it.
4069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Well - behaving class, does not need static initializer
4079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockclass _STLP_CLASS_DECLSPEC _STLP_mutex : public _STLP_mutex_base {
4099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  public:
4109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    inline _STLP_mutex () { _M_initialize(); }
4119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    inline ~_STLP_mutex () { _M_destroy(); }
4129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  private:
4139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    _STLP_mutex(const _STLP_mutex&);
4149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    void operator=(const _STLP_mutex&);
4159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
4169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// A locking class that uses _STLP_STATIC_MUTEX.  The constructor takes
4189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// a reference to an _STLP_STATIC_MUTEX, and acquires a lock.  The destructor
4199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// releases the lock.
4209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It's not clear that this is exactly the right functionality.
4219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It will probably change in the future.
4229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockstruct _STLP_CLASS_DECLSPEC _STLP_auto_lock {
4249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_auto_lock(_STLP_STATIC_MUTEX& __lock) : _M_lock(__lock)
4259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { _M_lock._M_acquire_lock(); }
4269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  ~_STLP_auto_lock()
4279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  { _M_lock._M_release_lock(); }
4289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockprivate:
4309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_STATIC_MUTEX& _M_lock;
4319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void operator=(const _STLP_auto_lock&);
4329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_auto_lock(const _STLP_auto_lock&);
4339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
4349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/*
4369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Class _Refcount_Base provides a type, __stl_atomic_t, a data member,
4379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * _M_ref_count, and member functions _M_incr and _M_decr, which perform
4389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * atomic preincrement/predecrement.  The constructor initializes
4399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * _M_ref_count.
4409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
4419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockclass _STLP_CLASS_DECLSPEC _Refcount_Base {
4429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // The data member _M_ref_count
4439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (__DMC__)
4449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockpublic:
4459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
4469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_VOLATILE __stl_atomic_t _M_ref_count;
4479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS) && \
4499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   (!defined (_STLP_ATOMIC_INCREMENT) || !defined (_STLP_ATOMIC_DECREMENT) || \
450e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    defined (_STLP_WIN95_LIKE))
4519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_USE_MUTEX
4529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_mutex _M_mutex;
4539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
4549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  public:
4569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // Constructor
4579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _Refcount_Base(__stl_atomic_t __n) : _M_ref_count(__n) {}
458e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__BORLANDC__)
459e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  ~_Refcount_Base(){};
460e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif
4619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  // _M_incr and _M_decr
4639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
4649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if !defined (_STLP_USE_MUTEX)
4659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   __stl_atomic_t _M_incr() { return _STLP_ATOMIC_INCREMENT(&_M_ref_count); }
4669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   __stl_atomic_t _M_decr() { return _STLP_ATOMIC_DECREMENT(&_M_ref_count); }
4679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
4689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    undef _STLP_USE_MUTEX
4699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t _M_incr() {
4709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    _STLP_auto_lock l(_M_mutex);
4719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    return ++_M_ref_count;
4729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
4739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t _M_decr() {
4749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    _STLP_auto_lock l(_M_mutex);
4759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    return --_M_ref_count;
4769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
4779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
4789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else  /* No threads */
4799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t _M_incr() { return ++_M_ref_count; }
4809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t _M_decr() { return --_M_ref_count; }
4819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
4829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
4839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
4849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* Atomic swap on __stl_atomic_t
4859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * This is guaranteed to behave as though it were atomic only if all
4869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * possibly concurrent updates use _Atomic_swap.
4879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * In some cases the operation is emulated with a lock.
4889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Idem for _Atomic_swap_ptr
4899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
4909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* Helper struct to handle following cases:
4919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * - on platforms where sizeof(__stl_atomic_t) == sizeof(void*) atomic
4929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *   exchange can be done on pointers
4939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * - on platform without atomic operation swap is done in a critical section,
4949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *   portable but inefficient.
4959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */
4969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <int __use_ptr_atomic_swap>
4979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockclass _Atomic_swap_struct {
4989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockpublic:
4999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS) && \
5009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    !defined (_STLP_ATOMIC_EXCHANGE) && \
5019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
5029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block     defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
5039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_USE_ATOMIC_SWAP_MUTEX
5049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static _STLP_STATIC_MUTEX _S_swap_lock;
5059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
5069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
5079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
5089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
5099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_ATOMIC_EXCHANGE)
5109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _STLP_ATOMIC_EXCHANGE(__p, __q);
5119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
5129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_acquire_lock();
5139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t __result = *__p;
5149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_release_lock();
5169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
5189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    error Missing atomic swap implementation
5199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
5209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else
5219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  /* no threads */
5229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t __result = *__p;
5239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif // _STLP_THREADS
5269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
5279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
5289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
5299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
5309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
5319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
5329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_ATOMIC_EXCHANGE)
5339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
5349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
5359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block                                                         __REINTERPRET_CAST(__stl_atomic_t, __q))
5369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block                            );
5379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
5389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_acquire_lock();
5399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void *__result = *__p;
5409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_release_lock();
5429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
5449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    error Missing pointer atomic swap implementation
5459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
5469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else
5479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  /* no thread */
5489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void *__result = *__p;
5499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
5529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
5539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
5549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
5559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_TEMPLATE_NULL
5569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockclass _Atomic_swap_struct<0> {
5579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockpublic:
5589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS) && \
5599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    (!defined (_STLP_ATOMIC_EXCHANGE) || !defined (_STLP_ATOMIC_EXCHANGE_PTR)) && \
5609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
5619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block     defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
5629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  define _STLP_USE_ATOMIC_SWAP_MUTEX
5639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static _STLP_STATIC_MUTEX _S_swap_lock;
5649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
5659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
5669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
5679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
5689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_ATOMIC_EXCHANGE)
5699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _STLP_ATOMIC_EXCHANGE(__p, __q);
5709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
5719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  /* This should be portable, but performance is expected
5729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   * to be quite awful.  This really needs platform specific
5739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   * code.
5749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block   */
5759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_acquire_lock();
5769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t __result = *__p;
5779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_release_lock();
5799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
5819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    error Missing atomic swap implementation
5829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
5839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else
5849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  /* no threads */
5859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  __stl_atomic_t __result = *__p;
5869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
5879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
5889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif // _STLP_THREADS
5899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
5909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
5919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
5929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_THREADS)
5939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
5949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
5959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_ATOMIC_EXCHANGE)
5969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
5979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
5989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block                                                         __REINTERPRET_CAST(__stl_atomic_t, __q))
5999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block                            );
6009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
6019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_acquire_lock();
6029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void *__result = *__p;
6039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
6049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  _S_swap_lock._M_release_lock();
6059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
6069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  else
6079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#    error Missing pointer atomic swap implementation
6089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  endif
6099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#else
6109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  /* no thread */
6119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  void *__result = *__p;
6129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  *__p = __q;
6139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return __result;
6149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
6159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
6169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
6179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
6199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  pragma warning (push)
6209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  pragma warning (disable : 4189) //__use_ptr_atomic_swap initialized but not used
6219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
6229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockinline __stl_atomic_t _STLP_CALL _Atomic_swap(_STLP_VOLATILE __stl_atomic_t * __p, __stl_atomic_t __q) {
6249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
6259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap(__p, __q);
6269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block}
6279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockinline void* _STLP_CALL _Atomic_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
6299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
6309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap_ptr(__p, __q);
6319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block}
6329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
6349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  pragma warning (pop)
6359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
6369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if defined (_STLP_BETHREADS)
6389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <int __inst>
6399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockstruct _STLP_beos_static_lock_data {
6409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static bool is_init;
6419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  struct mutex_t : public _STLP_mutex {
6429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    mutex_t()
6439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    { _STLP_beos_static_lock_data<0>::is_init = true; }
6449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    ~mutex_t()
6459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    { _STLP_beos_static_lock_data<0>::is_init = false; }
6469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  };
6479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  static mutex_t mut;
6489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block};
6499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <int __inst>
6519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool _STLP_beos_static_lock_data<__inst>::is_init = false;
6529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <int __inst>
6539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktypename _STLP_beos_static_lock_data<__inst>::mutex_t _STLP_beos_static_lock_data<__inst>::mut;
6549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockinline void _STLP_mutex_base::_M_acquire_lock() {
6569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  if (sem == 0) {
6579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    // we need to initialise on demand here
6589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    // to prevent race conditions use our global
6599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    // mutex if it's available:
6609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    if (_STLP_beos_static_lock_data<0>::is_init) {
6619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      _STLP_auto_lock al(_STLP_beos_static_lock_data<0>::mut);
6629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      if (sem == 0) _M_initialize();
6639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    }
6649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    else {
6659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      // no lock available, we must still be
6669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      // in startup code, THERE MUST BE ONE THREAD
6679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      // ONLY active at this point.
6689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block      _M_initialize();
6699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block    }
6709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  }
6719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  status_t t;
6729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  t = acquire_sem(sem);
6739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block  assert(t == B_NO_ERROR);
6749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block}
6759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
6769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_END_NAMESPACE
6789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#if !defined (_STLP_LINK_TIME_INSTANTIATION)
6809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#  include <stl/_threads.c>
6819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif
6829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif /* _STLP_INTERNAL_THREADS_H */
6849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block
6859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Local Variables:
6869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// mode:C++
6879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// End:
688