111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1997-1999
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Silicon Graphics Computer Systems, Inc.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1999
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Boris Fomitchev
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This material is provided "as is", with absolutely no warranty expressed
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * or implied. Any use is at your own risk.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to use or copy this software for any purpose is hereby granted
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * without fee, provided the above notices are retained on all copies.
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to modify the code and to distribute modified code is granted,
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * provided the above notices are retained, and a notice that the code was
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * modified is included with the above copyright notice.
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// WARNING: This is an internal header file, included by other C++
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// standard library headers.  You should not attempt to use this header
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// file directly.
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_THREADS_H
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _STLP_INTERNAL_THREADS_H
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Supported threading models are native SGI, pthreads, uithreads
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// (similar to pthreads, but based on an earlier draft of the Posix
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// threads standard), and Win32 threads.  Uithread support by Jochen
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Schlick, 1999, and Solaris threads generalized to them.
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_CSTDDEF
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_cstddef.h>
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_CSTDLIB
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_cstdlib.h>
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// On SUN and Mac OS X gcc, zero-initialization works just fine...
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (__sun) || (defined (__GNUC__) && defined(__APPLE__))
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_MUTEX_INITIALIZER
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* This header defines the following atomic operation that platform should
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * try to support as much as possible. Atomic operation are exposed as macro
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * in order to easily test for their existance. They are:
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * __stl_atomic_t _STLP_ATOMIC_INCREMENT(volatile __stl_atomic_t* __ptr) :
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * increment *__ptr by 1 and returns the new value
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * __stl_atomic_t _STLP_ATOMIC_DECREMENT(volatile __stl_atomic_t* __ptr) :
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * decrement  *__ptr by 1 and returns the new value
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * __stl_atomic_t _STLP_ATOMIC_EXCHANGE(volatile __stl_atomic_t* __target, __stl_atomic_t __val) :
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * assign __val to *__target and returns former *__target value
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * void* _STLP_ATOMIC_EXCHANGE_PTR(void* volatile* __target, void* __ptr) :
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * assign __ptr to *__target and returns former *__target value
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_SGI_THREADS)
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <mutex.h>
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Hack for SGI o32 compilers.
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if !defined(__add_and_fetch) && \
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        (__mips < 3 || !(defined (_ABIN32) || defined(_ABI64)))
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define __add_and_fetch(__l,__v) add_then_test((unsigned long*)__l,__v)
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define __test_and_set(__l,__v)  test_and_set(__l,__v)
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif /* o32 */
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define _STLP_ATOMIC_EXCHANGE(__p, __q) test_and_set(__p, __q)
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define _STLP_ATOMIC_EXCHANGE(__p, __q) __test_and_set((unsigned long*)__p, (unsigned long)__q)
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_ATOMIC_INCREMENT(__x) __add_and_fetch(__x, 1)
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_ATOMIC_DECREMENT(__x) __add_and_fetch(__x, (size_t) -1)
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef long __stl_atomic_t;
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_PTHREADS)
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <pthread.h>
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if !defined (_STLP_USE_PTHREAD_SPINLOCK)
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if defined (PTHREAD_MUTEX_INITIALIZER) && !defined (_STLP_MUTEX_INITIALIZER) && defined (_REENTRANT)
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_MUTEX_INITIALIZER = { PTHREAD_MUTEX_INITIALIZER }
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//HPUX variants have (on some platforms optional) non-standard "DCE" pthreads impl
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if defined (_DECTHREADS_) && (defined (_PTHREAD_USE_D4) || defined (__hpux)) && !defined (_CMA_SUPPRESS_EXTERNALS_)
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_PTHREAD_ATTR_DEFAULT pthread_mutexattr_default
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      else
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_PTHREAD_ATTR_DEFAULT 0
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if defined (__OpenBSD__)
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        include <spinlock.h>
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if defined (__GNUC__) && defined (__i386__)
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if !defined (_STLP_ATOMIC_INCREMENT)
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline long _STLP_atomic_increment_gcc_x86(long volatile* p) {
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  long result;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __asm__ __volatile__
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ("lock; xaddl  %1, %0;"
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"=m" (*p), "=r" (result)
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"m" (*p),  "1"  (1)
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"cc");
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return result + 1;
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_INCREMENT(__x) (_STLP_atomic_increment_gcc_x86((long volatile*)__x))
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if !defined (_STLP_ATOMIC_DECREMENT)
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline long _STLP_atomic_decrement_gcc_x86(long volatile* p) {
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  long result;
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __asm__ __volatile__
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ("lock; xaddl  %1, %0;"
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"=m" (*p), "=r" (result)
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"m" (*p),  "1"  (-1)
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    :"cc");
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return result - 1;
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_DECREMENT(__x) (_STLP_atomic_decrement_gcc_x86((long volatile*)__x))
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef long __stl_atomic_t;
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif /* if defined(__GNUC__) && defined(__i386__) */
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_WIN32THREADS)
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if !defined (_STLP_ATOMIC_INCREMENT)
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if !defined (_STLP_NEW_PLATFORM_SDK)
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__CONST_CAST(long*, __x))
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__CONST_CAST(long*, __x))
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__CONST_CAST(long*, __x), __y)
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      else
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_INCREMENT(__x)           InterlockedIncrement(__x)
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_DECREMENT(__x)           InterlockedDecrement(__x)
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define _STLP_ATOMIC_EXCHANGE(__x, __y)       InterlockedExchange(__x, __y)
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define _STLP_ATOMIC_EXCHANGE_PTR(__x, __y)     STLPInterlockedExchangePointer(__x, __y)
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef long __stl_atomic_t;
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (__DECC) || defined (__DECCXX)
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <machine/builtins.h>
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_ATOMIC_EXCHANGE __ATOMIC_EXCH_LONG
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_ATOMIC_INCREMENT(__x) __ATOMIC_ADD_LONG(__x, 1)
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_ATOMIC_DECREMENT(__x) __ATOMIC_ADD_LONG(__x, -1)
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef long __stl_atomic_t;
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_SPARC_SOLARIS_THREADS)
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef long __stl_atomic_t;
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <stl/_sparc_atomic.h>
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_UITHREADS)
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// this inclusion is potential hazard to bring up all sorts
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// of old-style headers. Let's assume vendor already know how
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// to deal with that.
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    ifndef _STLP_INTERNAL_CTIME
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      include <stl/_ctime.h>
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if defined (_STLP_USE_NAMESPACES) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertusing _STLP_VENDOR_CSTD::time_t;
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <synch.h>
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    ifndef _STLP_INTERNAL_CSTDIO
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      include <stl/_cstdio.h>
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    ifndef _STLP_INTERNAL_CWCHAR
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      include <stl/_cwchar.h>
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_BETHREADS)
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <OS.h>
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <cassert>
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <stdio.h>
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_MUTEX_INITIALIZER = { 0 }
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_NWTHREADS)
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <nwthread.h>
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    include <nwsemaph.h>
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined(_STLP_OS2THREADS)
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if defined (__GNUC__)
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define INCL_DOSSEMAPHORES
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      include <os2.h>
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This section serves to replace os2.h for VisualAge C++
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef unsigned long ULONG;
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if !defined (__HEV__)  /* INCL_SEMAPHORE may also define HEV */
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#        define __HEV__
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ULONG HEV;
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef HEV*  PHEV;
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ULONG APIRET;
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ULONG HMTX;
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef HMTX*  PHMTX;
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef const char*  PCSZ;
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  typedef ULONG BOOL32;
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  APIRET _System DosCreateMutexSem(PCSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  APIRET _System DosRequestMutexSem(HMTX hmtx, ULONG ulTimeout);
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  APIRET _System DosReleaseMutexSem(HMTX hmtx);
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  APIRET _System DosCloseMutexSem(HMTX hmtx);
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      define _STLP_MUTEX_INITIALIZER = { 0 }
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif /* GNUC */
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* no threads */
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_ATOMIC_INCREMENT(__x) ++(*__x)
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_ATOMIC_DECREMENT(__x) --(*__x)
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* We do not grant other atomic operations as they are useless if STLport do not have
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * to be thread safe
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef size_t __stl_atomic_t;
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_MUTEX_INITIALIZER)
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined(_STLP_ATOMIC_EXCHANGE)
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_MUTEX_INITIALIZER = { 0 }
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined(_STLP_UITHREADS)
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_MUTEX_INITIALIZER = { DEFAULTMUTEX }
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define _STLP_MUTEX_INITIALIZER
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_BEGIN_NAMESPACE
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS) && !defined (_STLP_USE_PTHREAD_SPINLOCK)
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper struct.  This is a workaround for various compilers that don't
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// handle static variables in inline functions properly.
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int __inst>
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _STLP_mutex_spin {
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  enum { __low_max = 30, __high_max = 1000 };
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Low if we suspect uniprocessor, high for multiprocessor.
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static unsigned __max;
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static unsigned __last;
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void _STLP_CALL _M_do_lock(volatile __stl_atomic_t* __lock);
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void _STLP_CALL _S_nsec_sleep(int __log_nsec, unsigned int& __iteration);
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // !_STLP_USE_PTHREAD_SPINLOCK
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Locking class.  Note that this class *does not have a constructor*.
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It must be initialized either statically, with _STLP_MUTEX_INITIALIZER,
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// or dynamically, by explicitly calling the _M_initialize member function.
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// (This is similar to the ways that a pthreads mutex can be initialized.)
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// There are explicit member functions for acquiring and releasing the lock.
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// There is no constructor because static initialization is essential for
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// some uses, and only a class aggregate (see section 8.5.1 of the C++
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// standard) can be initialized that way.  That means we must have no
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// constructors, no base classes, no virtual functions, and no private or
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// protected members.
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// For non-static cases, clients should use  _STLP_mutex.
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _STLP_CLASS_DECLSPEC _STLP_mutex_base {
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_ATOMIC_EXCHANGE) || defined (_STLP_SGI_THREADS)
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // It should be relatively easy to get this to work on any modern Unix.
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  volatile __stl_atomic_t _M_lock;
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_ATOMIC_EXCHANGE)
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() { _M_lock = 0; }
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() {}
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void _M_acquire_lock() {
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_mutex_spin<0>::_M_do_lock(&_M_lock);
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() {
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    volatile __stl_atomic_t* __lock = &_M_lock;
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if defined(_STLP_SGI_THREADS) && defined(__GNUC__) && __mips >= 3
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    asm("sync");
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    *__lock = 0;
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    elif defined(_STLP_SGI_THREADS) && __mips >= 3 && \
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert         (defined (_ABIN32) || defined(_ABI64))
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    __lock_release(__lock);
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    elif defined (_STLP_SPARC_SOLARIS_THREADS)
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if defined (__WORD64) || defined (__arch64__) || defined (__sparcv9) || defined (__sparcv8plus)
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    asm("membar #StoreStore ; membar #LoadStore");
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      else
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    asm(" stbar ");
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    *__lock = 0;
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    *__lock = 0;
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // This is not sufficient on many multiprocessors, since
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // writes to protected variables and the lock may be reordered.
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_PTHREADS)
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    if defined (_STLP_USE_PTHREAD_SPINLOCK)
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if !defined (__OpenBSD__)
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pthread_spinlock_t _M_lock;
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() { pthread_spin_init( &_M_lock, 0 ); }
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() { pthread_spin_destroy( &_M_lock ); }
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // sorry, but no static initializer for pthread_spinlock_t;
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // this will not work for compilers that has problems with call
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // constructor of static object...
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // _STLP_mutex_base()
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //   { pthread_spin_init( &_M_lock, 0 ); }
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // ~_STLP_mutex_base()
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //   { pthread_spin_destroy( &_M_lock ); }
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() { pthread_spin_lock( &_M_lock ); }
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { pthread_spin_unlock( &_M_lock ); }
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      else // __OpenBSD__
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  spinlock_t _M_lock;
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() { _SPINLOCK_INIT( &_M_lock ); }
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() { }
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() { _SPINLOCK( &_M_lock ); }
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { _SPINUNLOCK( &_M_lock ); }
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif // __OpenBSD__
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    else // !_STLP_USE_PTHREAD_SPINLOCK
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pthread_mutex_t _M_lock;
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize()
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { pthread_mutex_init(&_M_lock,_STLP_PTHREAD_ATTR_DEFAULT); }
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy()
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { pthread_mutex_destroy(&_M_lock); }
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() {
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      if defined ( __hpux ) && ! defined (PTHREAD_MUTEX_INITIALIZER)
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (!_M_lock.field1)  _M_initialize();
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#      endif
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    pthread_mutex_lock(&_M_lock);
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { pthread_mutex_unlock(&_M_lock); }
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    endif // !_STLP_USE_PTHREAD_SPINLOCK
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_UITHREADS)
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  mutex_t _M_lock;
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize()
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { mutex_init(&_M_lock, 0, NULL); }
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy()
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { mutex_destroy(&_M_lock); }
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() { mutex_lock(&_M_lock); }
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { mutex_unlock(&_M_lock); }
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_OS2THREADS)
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  HMTX _M_lock;
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() { DosCreateMutexSem(NULL, &_M_lock, 0, false); }
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() { DosCloseMutexSem(_M_lock); }
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() {
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (!_M_lock) _M_initialize();
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    DosRequestMutexSem(_M_lock, SEM_INDEFINITE_WAIT);
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { DosReleaseMutexSem(_M_lock); }
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_BETHREADS)
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  sem_id sem;
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() {
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    sem = create_sem(1, "STLPort");
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    assert(sem > 0);
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() {
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int t = delete_sem(sem);
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    assert(t == B_NO_ERROR);
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock();
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() {
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    status_t t = release_sem(sem);
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    assert(t == B_NO_ERROR);
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_NWTHREADS)
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  LONG _M_lock;
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize()
38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { _M_lock = OpenLocalSemaphore(1); }
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy()
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { CloseLocalSemaphore(_M_lock); }
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock()
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { WaitOnLocalSemaphore(_M_lock); }
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() { SignalLocalSemaphore(_M_lock); }
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else      //*ty 11/24/2001 - added configuration check
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error "Unknown thread facility configuration"
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else /* No threads */
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_initialize() {}
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_destroy() {}
40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_acquire_lock() {}
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void _M_release_lock() {}
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _STLP_PTHREADS
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Locking class.  The constructor initializes the lock, the destructor destroys it.
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Well - behaving class, does not need static initializer
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _STLP_CLASS_DECLSPEC _STLP_mutex : public _STLP_mutex_base {
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline _STLP_mutex () { _M_initialize(); }
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline ~_STLP_mutex () { _M_destroy(); }
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  private:
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_mutex(const _STLP_mutex&);
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void operator=(const _STLP_mutex&);
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// A locking class that uses _STLP_STATIC_MUTEX.  The constructor takes
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a reference to an _STLP_STATIC_MUTEX, and acquires a lock.  The destructor
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// releases the lock.
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It's not clear that this is exactly the right functionality.
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It will probably change in the future.
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _STLP_CLASS_DECLSPEC _STLP_auto_lock {
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_auto_lock(_STLP_STATIC_MUTEX& __lock) : _M_lock(__lock)
42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { _M_lock._M_acquire_lock(); }
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~_STLP_auto_lock()
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { _M_lock._M_release_lock(); }
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate:
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_STATIC_MUTEX& _M_lock;
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void operator=(const _STLP_auto_lock&);
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_auto_lock(const _STLP_auto_lock&);
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Class _Refcount_Base provides a type, __stl_atomic_t, a data member,
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _M_ref_count, and member functions _M_incr and _M_decr, which perform
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * atomic preincrement/predecrement.  The constructor initializes
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _M_ref_count.
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _STLP_CLASS_DECLSPEC _Refcount_Base {
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // The data member _M_ref_count
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (__DMC__)
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_VOLATILE __stl_atomic_t _M_ref_count;
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS) && \
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   (!defined (_STLP_ATOMIC_INCREMENT) || !defined (_STLP_ATOMIC_DECREMENT) || \
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    defined (_STLP_WIN95_LIKE))
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_USE_MUTEX
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_mutex _M_mutex;
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Constructor
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _Refcount_Base(__stl_atomic_t __n) : _M_ref_count(__n) {}
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (__BORLANDC__)
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~_Refcount_Base(){};
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // _M_incr and _M_decr
46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if !defined (_STLP_USE_MUTEX)
46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   __stl_atomic_t _M_incr() { return _STLP_ATOMIC_INCREMENT(&_M_ref_count); }
46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   __stl_atomic_t _M_decr() { return _STLP_ATOMIC_DECREMENT(&_M_ref_count); }
46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    undef _STLP_USE_MUTEX
46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t _M_incr() {
47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_auto_lock l(_M_mutex);
47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return ++_M_ref_count;
47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t _M_decr() {
47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    _STLP_auto_lock l(_M_mutex);
47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return --_M_ref_count;
47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else  /* No threads */
47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t _M_incr() { return ++_M_ref_count; }
48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t _M_decr() { return --_M_ref_count; }
48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Atomic swap on __stl_atomic_t
48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is guaranteed to behave as though it were atomic only if all
48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * possibly concurrent updates use _Atomic_swap.
48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * In some cases the operation is emulated with a lock.
48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Idem for _Atomic_swap_ptr
48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Helper struct to handle following cases:
49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * - on platforms where sizeof(__stl_atomic_t) == sizeof(void*) atomic
49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   exchange can be done on pointers
49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * - on platform without atomic operation swap is done in a critical section,
49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   portable but inefficient.
49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
49611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int __use_ptr_atomic_swap>
49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _Atomic_swap_struct {
49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS) && \
50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    !defined (_STLP_ATOMIC_EXCHANGE) && \
50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_USE_ATOMIC_SWAP_MUTEX
50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static _STLP_STATIC_MUTEX _S_swap_lock;
50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_ATOMIC_EXCHANGE)
51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _STLP_ATOMIC_EXCHANGE(__p, __q);
51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_acquire_lock();
51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t __result = *__p;
51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_release_lock();
51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error Missing atomic swap implementation
51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* no threads */
52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t __result = *__p;
52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _STLP_THREADS
52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_ATOMIC_EXCHANGE)
53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                         __REINTERPRET_CAST(__stl_atomic_t, __q))
53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                            );
53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_acquire_lock();
53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void *__result = *__p;
54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_release_lock();
54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error Missing pointer atomic swap implementation
54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* no thread */
54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void *__result = *__p;
54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TEMPLATE_NULL
55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _Atomic_swap_struct<0> {
55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS) && \
55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (!defined (_STLP_ATOMIC_EXCHANGE) || !defined (_STLP_ATOMIC_EXCHANGE_PTR)) && \
56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \
56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert     defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))
56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define _STLP_USE_ATOMIC_SWAP_MUTEX
56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static _STLP_STATIC_MUTEX _S_swap_lock;
56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {
56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_ATOMIC_EXCHANGE)
56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _STLP_ATOMIC_EXCHANGE(__p, __q);
57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* This should be portable, but performance is expected
57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * to be quite awful.  This really needs platform specific
57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * code.
57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_acquire_lock();
57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t __result = *__p;
57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_release_lock();
57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error Missing atomic swap implementation
58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* no threads */
58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __stl_atomic_t __result = *__p;
58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _STLP_THREADS
58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_THREADS)
59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined (_STLP_ATOMIC_EXCHANGE_PTR)
59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);
59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_ATOMIC_EXCHANGE)
59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*))
59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p),
59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                         __REINTERPRET_CAST(__stl_atomic_t, __q))
59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                            );
60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX)
60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_acquire_lock();
60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void *__result = *__p;
60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  _S_swap_lock._M_release_lock();
60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error Missing pointer atomic swap implementation
60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /* no thread */
61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void *__result = *__p;
61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *__p = __q;
61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return __result;
61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  pragma warning (push)
62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  pragma warning (disable : 4189) //__use_ptr_atomic_swap initialized but not used
62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline __stl_atomic_t _STLP_CALL _Atomic_swap(_STLP_VOLATILE __stl_atomic_t * __p, __stl_atomic_t __q) {
62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap(__p, __q);
62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline void* _STLP_CALL _Atomic_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {
62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*);
63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap_ptr(__p, __q);
63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)
63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  pragma warning (pop)
63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_BETHREADS)
63811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int __inst>
63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _STLP_beos_static_lock_data {
64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static bool is_init;
64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct mutex_t : public _STLP_mutex {
64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    mutex_t()
64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { _STLP_beos_static_lock_data<0>::is_init = true; }
64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ~mutex_t()
64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { _STLP_beos_static_lock_data<0>::is_init = false; }
64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static mutex_t mut;
64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int __inst>
65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool _STLP_beos_static_lock_data<__inst>::is_init = false;
65211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int __inst>
65311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypename _STLP_beos_static_lock_data<__inst>::mutex_t _STLP_beos_static_lock_data<__inst>::mut;
65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertinline void _STLP_mutex_base::_M_acquire_lock() {
65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (sem == 0) {
65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // we need to initialise on demand here
65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // to prevent race conditions use our global
65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // mutex if it's available:
66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (_STLP_beos_static_lock_data<0>::is_init) {
66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _STLP_auto_lock al(_STLP_beos_static_lock_data<0>::mut);
66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (sem == 0) _M_initialize();
66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    else {
66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // no lock available, we must still be
66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // in startup code, THERE MUST BE ONE THREAD
66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // ONLY active at this point.
66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_initialize();
66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  status_t t;
67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  t = acquire_sem(sem);
67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  assert(t == B_NO_ERROR);
67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_END_NAMESPACE
67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined (_STLP_LINK_TIME_INSTANTIATION)
68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  include <stl/_threads.c>
68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_INTERNAL_THREADS_H */
68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Local Variables:
68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// mode:C++
68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// End:
688