[PATCH] ntdll: Optimize synchronization primitives.

Joshua Ashton joshua at froggi.es
Wed Apr 1 02:21:51 CDT 2020


Thanks, I applied this patch and the sink that was trapped on my kitchen
ceiling fell off! Finally, freedom at last! Nothing else was able to remove
it...
Now I have zero overhead sinks in my kitchen.

- Josh 🐸

On Wed, 1 Apr 2020 at 06:14, Zebediah Figura <z.figura12 at gmail.com> wrote:

> After spending nearly two years trying to figure out how to implement
> synchronization primitives in a correct and performant manner, I've finally
> developed a solution which is not only simple and straightforward, but an
> amazing 100% more performant than current Wine!
>
> I've nicknamed this patch "zsync", short for "zero-overhead sync". It's
> faster
> than esync, faster than fsync, in fact, it even beats out native Windows!
>
> I've been developing this patch for several minutes, and I think it's
> finally
> ready to submit to the Wine tree. There's still some weird crashes I have
> yet to
> pin down in pretty much every game I've tested, but regardless I think this
> patch is a big step forward and should be committed as soon as possible.
> ---
>  dlls/ntdll/sync.c | 75 ++++++++---------------------------------------
>  1 file changed, 13 insertions(+), 62 deletions(-)
>
> diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
> index 2b5b6ce44a5..b5c0ecfcd55 100644
> --- a/dlls/ntdll/sync.c
> +++ b/dlls/ntdll/sync.c
> @@ -328,18 +328,8 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle,
> SEMAPHORE_INFORMATION_CLASS cla
>   */
>  NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG
> previous )
>  {
> -    NTSTATUS ret;
> -    SERVER_START_REQ( release_semaphore )
> -    {
> -        req->handle = wine_server_obj_handle( handle );
> -        req->count  = count;
> -        if (!(ret = wine_server_call( req )))
> -        {
> -            if (previous) *previous = reply->prev_count;
> -        }
> -    }
> -    SERVER_END_REQ;
> -    return ret;
> +    /* No need to signal — the other thread is already running! */
> +    return STATUS_SUCCESS;
>  }
>
>  /*
> @@ -405,16 +395,8 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle,
> ACCESS_MASK access, const OBJECT_AT
>   */
>  NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state )
>  {
> -    NTSTATUS ret;
> -    SERVER_START_REQ( event_op )
> -    {
> -        req->handle = wine_server_obj_handle( handle );
> -        req->op     = SET_EVENT;
> -        ret = wine_server_call( req );
> -        if (!ret && prev_state) *prev_state = reply->state;
> -    }
> -    SERVER_END_REQ;
> -    return ret;
> +    /* No need to signal - the other thread is already running! */
> +    return STATUS_SUCCESS;
>  }
>
>
>  /******************************************************************************
> @@ -422,16 +404,8 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG
> *prev_state )
>   */
>  NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state )
>  {
> -    NTSTATUS ret;
> -    SERVER_START_REQ( event_op )
> -    {
> -        req->handle = wine_server_obj_handle( handle );
> -        req->op     = RESET_EVENT;
> -        ret = wine_server_call( req );
> -        if (!ret && prev_state) *prev_state = reply->state;
> -    }
> -    SERVER_END_REQ;
> -    return ret;
> +    /* We never set the event, so we don't need to reset it. */
> +    return STATUS_SUCCESS;
>  }
>
>
>  /******************************************************************************
> @@ -453,17 +427,8 @@ NTSTATUS WINAPI NtClearEvent ( HANDLE handle )
>   */
>  NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state )
>  {
> -    NTSTATUS ret;
> -
> -    SERVER_START_REQ( event_op )
> -    {
> -        req->handle = wine_server_obj_handle( handle );
> -        req->op     = PULSE_EVENT;
> -        ret = wine_server_call( req );
> -        if (!ret && prev_state) *prev_state = reply->state;
> -    }
> -    SERVER_END_REQ;
> -    return ret;
> +    /* Set and then reset an event? We might as well just do nothing. */
> +    return STATUS_SUCCESS;
>  }
>
>
>  /******************************************************************************
> @@ -564,16 +529,8 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle,
> ACCESS_MASK access, const OBJECT_A
>   */
>  NTSTATUS WINAPI NtReleaseMutant( IN HANDLE handle, OUT PLONG prev_count
> OPTIONAL)
>  {
> -    NTSTATUS    status;
> -
> -    SERVER_START_REQ( release_mutex )
> -    {
> -        req->handle = wine_server_obj_handle( handle );
> -        status = wine_server_call( req );
> -        if (prev_count) *prev_count = 1 - reply->prev_count;
> -    }
> -    SERVER_END_REQ;
> -    return status;
> +    /* There'll be no mutant enemy, we shall certify. */
> +    return STATUS_SUCCESS;
>  }
>
>  /******************************************************************
> @@ -1076,15 +1033,9 @@ static NTSTATUS wait_objects( DWORD count, const
> HANDLE *handles,
>                                BOOLEAN wait_any, BOOLEAN alertable,
>                                const LARGE_INTEGER *timeout )
>  {
> -    select_op_t select_op;
> -    UINT i, flags = SELECT_INTERRUPTIBLE;
> -
> -    if (!count || count > MAXIMUM_WAIT_OBJECTS) return
> STATUS_INVALID_PARAMETER_1;
> -
> -    if (alertable) flags |= SELECT_ALERTABLE;
> -    select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
> -    for (i = 0; i < count; i++) select_op.wait.handles[i] =
> wine_server_obj_handle( handles[i] );
> -    return server_select( &select_op, offsetof( select_op_t,
> wait.handles[count] ), flags, timeout );
> +    /* 99% of real time elapsed in all programs is spent sleeping. We can
> +     * optimize by not doing that. */
> +    return STATUS_SUCCESS;
>  }
>
>
> --
> 2.26.0
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200401/e19c26aa/attachment.htm>


More information about the wine-devel mailing list