[PATCH] ntdll: Wake one waiter in RtlWakeAddressSingle in futex path.

Zebediah Figura z.figura12 at gmail.com
Mon Sep 9 23:03:56 CDT 2019


Hello Daniel,

On 9/9/19 10:39 PM, Daniel Lehman wrote:
> Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
> ---
>   dlls/ntdll/sync.c     | 10 ++++-----
>   dlls/ntdll/tests/om.c | 48 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 53 insertions(+), 5 deletions(-)
> 
> diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
> index 35b89df52e..88fb979b2c 100644
> --- a/dlls/ntdll/sync.c
> +++ b/dlls/ntdll/sync.c
> @@ -2416,7 +2416,7 @@ static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T
>       return STATUS_SUCCESS;
>   }
>   
> -static inline NTSTATUS fast_wake_addr( const void *addr )
> +static inline NTSTATUS fast_wake_addr( const void *addr, int waiters )
>   {
>       int *futex;
>   
> @@ -2427,7 +2427,7 @@ static inline NTSTATUS fast_wake_addr( const void *addr )
>   
>       interlocked_xchg_add( futex, 1 );
>   
> -    futex_wake( futex, INT_MAX );
> +    futex_wake( futex, waiters );
>       return STATUS_SUCCESS;
>   }
>   #else
> @@ -2437,7 +2437,7 @@ static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T
>       return STATUS_NOT_IMPLEMENTED;
>   }
>   
> -static inline NTSTATUS fast_wake_addr( const void *addr )
> +static inline NTSTATUS fast_wake_addr( const void *addr, int waiters )
>   {
>       return STATUS_NOT_IMPLEMENTED;
>   }
> @@ -2518,7 +2518,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
>    */
>   void WINAPI RtlWakeAddressAll( const void *addr )
>   {
> -    if (fast_wake_addr( addr ) != STATUS_NOT_IMPLEMENTED)
> +    if (fast_wake_addr( addr, INT_MAX ) != STATUS_NOT_IMPLEMENTED)
>           return;
>   
>       RtlEnterCriticalSection( &addr_section );
> @@ -2531,7 +2531,7 @@ void WINAPI RtlWakeAddressAll( const void *addr )
>    */
>   void WINAPI RtlWakeAddressSingle( const void *addr )
>   {
> -    if (fast_wake_addr( addr ) != STATUS_NOT_IMPLEMENTED)
> +    if (fast_wake_addr( addr, 1 ) != STATUS_NOT_IMPLEMENTED)
>           return;
>   
>       RtlEnterCriticalSection( &addr_section );

Unfortunately, this can't work. We map multiple addresses to each futex, 
so this could result in waking up the wrong one, while the right one 
never wakes up.

Do you have an application that relies on this?

ἔρρωσο,
Zeb



More information about the wine-devel mailing list