Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
3f97321c
Commit
3f97321c
authored
Mar 15, 2022
by
Piotr Caban
Committed by
Alexandre Julliard
Mar 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcp110: Use _Condition_variable in _Cnd_t implementation.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e040e2c1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
55 deletions
+108
-55
misc.c
dlls/msvcp90/misc.c
+18
-55
msvcp90.h
dlls/msvcp90/msvcp90.h
+18
-0
msvcp_main.c
dlls/msvcp90/msvcp_main.c
+72
-0
No files found.
dlls/msvcp90/misc.c
View file @
3f97321c
...
...
@@ -821,22 +821,11 @@ void __cdecl _Mtx_reset_owner(_Mtx_arg_t mtx)
m
->
count
++
;
}
static
inline
LONG
interlocked_dec_if_nonzero
(
LONG
*
dest
)
{
LONG
val
,
tmp
;
for
(
val
=
*
dest
;;
val
=
tmp
)
{
if
(
!
val
||
(
tmp
=
InterlockedCompareExchange
(
dest
,
val
-
1
,
val
))
==
val
)
break
;
}
return
val
;
}
#define CND_TIMEDOUT 2
typedef
struct
{
CONDITION_VARIABLE
cv
;
_Condition_variable
cv
;
}
*
_Cnd_t
;
#if _MSVCP_VER >= 140
...
...
@@ -849,19 +838,9 @@ typedef _Cnd_t *_Cnd_arg_t;
#define CND_T_TO_ARG(c) (&(c))
#endif
static
HANDLE
keyed_event
;
void
__cdecl
_Cnd_init_in_situ
(
_Cnd_t
cnd
)
{
InitializeConditionVariable
(
&
cnd
->
cv
);
if
(
!
keyed_event
)
{
HANDLE
event
;
NtCreateKeyedEvent
(
&
event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
if
(
InterlockedCompareExchangePointer
(
&
keyed_event
,
event
,
NULL
)
!=
NULL
)
NtClose
(
event
);
}
cv_init
(
&
cnd
->
cv
);
}
int
__cdecl
_Cnd_init
(
_Cnd_t
*
cnd
)
...
...
@@ -873,64 +852,50 @@ 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
;
InterlockedExchangeAdd
(
(
LONG
*
)
&
cv
->
Ptr
,
1
);
_Mtx_unlock
(
mtx
);
NtWaitForKeyedEvent
(
keyed_event
,
&
cv
->
Ptr
,
FALSE
,
NULL
);
_Condition_variable
*
cv
=
&
CND_T_FROM_ARG
(
cnd
)
->
cv
;
_Mtx_t
m
=
MTX_T_FROM_ARG
(
mtx
);
_Mtx_lock
(
mtx
);
_Mtx_clear_owner
(
mtx
);
cv_wait
(
cv
,
&
m
->
cs
);
_Mtx_reset_owner
(
mtx
);
return
0
;
}
int
__cdecl
_Cnd_timedwait
(
_Cnd_arg_t
cnd
,
_Mtx_arg_t
mtx
,
const
xtime
*
xt
)
{
CONDITION_VARIABLE
*
cv
=
&
CND_T_FROM_ARG
(
cnd
)
->
cv
;
LARGE_INTEGER
timeout
;
NTSTATUS
status
;
InterlockedExchangeAdd
(
(
LONG
*
)
&
cv
->
Ptr
,
1
);
_Mtx_unlock
(
mtx
);
timeout
.
QuadPart
=
(
ULONGLONG
)(
ULONG
)
_Xtime_diff_to_millis
(
xt
)
*
-
10000
;
status
=
NtWaitForKeyedEvent
(
keyed_event
,
&
cv
->
Ptr
,
FALSE
,
&
timeout
);
if
(
status
)
{
if
(
!
interlocked_dec_if_nonzero
(
(
LONG
*
)
&
cv
->
Ptr
))
status
=
NtWaitForKeyedEvent
(
keyed_event
,
&
cv
->
Ptr
,
FALSE
,
NULL
);
}
_Condition_variable
*
cv
=
&
CND_T_FROM_ARG
(
cnd
)
->
cv
;
_Mtx_t
m
=
MTX_T_FROM_ARG
(
mtx
);
bool
r
;
_Mtx_lock
(
mtx
);
return
status
?
CND_TIMEDOUT
:
0
;
_Mtx_clear_owner
(
mtx
);
r
=
cv_wait_for
(
cv
,
&
m
->
cs
,
_Xtime_diff_to_millis
(
xt
));
_Mtx_reset_owner
(
mtx
);
return
r
?
0
:
CND_TIMEDOUT
;
}
int
__cdecl
_Cnd_broadcast
(
_Cnd_arg_t
cnd
)
{
CONDITION_VARIABLE
*
cv
=
&
CND_T_FROM_ARG
(
cnd
)
->
cv
;
LONG
val
=
InterlockedExchange
(
(
LONG
*
)
&
cv
->
Ptr
,
0
);
while
(
val
--
>
0
)
NtReleaseKeyedEvent
(
keyed_event
,
&
cv
->
Ptr
,
FALSE
,
NULL
);
cv_notify_all
(
&
CND_T_FROM_ARG
(
cnd
)
->
cv
);
return
0
;
}
int
__cdecl
_Cnd_signal
(
_Cnd_arg_t
cnd
)
{
CONDITION_VARIABLE
*
cv
=
&
CND_T_FROM_ARG
(
cnd
)
->
cv
;
if
(
interlocked_dec_if_nonzero
(
(
LONG
*
)
&
cv
->
Ptr
))
NtReleaseKeyedEvent
(
keyed_event
,
&
cv
->
Ptr
,
FALSE
,
NULL
);
cv_notify_one
(
&
CND_T_FROM_ARG
(
cnd
)
->
cv
);
return
0
;
}
void
__cdecl
_Cnd_destroy_in_situ
(
_Cnd_t
cnd
)
{
_Cnd_broadcast
(
CND_T_TO_ARG
(
cnd
));
cv_destroy
(
&
cnd
->
cv
);
}
void
__cdecl
_Cnd_destroy
(
_Cnd_arg_t
cnd
)
{
if
(
cnd
)
{
_Cnd_broadcast
(
cnd
);
cv_destroy
(
&
CND_T_FROM_ARG
(
cnd
)
->
cv
);
operator_delete
(
CND_T_FROM_ARG
(
cnd
));
}
}
...
...
@@ -1777,8 +1742,6 @@ void init_misc(void *base)
void
free_misc
(
void
)
{
#if _MSVCP_VER >= 110
if
(
keyed_event
)
NtClose
(
keyed_event
);
HeapFree
(
GetProcessHeap
(),
0
,
broadcast_at_thread_exit
.
to_broadcast
);
#endif
}
...
...
dlls/msvcp90/msvcp90.h
View file @
3f97321c
...
...
@@ -58,11 +58,29 @@ typedef struct
void
*
tail
;
}
critical_section
;
typedef
struct
cv_queue
{
struct
cv_queue
*
next
;
LONG
expired
;
}
cv_queue
;
typedef
struct
{
/* cv_queue structure is not binary compatible */
cv_queue
*
queue
;
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
*
);
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
*
);
#endif
#if _MSVCP_VER >= 100
...
...
dlls/msvcp90/msvcp_main.c
View file @
3f97321c
...
...
@@ -68,10 +68,14 @@ __ASM_GLOBAL_FUNC(call_thiscall_func,
"jmp *%edx
\n\t
"
)
#define call_func1(func,this) ((void* (WINAPI*)(void*,void*))&call_thiscall_func)(func,this)
#define call_func2(func,this,a) ((void* (WINAPI*)(void*,void*,void*))&call_thiscall_func)(func,this,a)
#define call_func3(func,this,a,b) ((void* (WINAPI*)(void*,void*,void*,unsigned int))&call_thiscall_func)(func,this,a,b)
#else
/* __i386__ */
#define call_func1(func,this) func(this)
#define call_func2(func,this,a) func(this,a)
#define call_func3(func,this,a,b) func(this,a,b)
#endif
/* __i386__ */
...
...
@@ -81,6 +85,14 @@ static void (__thiscall *critical_section_lock)(critical_section*);
static
void
(
__thiscall
*
critical_section_unlock
)(
critical_section
*
);
static
bool
(
__thiscall
*
critical_section_trylock
)(
critical_section
*
);
static
_Condition_variable
*
(
__thiscall
*
_Condition_variable_ctor
)(
_Condition_variable
*
);
static
void
(
__thiscall
*
_Condition_variable_dtor
)(
_Condition_variable
*
);
static
void
(
__thiscall
*
_Condition_variable_wait
)(
_Condition_variable
*
,
critical_section
*
);
bool
(
__thiscall
*
_Condition_variable_wait_for
)(
_Condition_variable
*
,
critical_section
*
,
unsigned
int
);
void
(
__thiscall
*
_Condition_variable_notify_one
)(
_Condition_variable
*
);
void
(
__thiscall
*
_Condition_variable_notify_all
)(
_Condition_variable
*
);
void
cs_init
(
critical_section
*
cs
)
{
call_func1
(
critical_section_ctor
,
cs
);
...
...
@@ -105,6 +117,36 @@ bool cs_trylock(critical_section *cs)
{
return
call_func1
(
critical_section_trylock
,
cs
);
}
void
cv_init
(
_Condition_variable
*
cv
)
{
call_func1
(
_Condition_variable_ctor
,
cv
);
}
void
cv_destroy
(
_Condition_variable
*
cv
)
{
call_func1
(
_Condition_variable_dtor
,
cv
);
}
void
cv_wait
(
_Condition_variable
*
cv
,
critical_section
*
cs
)
{
call_func2
(
_Condition_variable_wait
,
cv
,
cs
);
}
bool
cv_wait_for
(
_Condition_variable
*
cv
,
critical_section
*
cs
,
unsigned
int
timeout
)
{
return
call_func3
(
_Condition_variable_wait_for
,
cv
,
cs
,
timeout
);
}
void
cv_notify_one
(
_Condition_variable
*
cv
)
{
call_func1
(
_Condition_variable_notify_one
,
cv
);
}
void
cv_notify_all
(
_Condition_variable
*
cv
)
{
call_func1
(
_Condition_variable_notify_all
,
cv
);
}
#endif
#if _MSVCP_VER >= 100
...
...
@@ -206,6 +248,16 @@ static void init_cxx_funcs(void)
critical_section_lock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?lock@critical_section@Concurrency@@QEAAXXZ"
);
critical_section_unlock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?unlock@critical_section@Concurrency@@QEAAXXZ"
);
critical_section_trylock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?try_lock@critical_section@Concurrency@@QEAA_NXZ"
);
_Condition_variable_ctor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??0_Condition_variable@details@Concurrency@@QEAA@XZ"
);
_Condition_variable_dtor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??1_Condition_variable@details@Concurrency@@QEAA@XZ"
);
_Condition_variable_wait
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait@_Condition_variable@details@Concurrency@@QEAAXAEAVcritical_section@3@@Z"
);
_Condition_variable_wait_for
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait_for@_Condition_variable@details@Concurrency@@QEAA_NAEAVcritical_section@3@I@Z"
);
_Condition_variable_notify_one
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_one@_Condition_variable@details@Concurrency@@QEAAXXZ"
);
_Condition_variable_notify_all
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_all@_Condition_variable@details@Concurrency@@QEAAXXZ"
);
}
else
{
...
...
@@ -215,12 +267,32 @@ static void init_cxx_funcs(void)
critical_section_lock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?lock@critical_section@Concurrency@@QAAXXZ"
);
critical_section_unlock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?unlock@critical_section@Concurrency@@QAAXXZ"
);
critical_section_trylock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?try_lock@critical_section@Concurrency@@QAA_NXZ"
);
_Condition_variable_ctor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??0_Condition_variable@details@Concurrency@@QAA@XZ"
);
_Condition_variable_dtor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??1_Condition_variable@details@Concurrency@@QAA@XZ"
);
_Condition_variable_wait
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait@_Condition_variable@details@Concurrency@@QAAXAAVcritical_section@3@@Z"
);
_Condition_variable_wait_for
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait_for@_Condition_variable@details@Concurrency@@QAA_NAAVcritical_section@3@I@Z"
);
_Condition_variable_notify_one
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_one@_Condition_variable@details@Concurrency@@QAAXXZ"
);
_Condition_variable_notify_all
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_all@_Condition_variable@details@Concurrency@@QAAXXZ"
);
#else
critical_section_ctor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??0critical_section@Concurrency@@QAE@XZ"
);
critical_section_dtor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??1critical_section@Concurrency@@QAE@XZ"
);
critical_section_lock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?lock@critical_section@Concurrency@@QAEXXZ"
);
critical_section_unlock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?unlock@critical_section@Concurrency@@QAEXXZ"
);
critical_section_trylock
=
(
void
*
)
GetProcAddress
(
hcon
,
"?try_lock@critical_section@Concurrency@@QAE_NXZ"
);
_Condition_variable_ctor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??0_Condition_variable@details@Concurrency@@QAE@XZ"
);
_Condition_variable_dtor
=
(
void
*
)
GetProcAddress
(
hcon
,
"??1_Condition_variable@details@Concurrency@@QAE@XZ"
);
_Condition_variable_wait
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait@_Condition_variable@details@Concurrency@@QAEXAAVcritical_section@3@@Z"
);
_Condition_variable_wait_for
=
(
void
*
)
GetProcAddress
(
hcon
,
"?wait_for@_Condition_variable@details@Concurrency@@QAE_NAAVcritical_section@3@I@Z"
);
_Condition_variable_notify_one
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_one@_Condition_variable@details@Concurrency@@QAEXXZ"
);
_Condition_variable_notify_all
=
(
void
*
)
GetProcAddress
(
hcon
,
"?notify_all@_Condition_variable@details@Concurrency@@QAEXXZ"
);
#endif
}
#endif
/* _MSVCP_VER >= 110 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment