From b8128f4162b5af7168ef7683543b96cd47d92748 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 15 Mar 2022 14:37:01 +0100 Subject: [PATCH] msvcp140: Add SRWLock based _Mtx_t and _Cnd_t implementation. Signed-off-by: Piotr Caban Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/msvcp90/misc.c | 13 ++--- dlls/msvcp90/msvcp90.h | 35 ++++++++----- dlls/msvcp90/msvcp_main.c | 101 +++++++++++++++++++++++++++++--------- 3 files changed, 106 insertions(+), 43 deletions(-) diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index c7047f72164..103eca6f4a3 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -22,9 +22,6 @@ #include "msvcp90.h" -#include "windef.h" -#include "winbase.h" -#include "winternl.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msvcp); @@ -714,7 +711,7 @@ unsigned int __cdecl _Random_device(void) typedef struct { DWORD flags; - critical_section cs; + cs cs; DWORD thread_id; DWORD count; } *_Mtx_t; @@ -802,7 +799,7 @@ int __cdecl _Mtx_trylock(_Mtx_arg_t mtx) return 0; } -critical_section* __cdecl _Mtx_getconcrtcs(_Mtx_arg_t mtx) +void* __cdecl _Mtx_getconcrtcs(_Mtx_arg_t mtx) { return &MTX_T_FROM_ARG(mtx)->cs; } @@ -825,7 +822,7 @@ void __cdecl _Mtx_reset_owner(_Mtx_arg_t mtx) typedef struct { - _Condition_variable cv; + cv cv; } *_Cnd_t; #if _MSVCP_VER >= 140 @@ -852,7 +849,7 @@ int __cdecl _Cnd_init(_Cnd_t *cnd) int __cdecl _Cnd_wait(_Cnd_arg_t cnd, _Mtx_arg_t mtx) { - _Condition_variable *cv = &CND_T_FROM_ARG(cnd)->cv; + cv *cv = &CND_T_FROM_ARG(cnd)->cv; _Mtx_t m = MTX_T_FROM_ARG(mtx); _Mtx_clear_owner(mtx); @@ -863,7 +860,7 @@ int __cdecl _Cnd_wait(_Cnd_arg_t cnd, _Mtx_arg_t mtx) int __cdecl _Cnd_timedwait(_Cnd_arg_t cnd, _Mtx_arg_t mtx, const xtime *xt) { - _Condition_variable *cv = &CND_T_FROM_ARG(cnd)->cv; + cv *cv = &CND_T_FROM_ARG(cnd)->cv; _Mtx_t m = MTX_T_FROM_ARG(mtx); bool r; diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 49840affcf6..b996ae84a46 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -19,6 +19,7 @@ #include "stdbool.h" #include "stdlib.h" #include "windef.h" +#include "winbase.h" #include "cxx.h" #define CXX_EXCEPTION 0xe06d7363 @@ -58,6 +59,12 @@ typedef struct void *tail; } critical_section; +typedef union +{ + critical_section conc; + SRWLOCK win; +} cs; + typedef struct cv_queue { struct cv_queue *next; LONG expired; @@ -69,18 +76,24 @@ typedef struct { critical_section lock; } _Condition_variable; -extern void cs_init(critical_section*); -extern void cs_destroy(critical_section*); -extern void cs_lock(critical_section*); -extern void cs_unlock(critical_section*); -extern bool cs_trylock(critical_section*); +typedef union +{ + _Condition_variable conc; + CONDITION_VARIABLE win; +} cv; -extern void cv_init(_Condition_variable*); -extern void cv_destroy(_Condition_variable*); -extern void cv_wait(_Condition_variable*, critical_section*); -extern bool cv_wait_for(_Condition_variable*, critical_section*, unsigned int); -extern void cv_notify_one(_Condition_variable*); -extern void cv_notify_all(_Condition_variable*); +extern void cs_init(cs*); +extern void cs_destroy(cs*); +extern void cs_lock(cs*); +extern void cs_unlock(cs*); +extern bool cs_trylock(cs*); + +extern void cv_init(cv*); +extern void cv_destroy(cv*); +extern void cv_wait(cv*, cs*); +extern bool cv_wait_for(cv*, cs*, unsigned int); +extern void cv_notify_one(cv*); +extern void cv_notify_all(cv*); #endif #if _MSVCP_VER >= 100 diff --git a/dlls/msvcp90/msvcp_main.c b/dlls/msvcp90/msvcp_main.c index afaa461312e..4c9faec9e26 100644 --- a/dlls/msvcp90/msvcp_main.c +++ b/dlls/msvcp90/msvcp_main.c @@ -56,7 +56,7 @@ DEFINE_VTBL_WRAPPER(56); void* (__cdecl *MSVCRT_set_new_handler)(void*); -#if _MSVCP_VER >= 110 +#if _MSVCP_VER >= 110 && _MSVCP_VER <= 120 #ifdef __ASM_USE_THISCALL_WRAPPER extern void *call_thiscall_func; @@ -93,59 +93,112 @@ bool (__thiscall *_Condition_variable_wait_for)(_Condition_variable*, void (__thiscall *_Condition_variable_notify_one)(_Condition_variable*); void (__thiscall *_Condition_variable_notify_all)(_Condition_variable*); -void cs_init(critical_section *cs) +void cs_init(cs *cs) { - call_func1(critical_section_ctor, cs); + call_func1(critical_section_ctor, &cs->conc); } -void cs_destroy(critical_section *cs) +void cs_destroy(cs *cs) { - call_func1(critical_section_dtor, cs); + call_func1(critical_section_dtor, &cs->conc); } -void cs_lock(critical_section *cs) +void cs_lock(cs *cs) { - call_func1(critical_section_lock, cs); + call_func1(critical_section_lock, &cs->conc); } -void cs_unlock(critical_section *cs) +void cs_unlock(cs *cs) { - call_func1(critical_section_unlock, cs); + call_func1(critical_section_unlock, &cs->conc); } -bool cs_trylock(critical_section *cs) +bool cs_trylock(cs *cs) { - return call_func1(critical_section_trylock, cs); + return call_func1(critical_section_trylock, &cs->conc); } -void cv_init(_Condition_variable *cv) +void cv_init(cv *cv) { - call_func1(_Condition_variable_ctor, cv); + call_func1(_Condition_variable_ctor, &cv->conc); } -void cv_destroy(_Condition_variable *cv) +void cv_destroy(cv *cv) { - call_func1(_Condition_variable_dtor, cv); + call_func1(_Condition_variable_dtor, &cv->conc); } -void cv_wait(_Condition_variable *cv, critical_section *cs) +void cv_wait(cv *cv, cs *cs) { - call_func2(_Condition_variable_wait, cv, cs); + call_func2(_Condition_variable_wait, &cv->conc, &cs->conc); } -bool cv_wait_for(_Condition_variable *cv, critical_section *cs, unsigned int timeout) +bool cv_wait_for(cv *cv, cs *cs, unsigned int timeout) { - return call_func3(_Condition_variable_wait_for, cv, cs, timeout); + return call_func3(_Condition_variable_wait_for, &cv->conc, &cs->conc, timeout); } -void cv_notify_one(_Condition_variable *cv) +void cv_notify_one(cv *cv) { - call_func1(_Condition_variable_notify_one, cv); + call_func1(_Condition_variable_notify_one, &cv->conc); } -void cv_notify_all(_Condition_variable *cv) +void cv_notify_all(cv *cv) { - call_func1(_Condition_variable_notify_all, cv); + call_func1(_Condition_variable_notify_all, &cv->conc); +} +#elif _MSVCP_VER >= 140 +void cs_init(cs *cs) +{ + InitializeSRWLock(&cs->win); +} + +void cs_destroy(cs *cs) +{ +} + +void cs_lock(cs *cs) +{ + AcquireSRWLockExclusive(&cs->win); +} + +void cs_unlock(cs *cs) +{ + ReleaseSRWLockExclusive(&cs->win); +} + +bool cs_trylock(cs *cs) +{ + return TryAcquireSRWLockExclusive(&cs->win); +} + +void cv_init(cv *cv) +{ + InitializeConditionVariable(&cv->win); +} + +void cv_destroy(cv *cv) +{ +} + +void cv_wait(cv *cv, cs *cs) +{ + SleepConditionVariableSRW(&cv->win, &cs->win, INFINITE, 0); +} + +bool cv_wait_for(cv *cv, cs *cs, unsigned int timeout) +{ + return SleepConditionVariableSRW(&cv->win, &cs->win, timeout, 0); +} + +void cv_notify_one(cv *cv) +{ + WakeConditionVariable(&cv->win); +} + +void cv_notify_all(cv *cv) +{ + WakeAllConditionVariable(&cv->win); } #endif @@ -240,7 +293,7 @@ static void init_cxx_funcs(void) } #endif -#if _MSVCP_VER >= 110 +#if _MSVCP_VER >= 110 && _MSVCP_VER <= 120 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */ { critical_section_ctor = (void*)GetProcAddress(hcon, "??0critical_section@Concurrency@@QEAA@XZ");