2021-04-30 16:09:47 -07:00
|
|
|
From f910f81d3c8f3c01f7582738e61071ae7a24dfea Mon Sep 17 00:00:00 2001
|
2020-12-08 18:56:56 -08:00
|
|
|
From: Zebediah Figura <z.figura12@gmail.com>
|
2021-04-30 16:09:47 -07:00
|
|
|
Date: Fri, 30 Apr 2021 16:35:13 -0500
|
|
|
|
Subject: [PATCH] ntdll: Implement thread-ID alerts using futexes if possible.
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
|
|
|
---
|
2021-04-30 16:09:47 -07:00
|
|
|
dlls/ntdll/unix/sync.c | 76 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
1 file changed, 76 insertions(+)
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
2021-04-30 16:09:47 -07:00
|
|
|
index 014e5e5d0a7..058262ac0ad 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/unix/sync.c
|
|
|
|
+++ b/dlls/ntdll/unix/sync.c
|
2021-04-30 16:09:47 -07:00
|
|
|
@@ -2289,6 +2289,9 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
|
|
|
union tid_alert_entry
|
|
|
|
{
|
|
|
|
HANDLE event;
|
2020-12-08 18:56:56 -08:00
|
|
|
+#ifdef __linux__
|
2021-04-30 16:09:47 -07:00
|
|
|
+ int futex;
|
|
|
|
+#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry))
|
|
|
|
@@ -2323,6 +2326,11 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
|
|
|
|
|
|
|
|
entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE];
|
|
|
|
|
|
|
|
+#ifdef __linux__
|
|
|
|
+ if (use_futexes())
|
|
|
|
+ return entry;
|
2020-12-08 18:56:56 -08:00
|
|
|
+#endif
|
2021-04-30 16:09:47 -07:00
|
|
|
+
|
|
|
|
if (!entry->event)
|
|
|
|
{
|
|
|
|
HANDLE event;
|
|
|
|
@@ -2348,10 +2356,43 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
|
|
|
|
|
|
|
if (!entry) return STATUS_INVALID_CID;
|
|
|
|
|
|
|
|
+#ifdef __linux__
|
|
|
|
+ if (use_futexes())
|
|
|
|
+ {
|
|
|
|
+ int *futex = &entry->futex;
|
|
|
|
+ if (!InterlockedExchange( futex, 1 ))
|
|
|
|
+ futex_wake( futex, 1 );
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
return NtSetEvent( entry->event, NULL );
|
2020-12-08 18:56:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-30 16:09:47 -07:00
|
|
|
+#ifdef __linux__
|
2020-12-08 18:56:56 -08:00
|
|
|
+static LONGLONG get_absolute_timeout( const LARGE_INTEGER *timeout )
|
|
|
|
+{
|
|
|
|
+ LARGE_INTEGER now;
|
|
|
|
+
|
|
|
|
+ if (timeout->QuadPart >= 0) return timeout->QuadPart;
|
|
|
|
+ NtQuerySystemTime( &now );
|
|
|
|
+ return now.QuadPart - timeout->QuadPart;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static LONGLONG update_timeout( ULONGLONG end )
|
|
|
|
+{
|
|
|
|
+ LARGE_INTEGER now;
|
|
|
|
+ LONGLONG timeleft;
|
|
|
|
+
|
|
|
|
+ NtQuerySystemTime( &now );
|
|
|
|
+ timeleft = end - now.QuadPart;
|
|
|
|
+ if (timeleft < 0) timeleft = 0;
|
|
|
|
+ return timeleft;
|
|
|
|
+}
|
2021-04-30 16:09:47 -07:00
|
|
|
+#endif
|
2020-12-08 18:56:56 -08:00
|
|
|
+
|
|
|
|
+
|
|
|
|
/***********************************************************************
|
|
|
|
* NtWaitForAlertByThreadId (NTDLL.@)
|
|
|
|
*/
|
2021-04-30 16:09:47 -07:00
|
|
|
@@ -2364,6 +2405,41 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
|
|
|
|
|
|
|
if (!entry) return STATUS_INVALID_CID;
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
+#ifdef __linux__
|
|
|
|
+ if (use_futexes())
|
|
|
|
+ {
|
2021-04-30 16:09:47 -07:00
|
|
|
+ int *futex = &entry->futex;
|
2020-12-08 18:56:56 -08:00
|
|
|
+ ULONGLONG end;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ if (timeout)
|
|
|
|
+ {
|
|
|
|
+ if (timeout->QuadPart == TIMEOUT_INFINITE)
|
|
|
|
+ timeout = NULL;
|
|
|
|
+ else
|
|
|
|
+ end = get_absolute_timeout( timeout );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ while (!InterlockedExchange( futex, 0 ))
|
|
|
|
+ {
|
|
|
|
+ if (timeout)
|
|
|
|
+ {
|
|
|
|
+ LONGLONG timeleft = update_timeout( end );
|
|
|
|
+ struct timespec timespec;
|
|
|
|
+
|
|
|
|
+ timespec.tv_sec = timeleft / (ULONGLONG)TICKSPERSEC;
|
|
|
|
+ timespec.tv_nsec = (timeleft % TICKSPERSEC) * 100;
|
|
|
|
+ ret = futex_wait( futex, 0, ×pec );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ ret = futex_wait( futex, 0, NULL );
|
|
|
|
+
|
|
|
|
+ if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT;
|
|
|
|
+ }
|
|
|
|
+ return STATUS_ALERTED;
|
|
|
|
+ }
|
|
|
|
+#endif
|
2021-04-30 16:09:47 -07:00
|
|
|
+
|
|
|
|
status = NtWaitForSingleObject( entry->event, FALSE, timeout );
|
|
|
|
if (!status) return STATUS_ALERTED;
|
|
|
|
return status;
|
2020-12-08 18:56:56 -08:00
|
|
|
--
|
2021-04-30 16:09:47 -07:00
|
|
|
2.30.2
|
2020-12-08 18:56:56 -08:00
|
|
|
|