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