Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
509ad75a
Commit
509ad75a
authored
Jun 09, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move the futex-based condition variable implementation to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
246dedaa
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
138 additions
and
114 deletions
+138
-114
sync.c
dlls/ntdll/sync.c
+6
-113
loader.c
dlls/ntdll/unix/loader.c
+3
-0
sync.c
dlls/ntdll/unix/sync.c
+115
-0
unix_private.h
dlls/ntdll/unix/unix_private.h
+6
-0
unixlib.h
dlls/ntdll/unixlib.h
+8
-1
No files found.
dlls/ntdll/sync.c
View file @
509ad75a
...
...
@@ -105,16 +105,6 @@ static inline int use_futexes(void)
return
supported
;
}
static
int
*
get_futex
(
void
**
ptr
)
{
if
(
sizeof
(
void
*
)
==
8
)
return
(
int
*
)((((
ULONG_PTR
)
ptr
)
+
3
)
&
~
3
);
else
if
(
!
(((
ULONG_PTR
)
ptr
)
&
3
))
return
(
int
*
)
ptr
;
else
return
NULL
;
}
static
void
timespec_from_timeout
(
struct
timespec
*
timespec
,
const
LARGE_INTEGER
*
timeout
)
{
LARGE_INTEGER
now
;
...
...
@@ -1437,105 +1427,6 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock )
return
TRUE
;
}
#ifdef __linux__
static
NTSTATUS
fast_wait_cv
(
int
*
futex
,
int
val
,
const
LARGE_INTEGER
*
timeout
)
{
struct
timespec
timespec
;
int
ret
;
if
(
timeout
&&
timeout
->
QuadPart
!=
TIMEOUT_INFINITE
)
{
timespec_from_timeout
(
&
timespec
,
timeout
);
ret
=
futex_wait
(
futex
,
val
,
&
timespec
);
}
else
ret
=
futex_wait
(
futex
,
val
,
NULL
);
if
(
ret
==
-
1
&&
errno
==
ETIMEDOUT
)
return
STATUS_TIMEOUT
;
return
STATUS_WAIT_0
;
}
static
NTSTATUS
fast_sleep_cs_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
)
{
NTSTATUS
status
;
int
val
,
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
)))
return
STATUS_NOT_IMPLEMENTED
;
val
=
*
futex
;
RtlLeaveCriticalSection
(
cs
);
status
=
fast_wait_cv
(
futex
,
val
,
timeout
);
RtlEnterCriticalSection
(
cs
);
return
status
;
}
static
NTSTATUS
fast_sleep_srw_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
)
{
NTSTATUS
status
;
int
val
,
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
)))
return
STATUS_NOT_IMPLEMENTED
;
val
=
*
futex
;
if
(
flags
&
RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
)
RtlReleaseSRWLockShared
(
lock
);
else
RtlReleaseSRWLockExclusive
(
lock
);
status
=
fast_wait_cv
(
futex
,
val
,
timeout
);
if
(
flags
&
RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
)
RtlAcquireSRWLockShared
(
lock
);
else
RtlAcquireSRWLockExclusive
(
lock
);
return
status
;
}
static
NTSTATUS
fast_wake_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
)
{
int
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
)))
return
STATUS_NOT_IMPLEMENTED
;
InterlockedIncrement
(
futex
);
futex_wake
(
futex
,
count
);
return
STATUS_SUCCESS
;
}
#else
static
NTSTATUS
fast_sleep_srw_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
static
NTSTATUS
fast_sleep_cs_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
static
NTSTATUS
fast_wake_cv
(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
#endif
/***********************************************************************
* RtlInitializeConditionVariable (NTDLL.@)
*
...
...
@@ -1569,7 +1460,7 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
*/
void
WINAPI
RtlWakeConditionVariable
(
RTL_CONDITION_VARIABLE
*
variable
)
{
if
(
fast_wake_cv
(
variable
,
1
)
==
STATUS_NOT_IMPLEMENTED
)
if
(
unix_funcs
->
fast_RtlWakeConditionVariable
(
variable
,
1
)
==
STATUS_NOT_IMPLEMENTED
)
{
InterlockedIncrement
(
(
int
*
)
&
variable
->
Ptr
);
RtlWakeAddressSingle
(
variable
);
...
...
@@ -1583,7 +1474,7 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
*/
void
WINAPI
RtlWakeAllConditionVariable
(
RTL_CONDITION_VARIABLE
*
variable
)
{
if
(
fast_wake_cv
(
variable
,
INT_MAX
)
==
STATUS_NOT_IMPLEMENTED
)
if
(
unix_funcs
->
fast_RtlWakeConditionVariable
(
variable
,
INT_MAX
)
==
STATUS_NOT_IMPLEMENTED
)
{
InterlockedIncrement
(
(
int
*
)
&
variable
->
Ptr
);
RtlWakeAddressAll
(
variable
);
...
...
@@ -1611,7 +1502,8 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R
NTSTATUS
status
;
int
val
;
if
((
status
=
fast_sleep_cs_cv
(
variable
,
crit
,
timeout
))
!=
STATUS_NOT_IMPLEMENTED
)
if
((
status
=
unix_funcs
->
fast_RtlSleepConditionVariableCS
(
variable
,
crit
,
timeout
))
!=
STATUS_NOT_IMPLEMENTED
)
return
status
;
val
=
*
(
int
*
)
&
variable
->
Ptr
;
...
...
@@ -1646,7 +1538,8 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
NTSTATUS
status
;
int
val
;
if
((
status
=
fast_sleep_srw_cv
(
variable
,
lock
,
timeout
,
flags
))
!=
STATUS_NOT_IMPLEMENTED
)
if
((
status
=
unix_funcs
->
fast_RtlSleepConditionVariableSRW
(
variable
,
lock
,
timeout
,
flags
))
!=
STATUS_NOT_IMPLEMENTED
)
return
status
;
val
=
*
(
int
*
)
&
variable
->
Ptr
;
...
...
dlls/ntdll/unix/loader.c
View file @
509ad75a
...
...
@@ -1052,6 +1052,9 @@ static struct unix_funcs unix_funcs =
fast_RtlAcquireSRWLockShared
,
fast_RtlReleaseSRWLockExclusive
,
fast_RtlReleaseSRWLockShared
,
fast_RtlSleepConditionVariableSRW
,
fast_RtlSleepConditionVariableCS
,
fast_RtlWakeConditionVariable
,
get_main_args
,
get_paths
,
get_dll_path
,
...
...
dlls/ntdll/unix/sync.c
View file @
509ad75a
...
...
@@ -67,6 +67,7 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
sync
);
#define TICKSPERSEC 10000000
HANDLE
keyed_event
=
0
;
...
...
@@ -126,6 +127,23 @@ static int *get_futex(void **ptr)
return
NULL
;
}
static
void
timespec_from_timeout
(
struct
timespec
*
timespec
,
const
LARGE_INTEGER
*
timeout
)
{
LARGE_INTEGER
now
;
timeout_t
diff
;
if
(
timeout
->
QuadPart
>
0
)
{
NtQuerySystemTime
(
&
now
);
diff
=
timeout
->
QuadPart
-
now
.
QuadPart
;
}
else
diff
=
-
timeout
->
QuadPart
;
timespec
->
tv_sec
=
diff
/
TICKSPERSEC
;
timespec
->
tv_nsec
=
(
diff
%
TICKSPERSEC
)
*
100
;
}
#endif
...
...
@@ -1260,6 +1278,86 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
return
STATUS_SUCCESS
;
}
static
NTSTATUS
wait_cv
(
int
*
futex
,
int
val
,
const
LARGE_INTEGER
*
timeout
)
{
struct
timespec
timespec
;
int
ret
;
if
(
timeout
&&
timeout
->
QuadPart
!=
TIMEOUT_INFINITE
)
{
timespec_from_timeout
(
&
timespec
,
timeout
);
ret
=
futex_wait
(
futex
,
val
,
&
timespec
);
}
else
ret
=
futex_wait
(
futex
,
val
,
NULL
);
if
(
ret
==
-
1
&&
errno
==
ETIMEDOUT
)
return
STATUS_TIMEOUT
;
return
STATUS_WAIT_0
;
}
NTSTATUS
CDECL
fast_RtlSleepConditionVariableCS
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
)
{
NTSTATUS
status
;
int
val
,
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
)))
return
STATUS_NOT_IMPLEMENTED
;
val
=
*
futex
;
RtlLeaveCriticalSection
(
cs
);
status
=
wait_cv
(
futex
,
val
,
timeout
);
RtlEnterCriticalSection
(
cs
);
return
status
;
}
NTSTATUS
CDECL
fast_RtlSleepConditionVariableSRW
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
)
{
NTSTATUS
status
;
int
val
,
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
))
||
!
get_futex
(
&
lock
->
Ptr
))
return
STATUS_NOT_IMPLEMENTED
;
val
=
*
futex
;
if
(
flags
&
RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
)
fast_RtlReleaseSRWLockShared
(
lock
);
else
fast_RtlReleaseSRWLockExclusive
(
lock
);
status
=
wait_cv
(
futex
,
val
,
timeout
);
if
(
flags
&
RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
)
fast_RtlAcquireSRWLockShared
(
lock
);
else
fast_RtlAcquireSRWLockExclusive
(
lock
);
return
status
;
}
NTSTATUS
CDECL
fast_RtlWakeConditionVariable
(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
)
{
int
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
if
(
!
(
futex
=
get_futex
(
&
variable
->
Ptr
)))
return
STATUS_NOT_IMPLEMENTED
;
InterlockedIncrement
(
futex
);
futex_wake
(
futex
,
count
);
return
STATUS_SUCCESS
;
}
#else
NTSTATUS
CDECL
fast_RtlTryAcquireSRWLockExclusive
(
RTL_SRWLOCK
*
lock
)
...
...
@@ -1292,4 +1390,21 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
return
STATUS_NOT_IMPLEMENTED
;
}
NTSTATUS
CDECL
fast_RtlSleepConditionVariableSRW
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
NTSTATUS
CDECL
fast_RtlSleepConditionVariableCS
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
NTSTATUS
CDECL
fast_RtlWakeConditionVariable
(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
#endif
dlls/ntdll/unix/unix_private.h
View file @
509ad75a
...
...
@@ -63,6 +63,12 @@ extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLS
extern
NTSTATUS
CDECL
fast_RtlAcquireSRWLockShared
(
RTL_SRWLOCK
*
lock
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlReleaseSRWLockExclusive
(
RTL_SRWLOCK
*
lock
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlReleaseSRWLockShared
(
RTL_SRWLOCK
*
lock
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlSleepConditionVariableSRW
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlSleepConditionVariableCS
(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlWakeConditionVariable
(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
)
DECLSPEC_HIDDEN
;
void
CDECL
mmap_add_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
void
CDECL
mmap_remove_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unixlib.h
View file @
509ad75a
...
...
@@ -28,7 +28,7 @@ struct ldt_copy;
struct
msghdr
;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 3
5
#define NTDLL_UNIXLIB_VERSION 3
6
struct
unix_funcs
{
...
...
@@ -151,6 +151,13 @@ struct unix_funcs
NTSTATUS
(
CDECL
*
fast_RtlAcquireSRWLockShared
)(
RTL_SRWLOCK
*
lock
);
NTSTATUS
(
CDECL
*
fast_RtlReleaseSRWLockExclusive
)(
RTL_SRWLOCK
*
lock
);
NTSTATUS
(
CDECL
*
fast_RtlReleaseSRWLockShared
)(
RTL_SRWLOCK
*
lock
);
NTSTATUS
(
CDECL
*
fast_RtlSleepConditionVariableSRW
)(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_SRWLOCK
*
lock
,
const
LARGE_INTEGER
*
timeout
,
ULONG
flags
);
NTSTATUS
(
CDECL
*
fast_RtlSleepConditionVariableCS
)(
RTL_CONDITION_VARIABLE
*
variable
,
RTL_CRITICAL_SECTION
*
cs
,
const
LARGE_INTEGER
*
timeout
);
NTSTATUS
(
CDECL
*
fast_RtlWakeConditionVariable
)(
RTL_CONDITION_VARIABLE
*
variable
,
int
count
);
/* environment functions */
void
(
CDECL
*
get_main_args
)(
int
*
argc
,
char
**
argv
[],
char
**
envp
[]
);
...
...
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