ntdll: Move the futex-based condition variable implementation to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
246dedaa09
commit
509ad75adb
|
@ -105,16 +105,6 @@ static inline int use_futexes(void)
|
||||||
return supported;
|
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 )
|
static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
LARGE_INTEGER now;
|
LARGE_INTEGER now;
|
||||||
|
@ -1437,105 +1427,6 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||||
return TRUE;
|
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( ×pec, timeout );
|
|
||||||
ret = futex_wait( futex, val, ×pec );
|
|
||||||
}
|
|
||||||
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.@)
|
* RtlInitializeConditionVariable (NTDLL.@)
|
||||||
*
|
*
|
||||||
|
@ -1569,7 +1460,7 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||||
*/
|
*/
|
||||||
void WINAPI RtlWakeConditionVariable( 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 );
|
InterlockedIncrement( (int *)&variable->Ptr );
|
||||||
RtlWakeAddressSingle( variable );
|
RtlWakeAddressSingle( variable );
|
||||||
|
@ -1583,7 +1474,7 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||||
*/
|
*/
|
||||||
void WINAPI RtlWakeAllConditionVariable( 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 );
|
InterlockedIncrement( (int *)&variable->Ptr );
|
||||||
RtlWakeAddressAll( variable );
|
RtlWakeAddressAll( variable );
|
||||||
|
@ -1611,7 +1502,8 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
int val;
|
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;
|
return status;
|
||||||
|
|
||||||
val = *(int *)&variable->Ptr;
|
val = *(int *)&variable->Ptr;
|
||||||
|
@ -1646,7 +1538,8 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
int val;
|
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;
|
return status;
|
||||||
|
|
||||||
val = *(int *)&variable->Ptr;
|
val = *(int *)&variable->Ptr;
|
||||||
|
|
|
@ -1052,6 +1052,9 @@ static struct unix_funcs unix_funcs =
|
||||||
fast_RtlAcquireSRWLockShared,
|
fast_RtlAcquireSRWLockShared,
|
||||||
fast_RtlReleaseSRWLockExclusive,
|
fast_RtlReleaseSRWLockExclusive,
|
||||||
fast_RtlReleaseSRWLockShared,
|
fast_RtlReleaseSRWLockShared,
|
||||||
|
fast_RtlSleepConditionVariableSRW,
|
||||||
|
fast_RtlSleepConditionVariableCS,
|
||||||
|
fast_RtlWakeConditionVariable,
|
||||||
get_main_args,
|
get_main_args,
|
||||||
get_paths,
|
get_paths,
|
||||||
get_dll_path,
|
get_dll_path,
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||||
|
|
||||||
|
#define TICKSPERSEC 10000000
|
||||||
|
|
||||||
HANDLE keyed_event = 0;
|
HANDLE keyed_event = 0;
|
||||||
|
|
||||||
|
@ -126,6 +127,23 @@ static int *get_futex(void **ptr)
|
||||||
return NULL;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1260,6 +1278,86 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||||
return STATUS_SUCCESS;
|
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( ×pec, timeout );
|
||||||
|
ret = futex_wait( futex, val, ×pec );
|
||||||
|
}
|
||||||
|
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
|
#else
|
||||||
|
|
||||||
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||||
|
@ -1292,4 +1390,21 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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
|
#endif
|
||||||
|
|
|
@ -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_RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS CDECL fast_RtlReleaseSRWLockExclusive( 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_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_add_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||||
void CDECL mmap_remove_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
void CDECL mmap_remove_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
||||||
struct msghdr;
|
struct msghdr;
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 35
|
#define NTDLL_UNIXLIB_VERSION 36
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -151,6 +151,13 @@ struct unix_funcs
|
||||||
NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock );
|
NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock );
|
||||||
NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock );
|
NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock );
|
||||||
NTSTATUS (CDECL *fast_RtlReleaseSRWLockShared)( 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 */
|
/* environment functions */
|
||||||
void (CDECL *get_main_args)( int *argc, char **argv[], char **envp[] );
|
void (CDECL *get_main_args)( int *argc, char **argv[], char **envp[] );
|
||||||
|
|
Loading…
Reference in New Issue