From: Rémi Bernon rbernon@codeweavers.com
This improves performance of unix calls a little by removing one level of indirection and a branch. --- dlls/win32u/Makefile.in | 2 +- dlls/winecrt0/unix_lib.c | 34 +++++++++++++++++----------------- include/wine/unixlib.h | 5 +++-- 3 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index 692b2d5c9f2..ba6915d91d8 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DWINE_NO_LONG_TYPES MODULE = win32u.dll UNIXLIB = win32u.so IMPORTLIB = win32u -IMPORTS = ntdll winecrt0 +IMPORTS = winecrt0 ntdll UNIX_CFLAGS = $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) UNIX_LIBS = $(CARBON_LIBS) $(APPKIT_LIBS) $(PTHREAD_LIBS) -lm
diff --git a/dlls/winecrt0/unix_lib.c b/dlls/winecrt0/unix_lib.c index c86897b9905..1926fb8d36b 100644 --- a/dlls/winecrt0/unix_lib.c +++ b/dlls/winecrt0/unix_lib.c @@ -29,28 +29,28 @@ #include "winternl.h" #include "wine/unixlib.h"
-static NTSTATUS (WINAPI *p__wine_unix_call)( unixlib_handle_t, unsigned int, void * ); - -static void load_func( void **func, const char *name, void *def ) -{ - if (!*func) - { - HMODULE module = GetModuleHandleW( L"ntdll.dll" ); - void *proc = GetProcAddress( module, name ); - InterlockedExchangePointer( func, proc ? proc : def ); - } -} -#define LOAD_FUNC(name) load_func( (void **)&p ## name, #name, fallback ## name ) - -static NTSTATUS __cdecl fallback__wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ) +static NTSTATUS WINAPI fallback__wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ) { return STATUS_DLL_NOT_FOUND; }
-NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ) +static NTSTATUS WINAPI delayload__wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ) { - LOAD_FUNC( __wine_unix_call ); - return p__wine_unix_call( handle, code, args ); + UNICODE_STRING ntdll_str; + ANSI_STRING name_str; + HMODULE module; + void *proc; + + RtlInitUnicodeString( &ntdll_str, L"ntdll.dll" ); + RtlInitAnsiString( &name_str, "__wine_unix_call" ); + + if (LdrGetDllHandleEx( LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL, &ntdll_str, &module )) proc = NULL; + else if (LdrGetProcedureAddress( module, &name_str, 0, &proc )) proc = NULL; + InterlockedExchangePointer( (void *)&__wine_unix_call, proc ? proc : (void *)fallback__wine_unix_call ); + + return __wine_unix_call( handle, code, args ); }
+NTSTATUS (WINAPI *__wine_unix_call)( unixlib_handle_t, unsigned int, void * ) = delayload__wine_unix_call; + #endif /* __WINE_PE_BUILD */ diff --git a/include/wine/unixlib.h b/include/wine/unixlib.h index ef60b32184c..bde7bfc3e72 100644 --- a/include/wine/unixlib.h +++ b/include/wine/unixlib.h @@ -24,10 +24,11 @@ typedef NTSTATUS (*unixlib_entry_t)( void *args ); typedef UINT64 unixlib_handle_t;
+#ifndef WINE_UNIX_LIB +extern NTSTATUS (WINAPI *__wine_unix_call)( unixlib_handle_t handle, unsigned int code, void *args ); +#else extern NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args );
-#ifdef WINE_UNIX_LIB - /* some useful helpers from ntdll */ extern const char *ntdll_get_build_dir(void); extern const char *ntdll_get_data_dir(void);