/* xtls.h internal header */ #ifndef _XTLS #define _XTLS #ifndef _SYSTEM_BUILD #pragma system_include #endif #include /* We need to turn off this warning */ #pragma diag_suppress = Pe076 _C_LIB_DECL typedef void (*_Tlsdtor_t)(void*); __INTRINSIC int _Atthreadexit(void (*)(void)); __INTRINSIC void _Destroytls(void); #define _IMPLICIT_EXTERN #if _COMPILER_TLS #define _XTLS_QUAL _TLS_QUAL #else /* _COMPILER_TLS */ #define _XTLS_QUAL #endif /* _COMPILER_TLS */ #if _GLOBAL_LOCALE #define _TLS_LOCK(lock) _Locksyslock(lock) #define _TLS_UNLOCK(lock) _Unlocksyslock(lock) #else /* _GLOBAL_LOCALE */ #define _TLS_LOCK(lock) (void)0 #define _TLS_UNLOCK(lock) (void)0 #endif /* _GLOBAL_LOCALE */ #define _XTLS_DTOR(name) _Tls_dtor_ ## name #define _XTLS_GET(name) _Tls_get_ ## name #define _XTLS_INIT(name) _Tls_init_ ## name #define _XTLS_KEY(name) _Tls_key_ ## name #define _XTLS_ONCE(name) _Tls_once_ ## name #define _XTLS_REG(name) _Tls_reg_ ## name #define _XTLS_SETUP(name) _Tls_setup_ ## name #define _XTLS_SETUPX(name) _Tls_setupx_ ## name #if _COMPILER_TLS #define _CLEANUP(x) _Atthreadexit(x) #else /* _COMPILER_TLS */ #define _CLEANUP(x) _Atexit(x) #endif /* _COMPILER_TLS */ #if !_MULTI_THREAD || _GLOBAL_LOCALE || _COMPILER_TLS #define _TLS_DATA_DECL(type, name) \ extern int (*_XTLS_SETUP(name))(void); \ extern type name #define _TLS_DEFINE_INIT(scope, type, name) \ scope _XTLS_QUAL type name #define _TLS_DEFINE_NO_INIT(scope, type, name) \ scope int (* _XTLS_SETUP(name))(void) = 0 #define _TLS_DATA_DEF(scope, type, name, init) \ _TLS_DEFINE_INIT(scope, type, name) = init; \ _TLS_DEFINE_NO_INIT(scope, type, name) #define _TLS_DEFINE_INIT_DT(scope, type, name) \ _TLS_DEFINE_INIT(scope, type, name) #define _TLS_DEFINE_NO_INIT_DT(scope, type, name, dtor) \ static _Once_t _XTLS_ONCE(name) = _ONCE_T_INIT; \ static void _XTLS_DTOR(name)(void) \ { \ dtor(&(name)); \ } \ static void _XTLS_REG(name)(void) \ { \ _CLEANUP(_XTLS_DTOR(name)); \ } \ static int _XTLS_SETUPX(name)(void) \ { \ _Once(&_XTLS_ONCE(name), _XTLS_REG(name)); \ return 1; \ } \ scope int (*_XTLS_SETUP(name))(void) = _XTLS_SETUPX(name) #define _TLS_DATA_DEF_DT(scope, type, name, init, dtor) \ _TLS_DEFINE_INIT_DT(scope, type, name) = init; \ _TLS_DEFINE_NO_INIT_DT(scope, type, name, dtor) #define _TLS_DATA_PTR(name) \ ((_XTLS_SETUP(name) && _XTLS_SETUP(name)()), (&(name))) #define _TLS_ARR_DECL(type, name) \ extern type name[] #define _XTLS_ARR_DEF_INIT(scope, type, name, elts) \ scope _XTLS_QUAL type name[elts] #define _TLS_ARR_DEF(scope, type, name, elts) \ _XTLS_ARR_DEF_INIT(scope, type, name, elts); \ _TLS_DEFINE_NO_INIT(scope, type, name) #define _TLS_ARR_DEF_DT(scope, type, name, elts, dtor) \ _XTLS_ARR_DEF_INIT(scope, type, name, elts); \ _TLS_DEFINE_NO_INIT_DT(scope, type, name, dtor) #define _TLS_ARR(name) \ ((_XTLS_SETUP(name) && _XTLS_SETUP(name)()), (&(name[0]))) #else /* !_MULTI_THREAD || _GLOBAL_LOCALE || _COMPILER_TLS */ #define _TLS_DATA_DECL(type, name) \ extern type *_XTLS_GET(name)(void) #define _TLS_DEFINE_INIT(scope, type, name) \ static const type _XTLS_INIT(name) #define _XTLS_DEFINE_NO_INIT(scope, type, name, elts, dtor) \ static _Once_t _XTLS_ONCE(name) = _ONCE_T_INIT; \ static _Tlskey_t _XTLS_KEY(name); \ static void _XTLS_SETUP(name)(void) \ { \ _Tlsalloc(&_XTLS_KEY(name), dtor); \ } \ scope type *_XTLS_GET(name)(void) \ { \ type *_Ptr; \ _Once(&_XTLS_ONCE(name), _XTLS_SETUP(name)); \ if ((_Ptr = (type *)_Tlsget(_XTLS_KEY(name))) != 0) \ ; \ else if ((_Ptr = (type *)calloc(elts, sizeof(type))) == 0) \ ; \ else if (_Tlsset(_XTLS_KEY(name), (void*)_Ptr) != 0) \ free((void*)_Ptr), _Ptr = 0; \ else \ *_Ptr = _XTLS_INIT(name); \ return _Ptr; \ } \ extern int _TLS_Dummy #define _TLS_DEFINE_NO_INIT(scope, type, name) \ _XTLS_DEFINE_NO_INIT(scope, type, name, 1, free) #define _TLS_DATA_DEF(scope, type, name, init) \ _TLS_DEFINE_INIT(scope, type, name) = init; \ _XTLS_DEFINE_NO_INIT(scope, type, name, 1, free) #define _TLS_DEFINE_INIT_DT(scope, type, name) \ _TLS_DEFINE_INIT(scope, type, name) #define _XTLS_DEFINE_NO_INIT_DT(scope, type, name, elts, dtor) \ static void _XTLS_DTOR(name)(void* _Ptr) \ { \ (dtor)(_Ptr); \ free(_Ptr); \ } \ _XTLS_DEFINE_NO_INIT(scope, type, name, elts, _XTLS_DTOR(name)) #define _TLS_DEFINE_NO_INIT_DT(scope, type, name, dtor) \ _XTLS_DEFINE_NO_INIT_DT(scope, type, name, 1, dtor) #define _TLS_DATA_DEF_DT(scope, type, name, init, dtor) \ _TLS_DEFINE_INIT_DT(scope, type, name) = init; \ _TLS_DEFINE_NO_INIT_DT(scope, type, name, dtor) #define _TLS_DATA_PTR(name) _XTLS_GET(name)() #define _TLS_ARR_DECL(type, name) \ _TLS_DATA_DECL(type, name) #define _TLS_ARR_DEF(scope, type, name, elts) \ _TLS_DEFINE_INIT(scope, type, name) = {0}; \ _XTLS_DEFINE_NO_INIT(scope, type, name, elts, free) #define _TLS_ARR_DEF_DT(scope, type, name, elts, dtor) \ _TLS_DEFINE_INIT(scope, type, name) = {0}; \ _XTLS_DEFINE_NO_INIT_DT(scope, type, name, elts, dtor) #define _TLS_ARR(name) \ _XTLS_GET(name)() #endif /* !_MULTI_THREAD || _GLOBAL_LOCALE || _COMPILER_TLS */ _END_C_LIB_DECL #endif /* _XTLS */ /* * Copyright (c) 1992-2002 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.12:0576 */