diff --git a/stl/inc/__msvc_threads_core.hpp b/stl/inc/__msvc_threads_core.hpp index 27cc751b442..94cc7346131 100644 --- a/stl/inc/__msvc_threads_core.hpp +++ b/stl/inc/__msvc_threads_core.hpp @@ -33,50 +33,38 @@ struct _Stl_critical_section { }; struct _Mtx_internal_imp_t { -#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) -#ifdef _WIN64 - static constexpr size_t _Critical_section_size = 16; -#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv - static constexpr size_t _Critical_section_size = 8; -#endif // ^^^ !defined(_WIN64) ^^^ -#else // ^^^ Windows private STL / public STL vvv -#ifdef _WIN64 +#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) // for Windows-internal code + static constexpr size_t _Critical_section_size = 2 * sizeof(void*); +#elif defined(_WIN64) // ordinary 64-bit code static constexpr size_t _Critical_section_size = 64; -#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv +#else // vvv ordinary 32-bit code vvv static constexpr size_t _Critical_section_size = 36; -#endif // ^^^ !defined(_WIN64) ^^^ -#endif // ^^^ public STL ^^^ - - static constexpr size_t _Critical_section_align = alignof(void*); +#endif // ^^^ ordinary 32-bit code ^^^ int _Type{}; union { _Stl_critical_section _Critical_section{}; - _STD _Aligned_storage_t<_Critical_section_size, _Critical_section_align> _Cs_storage; + _STD _Aligned_storage_t<_Critical_section_size, alignof(void*)> _Cs_storage; }; long _Thread_id{}; int _Count{}; }; -// Size and alignment for _Cnd_internal_imp_t +using _Mtx_t = _Mtx_internal_imp_t*; + +struct _Cnd_internal_imp_t { #if defined(_CRT_WINDOWS) // for Windows-internal code -_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 2 * sizeof(void*); + static constexpr size_t _Cnd_internal_imp_size = 2 * sizeof(void*); #elif defined(_WIN64) // ordinary 64-bit code -_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 72; + static constexpr size_t _Cnd_internal_imp_size = 72; #else // vvv ordinary 32-bit code vvv -_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 40; + static constexpr size_t _Cnd_internal_imp_size = 40; #endif // ^^^ ordinary 32-bit code ^^^ -_INLINE_VAR constexpr size_t _Cnd_internal_imp_alignment = alignof(void*); - -using _Mtx_t = _Mtx_internal_imp_t*; + _STD _Aligned_storage_t<_Cnd_internal_imp_size, alignof(void*)> _Cv_storage; +}; -#ifdef _M_CEE // avoid warning LNK4248: unresolved typeref token for '_Cnd_internal_imp_t'; image may not run -using _Cnd_t = void*; -#else // ^^^ defined(_M_CEE) / !defined(_M_CEE) vvv -struct _Cnd_internal_imp_t; using _Cnd_t = _Cnd_internal_imp_t*; -#endif // ^^^ !defined(_M_CEE) ^^^ } // extern "C" #pragma pop_macro("new") diff --git a/stl/inc/condition_variable b/stl/inc/condition_variable index 9878204252f..93f84507535 100644 --- a/stl/inc/condition_variable +++ b/stl/inc/condition_variable @@ -220,10 +220,10 @@ public: private: shared_ptr _Myptr; - _Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> _Cnd_storage; + _Cnd_internal_imp_t _Cnd_storage; - _NODISCARD _Cnd_t _Mycnd() noexcept { // get pointer to _Cnd_internal_imp_t inside _Cnd_storage - return reinterpret_cast<_Cnd_t>(&_Cnd_storage); + _NODISCARD _Cnd_t _Mycnd() noexcept { + return &_Cnd_storage; } template diff --git a/stl/inc/mutex b/stl/inc/mutex index 42544d2204b..49291830219 100644 --- a/stl/inc/mutex +++ b/stl/inc/mutex @@ -637,10 +637,10 @@ public: } private: - _Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> _Cnd_storage; + _Cnd_internal_imp_t _Cnd_storage; - _Cnd_t _Mycnd() noexcept { // get pointer to _Cnd_internal_imp_t inside _Cnd_storage - return reinterpret_cast<_Cnd_t>(&_Cnd_storage); + _Cnd_t _Mycnd() noexcept { + return &_Cnd_storage; } }; diff --git a/stl/src/cond.cpp b/stl/src/cond.cpp index 38ae9c20a9c..4cb255335fa 100644 --- a/stl/src/cond.cpp +++ b/stl/src/cond.cpp @@ -14,7 +14,7 @@ extern "C" { _CRTIMP2_PURE void __cdecl _Cnd_init_in_situ(const _Cnd_t cond) noexcept { // initialize condition variable in situ - new (cond->_get_cv()) Concurrency::details::stl_condition_variable_win7; + new (Concurrency::details::_Get_cond_var(cond)) Concurrency::details::stl_condition_variable_win7; } _CRTIMP2_PURE void __cdecl _Cnd_destroy_in_situ(_Cnd_t) noexcept {} // destroy condition variable in situ @@ -54,7 +54,7 @@ _CRTIMP2_PURE void __cdecl _Mtx_reset_owner(_Mtx_t mtx) noexcept { // set owner _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) noexcept { // wait until signaled const auto cs = &mtx->_Critical_section; _Mtx_clear_owner(mtx); - cond->_get_cv()->wait(cs); + Concurrency::details::_Get_cond_var(cond)->wait(cs); _Mtx_reset_owner(mtx); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } @@ -66,13 +66,14 @@ _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait( const auto cs = &mtx->_Critical_section; if (target == nullptr) { // no target time specified, wait on mutex _Mtx_clear_owner(mtx); - cond->_get_cv()->wait(cs); + Concurrency::details::_Get_cond_var(cond)->wait(cs); _Mtx_reset_owner(mtx); } else { // target time specified, wait for it _timespec64 now; _Timespec64_get_sys(&now); _Mtx_clear_owner(mtx); - if (!cond->_get_cv()->wait_for(cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout + if (!Concurrency::details::_Get_cond_var(cond)->wait_for( + cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout _Timespec64_get_sys(&now); if (_Xtime_diff_to_millis2(target, &now) == 0) { res = _Thrd_result::_Timedout; @@ -84,12 +85,12 @@ _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait( } _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_signal(const _Cnd_t cond) noexcept { // release one waiting thread - cond->_get_cv()->notify_one(); + Concurrency::details::_Get_cond_var(cond)->notify_one(); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_broadcast(const _Cnd_t cond) noexcept { // release all waiting threads - cond->_get_cv()->notify_all(); + Concurrency::details::_Get_cond_var(cond)->notify_all(); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } diff --git a/stl/src/primitives.hpp b/stl/src/primitives.hpp index cd888ab514e..ff9b5937256 100644 --- a/stl/src/primitives.hpp +++ b/stl/src/primitives.hpp @@ -3,6 +3,7 @@ #pragma once +#include <__msvc_threads_core.hpp> #include #include @@ -43,18 +44,8 @@ namespace Concurrency { CONDITION_VARIABLE m_condition_variable = CONDITION_VARIABLE_INIT; }; + [[nodiscard]] inline stl_condition_variable_win7* _Get_cond_var(::_Cnd_internal_imp_t* _Cond) noexcept { + return reinterpret_cast(&_Cond->_Cv_storage); + } } // namespace details } // namespace Concurrency - -extern "C" { - -struct _Cnd_internal_imp_t { - std::_Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> cv; - - [[nodiscard]] Concurrency::details::stl_condition_variable_win7* _get_cv() noexcept { - // get pointer to implementation - return reinterpret_cast(&cv); - } -}; - -} // extern "C" diff --git a/stl/src/sharedmutex.cpp b/stl/src/sharedmutex.cpp index 73dbf6b2888..ef5e53f7450 100644 --- a/stl/src/sharedmutex.cpp +++ b/stl/src/sharedmutex.cpp @@ -50,7 +50,7 @@ _Thrd_result __stdcall _Cnd_timedwait_for(const _Cnd_t cond, const _Mtx_t mtx, c mtx->_Thread_id = -1; --mtx->_Count; - if (!cond->_get_cv()->wait_for(cs, target_ms)) { // report timeout + if (!Concurrency::details::_Get_cond_var(cond)->wait_for(cs, target_ms)) { // report timeout const auto end_ms = GetTickCount64(); if (end_ms - start_ms >= target_ms) { res = _Thrd_result::_Timedout;