Skip to content

Commit b8128f4

Browse files
PiotrCWjulliard
authored andcommitted
msvcp140: Add SRWLock based _Mtx_t and _Cnd_t implementation.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
1 parent 3f97321 commit b8128f4

File tree

3 files changed

+107
-44
lines changed

3 files changed

+107
-44
lines changed

dlls/msvcp90/misc.c

+5-8
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222

2323
#include "msvcp90.h"
2424

25-
#include "windef.h"
26-
#include "winbase.h"
27-
#include "winternl.h"
2825
#include "wine/debug.h"
2926

3027
WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
@@ -714,7 +711,7 @@ unsigned int __cdecl _Random_device(void)
714711
typedef struct
715712
{
716713
DWORD flags;
717-
critical_section cs;
714+
cs cs;
718715
DWORD thread_id;
719716
DWORD count;
720717
} *_Mtx_t;
@@ -802,7 +799,7 @@ int __cdecl _Mtx_trylock(_Mtx_arg_t mtx)
802799
return 0;
803800
}
804801

805-
critical_section* __cdecl _Mtx_getconcrtcs(_Mtx_arg_t mtx)
802+
void* __cdecl _Mtx_getconcrtcs(_Mtx_arg_t mtx)
806803
{
807804
return &MTX_T_FROM_ARG(mtx)->cs;
808805
}
@@ -825,7 +822,7 @@ void __cdecl _Mtx_reset_owner(_Mtx_arg_t mtx)
825822

826823
typedef struct
827824
{
828-
_Condition_variable cv;
825+
cv cv;
829826
} *_Cnd_t;
830827

831828
#if _MSVCP_VER >= 140
@@ -852,7 +849,7 @@ int __cdecl _Cnd_init(_Cnd_t *cnd)
852849

853850
int __cdecl _Cnd_wait(_Cnd_arg_t cnd, _Mtx_arg_t mtx)
854851
{
855-
_Condition_variable *cv = &CND_T_FROM_ARG(cnd)->cv;
852+
cv *cv = &CND_T_FROM_ARG(cnd)->cv;
856853
_Mtx_t m = MTX_T_FROM_ARG(mtx);
857854

858855
_Mtx_clear_owner(mtx);
@@ -863,7 +860,7 @@ int __cdecl _Cnd_wait(_Cnd_arg_t cnd, _Mtx_arg_t mtx)
863860

864861
int __cdecl _Cnd_timedwait(_Cnd_arg_t cnd, _Mtx_arg_t mtx, const xtime *xt)
865862
{
866-
_Condition_variable *cv = &CND_T_FROM_ARG(cnd)->cv;
863+
cv *cv = &CND_T_FROM_ARG(cnd)->cv;
867864
_Mtx_t m = MTX_T_FROM_ARG(mtx);
868865
bool r;
869866

dlls/msvcp90/msvcp90.h

+25-12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "stdbool.h"
2020
#include "stdlib.h"
2121
#include "windef.h"
22+
#include "winbase.h"
2223
#include "cxx.h"
2324

2425
#define CXX_EXCEPTION 0xe06d7363
@@ -58,6 +59,12 @@ typedef struct
5859
void *tail;
5960
} critical_section;
6061

62+
typedef union
63+
{
64+
critical_section conc;
65+
SRWLOCK win;
66+
} cs;
67+
6168
typedef struct cv_queue {
6269
struct cv_queue *next;
6370
LONG expired;
@@ -69,18 +76,24 @@ typedef struct {
6976
critical_section lock;
7077
} _Condition_variable;
7178

72-
extern void cs_init(critical_section*);
73-
extern void cs_destroy(critical_section*);
74-
extern void cs_lock(critical_section*);
75-
extern void cs_unlock(critical_section*);
76-
extern bool cs_trylock(critical_section*);
77-
78-
extern void cv_init(_Condition_variable*);
79-
extern void cv_destroy(_Condition_variable*);
80-
extern void cv_wait(_Condition_variable*, critical_section*);
81-
extern bool cv_wait_for(_Condition_variable*, critical_section*, unsigned int);
82-
extern void cv_notify_one(_Condition_variable*);
83-
extern void cv_notify_all(_Condition_variable*);
79+
typedef union
80+
{
81+
_Condition_variable conc;
82+
CONDITION_VARIABLE win;
83+
} cv;
84+
85+
extern void cs_init(cs*);
86+
extern void cs_destroy(cs*);
87+
extern void cs_lock(cs*);
88+
extern void cs_unlock(cs*);
89+
extern bool cs_trylock(cs*);
90+
91+
extern void cv_init(cv*);
92+
extern void cv_destroy(cv*);
93+
extern void cv_wait(cv*, cs*);
94+
extern bool cv_wait_for(cv*, cs*, unsigned int);
95+
extern void cv_notify_one(cv*);
96+
extern void cv_notify_all(cv*);
8497
#endif
8598

8699
#if _MSVCP_VER >= 100

dlls/msvcp90/msvcp_main.c

+77-24
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ DEFINE_VTBL_WRAPPER(56);
5656

5757
void* (__cdecl *MSVCRT_set_new_handler)(void*);
5858

59-
#if _MSVCP_VER >= 110
59+
#if _MSVCP_VER >= 110 && _MSVCP_VER <= 120
6060
#ifdef __ASM_USE_THISCALL_WRAPPER
6161

6262
extern void *call_thiscall_func;
@@ -93,59 +93,112 @@ bool (__thiscall *_Condition_variable_wait_for)(_Condition_variable*,
9393
void (__thiscall *_Condition_variable_notify_one)(_Condition_variable*);
9494
void (__thiscall *_Condition_variable_notify_all)(_Condition_variable*);
9595

96-
void cs_init(critical_section *cs)
96+
void cs_init(cs *cs)
9797
{
98-
call_func1(critical_section_ctor, cs);
98+
call_func1(critical_section_ctor, &cs->conc);
9999
}
100100

101-
void cs_destroy(critical_section *cs)
101+
void cs_destroy(cs *cs)
102102
{
103-
call_func1(critical_section_dtor, cs);
103+
call_func1(critical_section_dtor, &cs->conc);
104104
}
105105

106-
void cs_lock(critical_section *cs)
106+
void cs_lock(cs *cs)
107107
{
108-
call_func1(critical_section_lock, cs);
108+
call_func1(critical_section_lock, &cs->conc);
109109
}
110110

111-
void cs_unlock(critical_section *cs)
111+
void cs_unlock(cs *cs)
112112
{
113-
call_func1(critical_section_unlock, cs);
113+
call_func1(critical_section_unlock, &cs->conc);
114114
}
115115

116-
bool cs_trylock(critical_section *cs)
116+
bool cs_trylock(cs *cs)
117117
{
118-
return call_func1(critical_section_trylock, cs);
118+
return call_func1(critical_section_trylock, &cs->conc);
119119
}
120120

121-
void cv_init(_Condition_variable *cv)
121+
void cv_init(cv *cv)
122122
{
123-
call_func1(_Condition_variable_ctor, cv);
123+
call_func1(_Condition_variable_ctor, &cv->conc);
124124
}
125125

126-
void cv_destroy(_Condition_variable *cv)
126+
void cv_destroy(cv *cv)
127127
{
128-
call_func1(_Condition_variable_dtor, cv);
128+
call_func1(_Condition_variable_dtor, &cv->conc);
129129
}
130130

131-
void cv_wait(_Condition_variable *cv, critical_section *cs)
131+
void cv_wait(cv *cv, cs *cs)
132132
{
133-
call_func2(_Condition_variable_wait, cv, cs);
133+
call_func2(_Condition_variable_wait, &cv->conc, &cs->conc);
134134
}
135135

136-
bool cv_wait_for(_Condition_variable *cv, critical_section *cs, unsigned int timeout)
136+
bool cv_wait_for(cv *cv, cs *cs, unsigned int timeout)
137137
{
138-
return call_func3(_Condition_variable_wait_for, cv, cs, timeout);
138+
return call_func3(_Condition_variable_wait_for, &cv->conc, &cs->conc, timeout);
139139
}
140140

141-
void cv_notify_one(_Condition_variable *cv)
141+
void cv_notify_one(cv *cv)
142142
{
143-
call_func1(_Condition_variable_notify_one, cv);
143+
call_func1(_Condition_variable_notify_one, &cv->conc);
144144
}
145145

146-
void cv_notify_all(_Condition_variable *cv)
146+
void cv_notify_all(cv *cv)
147147
{
148-
call_func1(_Condition_variable_notify_all, cv);
148+
call_func1(_Condition_variable_notify_all, &cv->conc);
149+
}
150+
#elif _MSVCP_VER >= 140
151+
void cs_init(cs *cs)
152+
{
153+
InitializeSRWLock(&cs->win);
154+
}
155+
156+
void cs_destroy(cs *cs)
157+
{
158+
}
159+
160+
void cs_lock(cs *cs)
161+
{
162+
AcquireSRWLockExclusive(&cs->win);
163+
}
164+
165+
void cs_unlock(cs *cs)
166+
{
167+
ReleaseSRWLockExclusive(&cs->win);
168+
}
169+
170+
bool cs_trylock(cs *cs)
171+
{
172+
return TryAcquireSRWLockExclusive(&cs->win);
173+
}
174+
175+
void cv_init(cv *cv)
176+
{
177+
InitializeConditionVariable(&cv->win);
178+
}
179+
180+
void cv_destroy(cv *cv)
181+
{
182+
}
183+
184+
void cv_wait(cv *cv, cs *cs)
185+
{
186+
SleepConditionVariableSRW(&cv->win, &cs->win, INFINITE, 0);
187+
}
188+
189+
bool cv_wait_for(cv *cv, cs *cs, unsigned int timeout)
190+
{
191+
return SleepConditionVariableSRW(&cv->win, &cs->win, timeout, 0);
192+
}
193+
194+
void cv_notify_one(cv *cv)
195+
{
196+
WakeConditionVariable(&cv->win);
197+
}
198+
199+
void cv_notify_all(cv *cv)
200+
{
201+
WakeAllConditionVariable(&cv->win);
149202
}
150203
#endif
151204

@@ -240,7 +293,7 @@ static void init_cxx_funcs(void)
240293
}
241294
#endif
242295

243-
#if _MSVCP_VER >= 110
296+
#if _MSVCP_VER >= 110 && _MSVCP_VER <= 120
244297
if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
245298
{
246299
critical_section_ctor = (void*)GetProcAddress(hcon, "??0critical_section@Concurrency@@QEAA@XZ");

0 commit comments

Comments
 (0)