📄 _threads.h
字号:
# endif // __OpenBSD__# else // !_STLP_USE_PTHREAD_SPINLOCK pthread_mutex_t _M_lock; inline void _M_initialize() { pthread_mutex_init(&_M_lock,_STLP_PTHREAD_ATTR_DEFAULT); } inline void _M_destroy() { pthread_mutex_destroy(&_M_lock); } inline void _M_acquire_lock() {# if defined ( __hpux ) && ! defined (PTHREAD_MUTEX_INITIALIZER) if (!_M_lock.field1) _M_initialize();# endif pthread_mutex_lock(&_M_lock); } inline void _M_release_lock() { pthread_mutex_unlock(&_M_lock); }# endif // !_STLP_USE_PTHREAD_SPINLOCK# elif defined (_STLP_UITHREADS) mutex_t _M_lock; inline void _M_initialize() { mutex_init(&_M_lock, 0, NULL); } inline void _M_destroy() { mutex_destroy(&_M_lock); } inline void _M_acquire_lock() { mutex_lock(&_M_lock); } inline void _M_release_lock() { mutex_unlock(&_M_lock); }# elif defined (_STLP_OS2THREADS) HMTX _M_lock; inline void _M_initialize() { DosCreateMutexSem(NULL, &_M_lock, 0, false); } inline void _M_destroy() { DosCloseMutexSem(_M_lock); } inline void _M_acquire_lock() { if (!_M_lock) _M_initialize(); DosRequestMutexSem(_M_lock, SEM_INDEFINITE_WAIT); } inline void _M_release_lock() { DosReleaseMutexSem(_M_lock); }# elif defined (_STLP_BETHREADS) sem_id sem; inline void _M_initialize() { sem = create_sem(1, "STLPort"); assert(sem > 0); } inline void _M_destroy() { int t = delete_sem(sem); assert(t == B_NO_ERROR); } inline void _M_acquire_lock(); inline void _M_release_lock() { status_t t = release_sem(sem); assert(t == B_NO_ERROR); }# elif defined (_STLP_NWTHREADS) LONG _M_lock; inline void _M_initialize() { _M_lock = OpenLocalSemaphore(1); } inline void _M_destroy() { CloseLocalSemaphore(_M_lock); } inline void _M_acquire_lock() { WaitOnLocalSemaphore(_M_lock); } inline void _M_release_lock() { SignalLocalSemaphore(_M_lock); }# else //*ty 11/24/2001 - added configuration check# error "Unknown thread facility configuration"# endif#else /* No threads */ inline void _M_initialize() {} inline void _M_destroy() {} inline void _M_acquire_lock() {} inline void _M_release_lock() {}#endif // _STLP_PTHREADS};// Locking class. The constructor initializes the lock, the destructor destroys it.// Well - behaving class, does not need static initializerclass _STLP_CLASS_DECLSPEC _STLP_mutex : public _STLP_mutex_base { public: inline _STLP_mutex () { _M_initialize(); } inline ~_STLP_mutex () { _M_destroy(); } private: _STLP_mutex(const _STLP_mutex&); void operator=(const _STLP_mutex&);};// A locking class that uses _STLP_STATIC_MUTEX. The constructor takes// a reference to an _STLP_STATIC_MUTEX, and acquires a lock. The destructor// releases the lock.// It's not clear that this is exactly the right functionality.// It will probably change in the future.struct _STLP_CLASS_DECLSPEC _STLP_auto_lock { _STLP_auto_lock(_STLP_STATIC_MUTEX& __lock) : _M_lock(__lock) { _M_lock._M_acquire_lock(); } ~_STLP_auto_lock() { _M_lock._M_release_lock(); }private: _STLP_STATIC_MUTEX& _M_lock; void operator=(const _STLP_auto_lock&); _STLP_auto_lock(const _STLP_auto_lock&);};/* * Class _Refcount_Base provides a type, __stl_atomic_t, a data member, * _M_ref_count, and member functions _M_incr and _M_decr, which perform * atomic preincrement/predecrement. The constructor initializes * _M_ref_count. */class _STLP_CLASS_DECLSPEC _Refcount_Base { // The data member _M_ref_count#if defined (__DMC__)public:#endif _STLP_VOLATILE __stl_atomic_t _M_ref_count;#if defined (_STLP_THREADS) && \ (!defined (_STLP_ATOMIC_INCREMENT) || !defined (_STLP_ATOMIC_DECREMENT) || \ (defined (_STLP_WIN32_VERSION) && (_STLP_WIN32_VERSION <= 0x0400)))# define _STLP_USE_MUTEX _STLP_mutex _M_mutex;#endif public: // Constructor _Refcount_Base(__stl_atomic_t __n) : _M_ref_count(__n) {} // _M_incr and _M_decr#if defined (_STLP_THREADS)# if !defined (_STLP_USE_MUTEX) __stl_atomic_t _M_incr() { return _STLP_ATOMIC_INCREMENT(&_M_ref_count); } __stl_atomic_t _M_decr() { return _STLP_ATOMIC_DECREMENT(&_M_ref_count); }# else# undef _STLP_USE_MUTEX __stl_atomic_t _M_incr() { _STLP_auto_lock l(_M_mutex); return ++_M_ref_count; } __stl_atomic_t _M_decr() { _STLP_auto_lock l(_M_mutex); return --_M_ref_count; }# endif#else /* No threads */ __stl_atomic_t _M_incr() { return ++_M_ref_count; } __stl_atomic_t _M_decr() { return --_M_ref_count; }#endif};/* Atomic swap on __stl_atomic_t * This is guaranteed to behave as though it were atomic only if all * possibly concurrent updates use _Atomic_swap. * In some cases the operation is emulated with a lock. * Idem for _Atomic_swap_ptr *//* Helper struct to handle following cases: * - on platforms where sizeof(__stl_atomic_t) == sizeof(void*) atomic * exchange can be done on pointers * - on platform without atomic operation swap is done in a critical section, * portable but inefficient. */template <int __use_ptr_atomic_swap>class _Atomic_swap_struct {public:#if defined (_STLP_THREADS) && \ !defined (_STLP_ATOMIC_EXCHANGE) && \ (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \ defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))# define _STLP_USE_ATOMIC_SWAP_MUTEX static _STLP_STATIC_MUTEX _S_swap_lock;#endif static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {#if defined (_STLP_THREADS)# if defined (_STLP_ATOMIC_EXCHANGE) return _STLP_ATOMIC_EXCHANGE(__p, __q);# elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX) _S_swap_lock._M_acquire_lock(); __stl_atomic_t __result = *__p; *__p = __q; _S_swap_lock._M_release_lock(); return __result;# else# error Missing atomic swap implementation# endif#else /* no threads */ __stl_atomic_t __result = *__p; *__p = __q; return __result;#endif // _STLP_THREADS } static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {#if defined (_STLP_THREADS)# if defined (_STLP_ATOMIC_EXCHANGE_PTR) return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);# elif defined (_STLP_ATOMIC_EXCHANGE) _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*)) return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p), __REINTERPRET_CAST(__stl_atomic_t, __q)) );# elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX) _S_swap_lock._M_acquire_lock(); void *__result = *__p; *__p = __q; _S_swap_lock._M_release_lock(); return __result;# else# error Missing pointer atomic swap implementation# endif#else /* no thread */ void *__result = *__p; *__p = __q; return __result;#endif }};_STLP_TEMPLATE_NULLclass _Atomic_swap_struct<0> {public:#if defined (_STLP_THREADS) && \ (!defined (_STLP_ATOMIC_EXCHANGE) || !defined (_STLP_ATOMIC_EXCHANGE_PTR)) && \ (defined (_STLP_PTHREADS) || defined (_STLP_UITHREADS) || defined (_STLP_OS2THREADS) || \ defined (_STLP_USE_PTHREAD_SPINLOCK) || defined (_STLP_NWTHREADS))# define _STLP_USE_ATOMIC_SWAP_MUTEX static _STLP_STATIC_MUTEX _S_swap_lock;#endif static __stl_atomic_t _S_swap(_STLP_VOLATILE __stl_atomic_t* __p, __stl_atomic_t __q) {#if defined (_STLP_THREADS)# if defined (_STLP_ATOMIC_EXCHANGE) return _STLP_ATOMIC_EXCHANGE(__p, __q);# elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX) /* This should be portable, but performance is expected * to be quite awful. This really needs platform specific * code. */ _S_swap_lock._M_acquire_lock(); __stl_atomic_t __result = *__p; *__p = __q; _S_swap_lock._M_release_lock(); return __result;# else# error Missing atomic swap implementation# endif#else /* no threads */ __stl_atomic_t __result = *__p; *__p = __q; return __result;#endif // _STLP_THREADS } static void* _S_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) {#if defined (_STLP_THREADS)# if defined (_STLP_ATOMIC_EXCHANGE_PTR) return _STLP_ATOMIC_EXCHANGE_PTR(__p, __q);# elif defined (_STLP_ATOMIC_EXCHANGE) _STLP_STATIC_ASSERT(sizeof(__stl_atomic_t) == sizeof(void*)) return __REINTERPRET_CAST(void*, _STLP_ATOMIC_EXCHANGE(__REINTERPRET_CAST(volatile __stl_atomic_t*, __p), __REINTERPRET_CAST(__stl_atomic_t, __q)) );# elif defined (_STLP_USE_ATOMIC_SWAP_MUTEX) _S_swap_lock._M_acquire_lock(); void *__result = *__p; *__p = __q; _S_swap_lock._M_release_lock(); return __result;# else# error Missing pointer atomic swap implementation# endif#else /* no thread */ void *__result = *__p; *__p = __q; return __result;#endif }};#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)# pragma warning (push)# pragma warning (disable : 4189) //__use_ptr_atomic_swap initialized but not used#endifinline __stl_atomic_t _STLP_CALL _Atomic_swap(_STLP_VOLATILE __stl_atomic_t * __p, __stl_atomic_t __q) { const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*); return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap(__p, __q);}inline void* _STLP_CALL _Atomic_swap_ptr(void* _STLP_VOLATILE* __p, void* __q) { const int __use_ptr_atomic_swap = sizeof(__stl_atomic_t) == sizeof(void*); return _Atomic_swap_struct<__use_ptr_atomic_swap>::_S_swap_ptr(__p, __q);}#if defined (_STLP_MSVC) && (_STLP_MSVC == 1300)# pragma warning (pop)#endif#if defined (_STLP_BETHREADS)template <int __inst>struct _STLP_beos_static_lock_data { static bool is_init; struct mutex_t : public _STLP_mutex { mutex_t() { _STLP_beos_static_lock_data<0>::is_init = true; } ~mutex_t() { _STLP_beos_static_lock_data<0>::is_init = false; } }; static mutex_t mut;};template <int __inst>bool _STLP_beos_static_lock_data<__inst>::is_init = false;template <int __inst>typename _STLP_beos_static_lock_data<__inst>::mutex_t _STLP_beos_static_lock_data<__inst>::mut;inline void _STLP_mutex_base::_M_acquire_lock() { if (sem == 0) { // we need to initialise on demand here // to prevent race conditions use our global // mutex if it's available: if (_STLP_beos_static_lock_data<0>::is_init) { _STLP_auto_lock al(_STLP_beos_static_lock_data<0>::mut); if (sem == 0) _M_initialize(); } else { // no lock available, we must still be // in startup code, THERE MUST BE ONE THREAD // ONLY active at this point. _M_initialize(); } } status_t t; t = acquire_sem(sem); assert(t == B_NO_ERROR);}#endif_STLP_END_NAMESPACE#if !defined (_STLP_LINK_TIME_INSTANTIATION)# include <stl/_threads.c>#endif#endif /* _STLP_INTERNAL_THREADS_H */// Local Variables:// mode:C++// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -