1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

ntdll: Assume process-private futexes are always present on Linux.

This commit is contained in:
Brendan Shanks 2024-02-01 09:39:14 -08:00 committed by Alexandre Julliard
parent d93275c6ca
commit 455086e295
2 changed files with 17 additions and 44 deletions

View File

@ -42,7 +42,7 @@ especially the wealth of information found at https://www.winehq.org.
To compile and run Wine, you must have one of the following: To compile and run Wine, you must have one of the following:
- Linux version 2.0.36 or later - Linux version 2.6.22 or later
- FreeBSD 12.4 or later - FreeBSD 12.4 or later
- Solaris x86 9 or later - Solaris x86 9 or later
- NetBSD-current - NetBSD-current

View File

@ -103,10 +103,7 @@ static inline ULONGLONG monotonic_counter(void)
#ifdef __linux__ #ifdef __linux__
#define FUTEX_WAIT 0 #include <linux/futex.h>
#define FUTEX_WAKE 1
static int futex_private = 128;
static inline int futex_wait( const LONG *addr, int val, struct timespec *timeout ) static inline int futex_wait( const LONG *addr, int val, struct timespec *timeout )
{ {
@ -118,32 +115,15 @@ static inline int futex_wait( const LONG *addr, int val, struct timespec *timeou
long tv_nsec; long tv_nsec;
} timeout32 = { timeout->tv_sec, timeout->tv_nsec }; } timeout32 = { timeout->tv_sec, timeout->tv_nsec };
return syscall( __NR_futex, addr, FUTEX_WAIT | futex_private, val, &timeout32, 0, 0 ); return syscall( __NR_futex, addr, FUTEX_WAIT_PRIVATE, val, &timeout32, 0, 0 );
} }
#endif #endif
return syscall( __NR_futex, addr, FUTEX_WAIT | futex_private, val, timeout, 0, 0 ); return syscall( __NR_futex, addr, FUTEX_WAIT_PRIVATE, val, timeout, 0, 0 );
} }
static inline int futex_wake( const LONG *addr, int val ) static inline int futex_wake( const LONG *addr, int val )
{ {
return syscall( __NR_futex, addr, FUTEX_WAKE | futex_private, val, NULL, 0, 0 ); return syscall( __NR_futex, addr, FUTEX_WAKE_PRIVATE, val, NULL, 0, 0 );
}
static inline int use_futexes(void)
{
static LONG supported = -1;
if (supported == -1)
{
futex_wait( &supported, 10, NULL );
if (errno == ENOSYS)
{
futex_private = 0;
futex_wait( &supported, 10, NULL );
}
supported = (errno != ENOSYS);
}
return supported;
} }
#endif #endif
@ -2356,11 +2336,10 @@ union tid_alert_entry
{ {
#ifdef HAVE_KQUEUE #ifdef HAVE_KQUEUE
int kq; int kq;
#elif defined(__linux__)
LONG futex;
#else #else
HANDLE event; HANDLE event;
#ifdef __linux__
LONG futex;
#endif
#endif #endif
}; };
@ -2426,12 +2405,9 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
if (InterlockedCompareExchange( (LONG *)&entry->kq, kq, 0 )) if (InterlockedCompareExchange( (LONG *)&entry->kq, kq, 0 ))
close( kq ); close( kq );
} }
#elif defined(__linux__)
return entry;
#else #else
#ifdef __linux__
if (use_futexes())
return entry;
#endif
if (!entry->event) if (!entry->event)
{ {
HANDLE event; HANDLE event;
@ -2473,17 +2449,14 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
kevent( entry->kq, &signal_event, 1, NULL, 0, NULL ); kevent( entry->kq, &signal_event, 1, NULL, 0, NULL );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#else #elif defined(__linux__)
#ifdef __linux__
if (use_futexes())
{ {
LONG *futex = &entry->futex; LONG *futex = &entry->futex;
if (!InterlockedExchange( futex, 1 )) if (!InterlockedExchange( futex, 1 ))
futex_wake( futex, 1 ); futex_wake( futex, 1 );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#endif #else
return NtSetEvent( entry->event, NULL ); return NtSetEvent( entry->event, NULL );
#endif #endif
} }
@ -2571,14 +2544,12 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout )
{ {
union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread ); union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread );
NTSTATUS status;
TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
if (!entry) return STATUS_INVALID_CID; if (!entry) return STATUS_INVALID_CID;
#ifdef __linux__ #ifdef __linux__
if (use_futexes())
{ {
LONG *futex = &entry->futex; LONG *futex = &entry->futex;
ULONGLONG end; ULONGLONG end;
@ -2610,11 +2581,13 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
} }
return STATUS_ALERTED; return STATUS_ALERTED;
} }
#else
{
NTSTATUS status = NtWaitForSingleObject( entry->event, FALSE, timeout );
if (!status) return STATUS_ALERTED;
return status;
}
#endif #endif
status = NtWaitForSingleObject( entry->event, FALSE, timeout );
if (!status) return STATUS_ALERTED;
return status;
} }
#endif #endif