Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hasta la Vista #2317

Merged
merged 12 commits into from
Jul 1, 2022
Merged
7 changes: 4 additions & 3 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,7 @@ compiler option, or define _ALLOW_RTCc_IN_STL to acknowledge that you have recei
#endif // defined(MRTDLL) && !defined(_M_CEE_PURE)

#define _STL_WIN32_WINNT_VISTA 0x0600 // _WIN32_WINNT_VISTA from sdkddkver.h
#define _STL_WIN32_WINNT_WIN7 0x0601 // _WIN32_WINNT_WIN7 from sdkddkver.h
#define _STL_WIN32_WINNT_WIN8 0x0602 // _WIN32_WINNT_WIN8 from sdkddkver.h
#define _STL_WIN32_WINNT_WINBLUE 0x0603 // _WIN32_WINNT_WINBLUE from sdkddkver.h
#define _STL_WIN32_WINNT_WIN10 0x0A00 // _WIN32_WINNT_WIN10 from sdkddkver.h
Expand All @@ -1577,9 +1578,9 @@ compiler option, or define _ALLOW_RTCc_IN_STL to acknowledge that you have recei
#elif defined(_M_ARM) || defined(_ONECORE) || defined(_CRT_APP)
// The first ARM or OneCore or App Windows was Windows 8
#define _STL_WIN32_WINNT _STL_WIN32_WINNT_WIN8
#else // ^^^ default to Win8 // default to Vista vvv
// The earliest Windows supported by this implementation is Windows Vista
#define _STL_WIN32_WINNT _STL_WIN32_WINNT_VISTA
#else // ^^^ default to Win8 // default to Win7 vvv
// The earliest Windows supported by this implementation is Windows 7
#define _STL_WIN32_WINNT _STL_WIN32_WINNT_WIN7
#endif // ^^^ !defined(_M_ARM) && !defined(_M_ARM64) && !defined(_ONECORE) && !defined(_CRT_APP) ^^^
#endif // _STL_WIN32_WINNT

Expand Down
11 changes: 0 additions & 11 deletions stl/src/awint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ _CRT_BEGIN_C_HEADER
_CRTIMP2 BOOL __cdecl __crtIsPackagedApp();
#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)

#if _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7

#define __crtTryAcquireSRWLockExclusive(pLock) TryAcquireSRWLockExclusive(pLock)

#else // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7

BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(_Inout_ PSRWLOCK);

#endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7

#if _STL_WIN32_WINNT >= _WIN32_WINNT_WIN8

#define __crtGetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime) \
Expand Down Expand Up @@ -97,7 +87,6 @@ enum wrapKERNEL32Functions {
extern PVOID __KERNEL32Functions[eMaxKernel32Function];

using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME);
using PFNTRYACQUIRESRWLOCKEXCLUSIVE = BOOLEAN(WINAPI*)(PSRWLOCK);

// Use this macro for caching a function pointer from a DLL
#define STOREFUNCTIONPOINTER(instance, function_name) \
Expand Down
15 changes: 0 additions & 15 deletions stl/src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,21 +253,6 @@ static_assert(alignof(WIN32_FIND_DATAW) == alignof(__std_fs_find_data));
return __std_win_error::_Success;
}

#if _STL_WIN32_WINNT < _WIN32_WINNT_WIN7
// If the above call failed, we might be on pre Windows 7 / Windows Server 2008 R2, which doesn't support
// FindExInfoBasic; try again with FindExInfoStandard if we got an invalid parameter error.
const __std_win_error _Last_error{GetLastError()};
if (_Last_error != __std_win_error::_Not_supported && _Last_error != __std_win_error::_Invalid_parameter) {
return _Last_error;
}

*_Handle = __std_fs_dir_handle{reinterpret_cast<intptr_t>(
FindFirstFileExW(_Path_spec, FindExInfoStandard, _Results, FindExSearchNameMatch, nullptr, 0))};
if (*_Handle != __std_fs_dir_handle::_Invalid) {
return __std_win_error::_Success;
}
#endif // _STL_WIN32_WINNT < _WIN32_WINNT_WIN7

return __std_win_error{GetLastError()};
}

Expand Down
8 changes: 3 additions & 5 deletions stl/src/mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ extern "C" _CRTIMP2_PURE void _Thrd_abort(const char* msg) { // abort on precond
#define _THREAD_ASSERT(expr, msg) ((void) 0)
#endif // _THREAD_CHECKX

__stl_sync_api_modes_enum __stl_sync_api_impl_mode = __stl_sync_api_modes_enum::normal;

extern "C" _CRTIMP2 void __cdecl __set_stl_sync_api_mode(__stl_sync_api_modes_enum mode) {
__stl_sync_api_impl_mode = mode;
}
// TRANSITION, ABI: preserved for binary compatibility
enum class __stl_sync_api_modes_enum { normal, win7, vista, concrt };
extern "C" _CRTIMP2 void __cdecl __set_stl_sync_api_mode(__stl_sync_api_modes_enum) {}
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

struct _Mtx_internal_imp_t { // ConcRT mutex
int type;
Expand Down
184 changes: 22 additions & 162 deletions stl/src/primitives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@

#pragma once

#include <cstdlib> // for __max
#include <exception>
#include <new>

#include "awint.hpp"

enum class __stl_sync_api_modes_enum { normal, win7, vista, concrt };

extern __stl_sync_api_modes_enum __stl_sync_api_impl_mode;

namespace Concurrency {
namespace details {
class __declspec(novtable) stl_critical_section_interface {
Expand All @@ -33,81 +28,6 @@ namespace Concurrency {
virtual void destroy() = 0;
};

class stl_critical_section_vista final : public stl_critical_section_interface {
public:
stl_critical_section_vista() {
InitializeCriticalSectionEx(&_M_critical_section, 4000, 0);
}

stl_critical_section_vista(const stl_critical_section_vista&) = delete;
stl_critical_section_vista& operator=(const stl_critical_section_vista&) = delete;
~stl_critical_section_vista() = delete;

void destroy() override {
DeleteCriticalSection(&_M_critical_section);
}

void lock() override {
EnterCriticalSection(&_M_critical_section);
}

bool try_lock() override {
return TryEnterCriticalSection(&_M_critical_section) != 0;
}

bool try_lock_for(unsigned int) override {
// STL will call try_lock_for once again if this call will not succeed
return stl_critical_section_vista::try_lock();
}

void unlock() override {
LeaveCriticalSection(&_M_critical_section);
}

LPCRITICAL_SECTION native_handle() {
return &_M_critical_section;
}

private:
CRITICAL_SECTION _M_critical_section;
};

class stl_condition_variable_vista final : public stl_condition_variable_interface {
public:
stl_condition_variable_vista() {
InitializeConditionVariable(&m_condition_variable);
}

~stl_condition_variable_vista() = delete;
stl_condition_variable_vista(const stl_condition_variable_vista&) = delete;
stl_condition_variable_vista& operator=(const stl_condition_variable_vista&) = delete;

void destroy() override {}

void wait(stl_critical_section_interface* lock) override {
if (!stl_condition_variable_vista::wait_for(lock, INFINITE)) {
std::terminate();
}
}

bool wait_for(stl_critical_section_interface* lock, unsigned int timeout) override {
return SleepConditionVariableCS(&m_condition_variable,
static_cast<stl_critical_section_vista*>(lock)->native_handle(), timeout)
!= 0;
}

void notify_one() override {
WakeConditionVariable(&m_condition_variable);
}

void notify_all() override {
WakeAllConditionVariable(&m_condition_variable);
}

private:
CONDITION_VARIABLE m_condition_variable;
};

class stl_critical_section_win7 final : public stl_critical_section_interface {
public:
stl_critical_section_win7() {
Expand All @@ -125,7 +45,7 @@ namespace Concurrency {
}

bool try_lock() override {
return __crtTryAcquireSRWLockExclusive(&m_srw_lock) != 0;
return TryAcquireSRWLockExclusive(&m_srw_lock) != 0;
}

bool try_lock_for(unsigned int) override {
Expand Down Expand Up @@ -181,99 +101,39 @@ namespace Concurrency {
CONDITION_VARIABLE m_condition_variable;
};

inline bool are_win7_sync_apis_available() {
#if _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7
return true;
#else
// TryAcquireSRWLockExclusive ONLY available on Windows 7+
DYNAMICGETCACHEDFUNCTION(
PFNTRYACQUIRESRWLOCKEXCLUSIVE, TryAcquireSRWLockExclusive, pfTryAcquireSRWLockExclusive);
return pfTryAcquireSRWLockExclusive != nullptr;
#endif
}

inline void create_stl_critical_section(stl_critical_section_interface* p) {
#ifdef _CRT_WINDOWS
new (p) stl_critical_section_win7;
#else
switch (__stl_sync_api_impl_mode) {
case __stl_sync_api_modes_enum::normal:
case __stl_sync_api_modes_enum::win7:
if (are_win7_sync_apis_available()) {
new (p) stl_critical_section_win7;
return;
}
// fall through
case __stl_sync_api_modes_enum::vista:
new (p) stl_critical_section_vista;
return;
default:
abort();
}
#endif // _CRT_WINDOWS
}

inline void create_stl_condition_variable(stl_condition_variable_interface* p) {
#ifdef _CRT_WINDOWS
new (p) stl_condition_variable_win7;
#else
switch (__stl_sync_api_impl_mode) {
case __stl_sync_api_modes_enum::normal:
case __stl_sync_api_modes_enum::win7:
if (are_win7_sync_apis_available()) {
new (p) stl_condition_variable_win7;
return;
}
// fall through
case __stl_sync_api_modes_enum::vista:
new (p) stl_condition_variable_vista;
return;
default:
abort();
}
#endif // _CRT_WINDOWS
}

#if defined _CRT_WINDOWS
const size_t stl_critical_section_max_size = sizeof(stl_critical_section_win7);
const size_t stl_condition_variable_max_size = sizeof(stl_condition_variable_win7);
const size_t stl_critical_section_max_alignment = alignof(stl_critical_section_win7);
const size_t stl_condition_variable_max_alignment = alignof(stl_condition_variable_win7);
#elif defined _STL_CONCRT_SUPPORT

#ifdef _WIN64
const size_t sizeof_stl_critical_section_concrt = 64;
const size_t sizeof_stl_critical_section_concrt = 64;
const size_t sizeof_stl_condition_variable_concrt = 72;
const size_t alignof_stl_critical_section_concrt = 8;
const size_t alignof_stl_condition_variable_concrt = 8;
const size_t sizeof_stl_critical_section_vista = 48;
const size_t sizeof_stl_condition_variable_vista = 16;
#else // ^^^ 64-bit / 32-bit vvv
const size_t sizeof_stl_critical_section_concrt = 36;
const size_t sizeof_stl_condition_variable_concrt = 40;
const size_t alignof_stl_critical_section_concrt = 4;
const size_t alignof_stl_condition_variable_concrt = 4;
const size_t sizeof_stl_critical_section_concrt = 36;
const size_t sizeof_stl_condition_variable_concrt = 40;
const size_t sizeof_stl_critical_section_vista = 28;
const size_t sizeof_stl_condition_variable_vista = 8;
#endif // ^^^ 32-bit ^^^

const size_t stl_critical_section_max_size =
__max(__max(sizeof_stl_critical_section_concrt, sizeof(stl_critical_section_vista)),
sizeof(stl_critical_section_win7));
const size_t stl_condition_variable_max_size =
__max(__max(sizeof_stl_condition_variable_concrt, sizeof(stl_condition_variable_vista)),
sizeof(stl_condition_variable_win7));
const size_t stl_critical_section_max_alignment =
__max(__max(alignof_stl_critical_section_concrt, alignof(stl_critical_section_vista)),
alignof(stl_critical_section_win7));
const size_t stl_condition_variable_max_alignment =
__max(__max(alignof_stl_condition_variable_concrt, alignof(stl_condition_variable_vista)),
alignof(stl_condition_variable_win7));
#else
const size_t stl_critical_section_max_size =
__max(sizeof(stl_critical_section_vista), sizeof(stl_critical_section_win7));
const size_t stl_condition_variable_max_size =
__max(sizeof(stl_condition_variable_vista), sizeof(stl_condition_variable_win7));
const size_t stl_critical_section_max_alignment =
__max(alignof(stl_critical_section_vista), alignof(stl_critical_section_win7));
const size_t stl_condition_variable_max_alignment =
__max(alignof(stl_condition_variable_vista), alignof(stl_condition_variable_win7));
#endif
#if defined(_CRT_WINDOWS)
const size_t stl_critical_section_max_size = sizeof(stl_critical_section_win7);
const size_t stl_condition_variable_max_size = sizeof(stl_condition_variable_win7);
#elif defined(_STL_CONCRT_SUPPORT)
const size_t stl_critical_section_max_size = sizeof_stl_critical_section_concrt;
const size_t stl_condition_variable_max_size = sizeof_stl_condition_variable_concrt;
#else // vvv !defined(_CRT_WINDOWS) && !defined(_STL_CONCRT_SUPPORT) vvv
const size_t stl_critical_section_max_size = sizeof_stl_critical_section_vista;
const size_t stl_condition_variable_max_size = sizeof_stl_condition_variable_vista;
#endif // ^^^ !defined(_CRT_WINDOWS) && !defined(_STL_CONCRT_SUPPORT) ^^^

// concrt, vista, and win7 alignments are all identical to alignof(void*)
const size_t stl_critical_section_max_alignment = alignof(stl_critical_section_win7);
const size_t stl_condition_variable_max_alignment = alignof(stl_condition_variable_win7);
} // namespace details
} // namespace Concurrency
6 changes: 2 additions & 4 deletions stl/src/winapisupp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,9 @@ extern "C" BOOL __cdecl __crtQueueUserWorkItem(_In_ LPTHREAD_START_ROUTINE, _In_


#if _STL_WIN32_WINNT < _WIN32_WINNT_WIN7

// TRANSITION, ABI: preserved for binary compatibility
extern "C" BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(_Inout_ PSRWLOCK const pLock) {
DYNAMICGETCACHEDFUNCTION(PFNTRYACQUIRESRWLOCKEXCLUSIVE, TryAcquireSRWLockExclusive, pfTryAcquireSRWLockExclusive);
return pfTryAcquireSRWLockExclusive(pLock);
// Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling
return TryAcquireSRWLockExclusive(pLock);
}

#endif // _STL_WIN32_WINNT < _WIN32_WINNT_WIN7
Expand Down