diff --git a/patches/ntdll-CLI_Images/0001-ntdll-Load-CLI-.NET-images-in-the-same-way-as-Window.patch b/patches/ntdll-CLI_Images/0001-ntdll-Load-CLI-.NET-images-in-the-same-way-as-Window.patch index 3181f6b9..e2b8920b 100644 --- a/patches/ntdll-CLI_Images/0001-ntdll-Load-CLI-.NET-images-in-the-same-way-as-Window.patch +++ b/patches/ntdll-CLI_Images/0001-ntdll-Load-CLI-.NET-images-in-the-same-way-as-Window.patch @@ -1,4 +1,4 @@ -From 16bb8ba07739f3c189920cdbf56f87aa520456c0 Mon Sep 17 00:00:00 2001 +From f4024fac3fba56c007fa873a66271eef4f6c31ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Wed, 1 Apr 2015 04:34:20 +0200 Subject: ntdll: Load CLI/.NET images in the same way as Windows XP and above. @@ -9,7 +9,7 @@ Subject: ntdll: Load CLI/.NET images in the same way as Windows XP and above. 2 files changed, 133 insertions(+), 10 deletions(-) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c -index 2c8074b..5810080 100644 +index 1cd6e47..4d985d4 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1079,16 +1079,11 @@ static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry ) @@ -33,11 +33,11 @@ index 2c8074b..5810080 100644 ERR( "%s doesn't have an entry point, it cannot be executed\n", debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) ); diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c -index 9810f07..18f20fe 100644 +index bef0ab1..2dd8ad0 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -97,6 +97,10 @@ static UINT tls_module_count; /* number of modules with TLS directory */ - static const IMAGE_TLS_DIRECTORY **tls_dirs; /* array of TLS directories */ + static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */ LIST_ENTRY tls_links = { &tls_links, &tls_links }; +static HRESULT (WINAPI *p_CorValidateImage)(PVOID* ImageBase, LPCWSTR FileName); @@ -126,7 +126,7 @@ index 9810f07..18f20fe 100644 * get_modref * * Looks for the referenced HMODULE in the current process -@@ -863,6 +939,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path ) +@@ -868,6 +944,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path ) if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */ wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; @@ -137,7 +137,7 @@ index 9810f07..18f20fe 100644 wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr ); if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE, -@@ -1058,8 +1138,43 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved +@@ -1063,8 +1143,43 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved BOOL retv = FALSE; /* Skip calls for modules loaded with special load flags */ @@ -182,7 +182,7 @@ index 9810f07..18f20fe 100644 if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason ); if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return STATUS_SUCCESS; -@@ -2865,7 +2980,20 @@ static void load_global_options(void) +@@ -2870,7 +2985,20 @@ static void load_global_options(void) */ static void start_process( void *kernel_start ) { @@ -205,5 +205,5 @@ index 9810f07..18f20fe 100644 /****************************************************************** -- -2.3.3 +2.4.5 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 86ea1ec9..0082eb1c 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -55,7 +55,7 @@ version() echo "Copyright (C) 2014-2015 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" - echo " commit a8f45dff604058d419bd6c2e070f65a13a6ddfdb" + echo " commit 22f28d2923811b85024f63ce43e41966a864ecd0" echo "" } @@ -203,7 +203,6 @@ patch_enable_all () enable_server_RootDirectory_File="$1" enable_server_Shared_Memory="$1" enable_server_Stored_ACLs="$1" - enable_server_Unexpected_Wakeup="$1" enable_setupapi_SetupDiSelectBestCompatDrv="$1" enable_setupapi_SetupDiSetDeviceInstallParamsW="$1" enable_setupapi_SetupPromptForDisk="$1" @@ -678,9 +677,6 @@ patch_enable () server-Stored_ACLs) enable_server_Stored_ACLs="$2" ;; - server-Unexpected_Wakeup) - enable_server_Unexpected_Wakeup="$2" - ;; setupapi-SetupDiSelectBestCompatDrv) enable_setupapi_SetupDiSelectBestCompatDrv="$2" ;; @@ -1407,9 +1403,6 @@ if test "$enable_category_stable" -eq 1; then if test "$enable_server_Delete_On_Close" -gt 1; then abort "Patchset server-Delete_On_Close disabled, but category-stable depends on that." fi - if test "$enable_server_Unexpected_Wakeup" -gt 1; then - abort "Patchset server-Unexpected_Wakeup disabled, but category-stable depends on that." - fi if test "$enable_setupapi_SetupDiSetDeviceInstallParamsW" -gt 1; then abort "Patchset setupapi-SetupDiSetDeviceInstallParamsW disabled, but category-stable depends on that." fi @@ -1538,7 +1531,6 @@ if test "$enable_category_stable" -eq 1; then enable_server_ClipCursor=1 enable_server_CreateProcess_ACLs=1 enable_server_Delete_On_Close=1 - enable_server_Unexpected_Wakeup=1 enable_setupapi_SetupDiSetDeviceInstallParamsW=1 enable_shell32_RunDLL_CallEntry16=1 enable_shell32_SHFileOperation=1 @@ -4115,20 +4107,6 @@ if test "$enable_server_Shared_Memory" -eq 1; then ) >> "$patchlist" fi -# Patchset server-Unexpected_Wakeup -# | -# | Modified files: -# | * dlls/kernel32/tests/sync.c, server/thread.c -# | -if test "$enable_server_Unexpected_Wakeup" -eq 1; then - patch_apply server-Unexpected_Wakeup/0001-server-Avoid-sending-unexpected-wakeup-with-uninitia.patch - patch_apply server-Unexpected_Wakeup/0002-kernel32-tests-Repeat-test-for-SignalObjectAndWait-m.patch - ( - echo '+ { "Sebastian Lackner", "server: Avoid sending unexpected wakeup with uninitialized cookie value.", 1 },'; - echo '+ { "Sebastian Lackner", "kernel32/tests: Repeat test for SignalObjectAndWait multiple times to test wineserver wakeup cookie management.", 1 },'; - ) >> "$patchlist" -fi - # Patchset setupapi-SetupDiSelectBestCompatDrv # | # | This patchset fixes the following Wine bugs: @@ -4513,31 +4491,32 @@ fi # | * [#31640] Implement various vcomp functions # | # | Modified files: -# | * configure.ac, dlls/vcomp/main.c, dlls/vcomp/tests/Makefile.in, dlls/vcomp/tests/vcomp.c, -# | dlls/vcomp/tests/vcomp.manifest, dlls/vcomp/tests/vcomp.rc, dlls/vcomp/vcomp.spec, dlls/vcomp100/vcomp100.spec, -# | dlls/vcomp90/vcomp90.spec +# | * configure.ac, dlls/vcomp/main.c, dlls/vcomp/tests/Makefile.in, dlls/vcomp/tests/vcomp.c, dlls/vcomp/vcomp.spec, +# | dlls/vcomp100/vcomp100.spec, dlls/vcomp90/vcomp90.spec # | if test "$enable_vcomp_Functions" -eq 1; then patch_apply vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch - patch_apply vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch - patch_apply vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch - patch_apply vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch - patch_apply vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch - patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch - patch_apply vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch - patch_apply vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch - patch_apply vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch - patch_apply vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch - patch_apply vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch + patch_apply vcomp-Functions/0002-vcomp-Add-multithreaded-implementation-for-_vcomp_fo.patch + patch_apply vcomp-Functions/0003-vcomp-Implement-_vcomp_barrier.patch + patch_apply vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch + patch_apply vcomp-Functions/0005-vcomp-tests-Add-additional-tests-for-_vcomp_fork.patch + patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch + patch_apply vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch + patch_apply vcomp-Functions/0008-vcomp-Implement-_vcomp_for_static_init.patch + patch_apply vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch + patch_apply vcomp-Functions/0010-vcomp-Implement-omp_in_parallel.patch + patch_apply vcomp-Functions/0011-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch + patch_apply vcomp-Functions/0012-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch ( echo '+ { "Dan Kegel", "vcomp: Implement stub for _vcomp_fork.", 1 },'; - echo '+ { "Sebastian Lackner", "vcomp: Add basic worker thread infrastructure.", 1 },'; - echo '+ { "Dan Kegel", "vcomp/tests: Add initial tests for _vcomp_fork.", 1 },'; + echo '+ { "Sebastian Lackner", "vcomp: Add multithreaded implementation for _vcomp_fork.", 1 },'; + echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_barrier.", 1 },'; + echo '+ { "Sebastian Lackner", "vcomp/tests: Add initial tests.", 1 },'; + echo '+ { "Dan Kegel", "vcomp/tests: Add additional tests for _vcomp_fork.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_simple_init and _vcomp_for_static_end.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_simple_init.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_init.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_init.", 1 },'; - echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_barrier.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp: Implement omp_in_parallel.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and add tests.", 1 },'; echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next and add tests.", 1 },'; diff --git a/patches/server-Unexpected_Wakeup/0001-server-Avoid-sending-unexpected-wakeup-with-uninitia.patch b/patches/server-Unexpected_Wakeup/0001-server-Avoid-sending-unexpected-wakeup-with-uninitia.patch deleted file mode 100644 index 3caac1a2..00000000 --- a/patches/server-Unexpected_Wakeup/0001-server-Avoid-sending-unexpected-wakeup-with-uninitia.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 9df06c6e4b4cf258b7f321dfd5e20467bef2b36f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 22 Nov 2014 17:42:22 +0100 -Subject: server: Avoid sending unexpected wakeup with uninitialized cookie - value. - -While executing the kernel32/sync tests I noticed a couple of unexpected wakeup cookies, which looked like uninitialized wineserver memory. -Here an excerpt from the log (added additional debug values): ---- - server/thread.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/server/thread.c b/server/thread.c -index ba3f1d5..bdd9ef7 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -601,6 +601,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj - wait->count = count; - wait->flags = flags; - wait->select = select_op->op; -+ wait->cookie = 0; - wait->user = NULL; - wait->timeout = timeout; - wait->abandoned = 0; -@@ -719,7 +720,7 @@ int wake_thread( struct thread *thread ) - cookie = thread->wait->cookie; - if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled ); - end_wait( thread ); -- if (send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */ -+ if (cookie && send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */ - { - if (!count) count = -1; - break; -@@ -749,7 +750,7 @@ int wake_thread_queue_entry( struct wait_queue_entry *entry ) - if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled ); - end_wait( thread ); - -- if (send_thread_wakeup( thread, cookie, signaled ) != -1) -+ if (!cookie || send_thread_wakeup( thread, cookie, signaled ) != -1) - wake_thread( thread ); /* check other waits too */ - - return 1; -@@ -768,6 +769,8 @@ static void thread_timeout( void *ptr ) - - if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=TIMEOUT\n", thread->id ); - end_wait( thread ); -+ -+ assert( cookie ); - if (send_thread_wakeup( thread, cookie, STATUS_TIMEOUT ) == -1) return; - /* check if other objects have become signaled in the meantime */ - wake_thread( thread ); -@@ -1429,6 +1432,12 @@ DECL_HANDLER(select) - set_error( STATUS_INVALID_PARAMETER ); - return; - } -+ if (!req->cookie) -+ { -+ set_error( STATUS_INVALID_PARAMETER ); -+ return; -+ } -+ - op_size = min( get_req_data_size() - sizeof(*result), sizeof(select_op) ); - memset( &select_op, 0, sizeof(select_op) ); - memcpy( &select_op, result + 1, op_size ); --- -2.1.3 - diff --git a/patches/server-Unexpected_Wakeup/0002-kernel32-tests-Repeat-test-for-SignalObjectAndWait-m.patch b/patches/server-Unexpected_Wakeup/0002-kernel32-tests-Repeat-test-for-SignalObjectAndWait-m.patch deleted file mode 100644 index 3718e5d5..00000000 --- a/patches/server-Unexpected_Wakeup/0002-kernel32-tests-Repeat-test-for-SignalObjectAndWait-m.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e8a0619c85e774abd866e3882038dee563007c77 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Tue, 16 Dec 2014 06:23:15 +0100 -Subject: kernel32/tests: Repeat test for SignalObjectAndWait multiple times to - test wineserver wakeup cookie management. - ---- - dlls/kernel32/tests/sync.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c -index cbe0acb..668b92d 100644 ---- a/dlls/kernel32/tests/sync.c -+++ b/dlls/kernel32/tests/sync.c -@@ -64,6 +64,7 @@ static void test_signalandwait(void) - HMODULE kernel32; - DWORD r; - HANDLE event[2], semaphore[2], file; -+ int i; - - kernel32 = GetModuleHandleA("kernel32.dll"); - pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait"); -@@ -96,9 +97,13 @@ static void test_signalandwait(void) - r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); - ok( r == WAIT_OBJECT_0, "should succeed\n"); - -- /* event[0] is now signalled */ -- r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); -- ok( r == WAIT_OBJECT_0, "should succeed\n"); -+ /* event[0] is now signalled - we repeat this test multiple times -+ * to ensure that the wineserver handles this situation properly. */ -+ for (i = 0; i < 10000; i++) -+ { -+ r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); -+ ok( r == WAIT_OBJECT_0, "should succeed\n"); -+ } - - /* event[0] is not signalled */ - r = WaitForSingleObject(event[0], 0); --- -2.1.3 - diff --git a/patches/server-Unexpected_Wakeup/definition b/patches/server-Unexpected_Wakeup/definition deleted file mode 100644 index 5d05f260..00000000 --- a/patches/server-Unexpected_Wakeup/definition +++ /dev/null @@ -1 +0,0 @@ -Category: stable diff --git a/patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch b/patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch index a567d1e5..3820f2f5 100644 --- a/patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch +++ b/patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch @@ -1,17 +1,20 @@ -From 6404654fd885acbf0e563d9b5070d321986b5b8d Mon Sep 17 00:00:00 2001 +From d0d4b3991b691ee74e999f82dbf57a5a400fe7db Mon Sep 17 00:00:00 2001 From: Dan Kegel -Date: Sat, 11 Jul 2015 06:50:26 +0200 +Date: Tue, 14 Jul 2015 21:40:36 +0200 Subject: vcomp: Implement stub for _vcomp_fork. +Changes: +* The original patch added a new file, I moved the implementation to main.c. +* A huge comment block was removed, tests are more reliable than comments anyway. ;) --- - dlls/vcomp/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/main.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ dlls/vcomp/vcomp.spec | 2 +- dlls/vcomp100/vcomp100.spec | 2 +- dlls/vcomp90/vcomp90.spec | 2 +- - 4 files changed, 96 insertions(+), 3 deletions(-) + 4 files changed, 98 insertions(+), 3 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index ab2a372..26f6c67 100644 +index 8ec3616..03c085b 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -3,6 +3,7 @@ @@ -22,24 +25,14 @@ index ab2a372..26f6c67 100644 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public -@@ -107,6 +108,98 @@ void CDECL _vcomp_single_end(void) - TRACE("stub\n"); - } +@@ -40,6 +41,89 @@ struct vcomp_thread_data + int fork_threads; + }; +void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + -+void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) -+{ -+ __ms_va_list valist; -+ -+ TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper); -+ -+ __ms_va_start(valist, wrapper); -+ _vcomp_fork_call_wrapper(wrapper, nargs, valist); -+ __ms_va_end(valist); -+} -+ +#if defined(__i386__) ++ +__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") @@ -109,6 +102,7 @@ index ab2a372..26f6c67 100644 + __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") + __ASM_CFI(".cfi_same_value %rbp\n\t") + "ret") ++ +#else + +void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args) @@ -118,9 +112,27 @@ index ab2a372..26f6c67 100644 + +#endif + - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) + static inline struct vcomp_thread_data *vcomp_get_thread_data(void) { - TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + return (struct vcomp_thread_data *)TlsGetValue(vcomp_context_tls); +@@ -160,6 +244,17 @@ void CDECL _vcomp_single_end(void) + TRACE("stub\n"); + } + ++void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) ++{ ++ __ms_va_list valist; ++ ++ TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper); ++ ++ __ms_va_start(valist, wrapper); ++ _vcomp_fork_call_wrapper(wrapper, nargs, valist); ++ __ms_va_end(valist); ++} ++ + BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) + { + TRACE("(%p, %d, %p)\n", instance, reason, reserved); diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 306dd15..d446574 100644 --- a/dlls/vcomp/vcomp.spec diff --git a/patches/vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch b/patches/vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch deleted file mode 100644 index 4ea96641..00000000 --- a/patches/vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch +++ /dev/null @@ -1,311 +0,0 @@ -From e3f58ae29d504bd1f2287566878b7d6674bd5484 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 11 Jul 2015 18:53:41 +0200 -Subject: vcomp: Add basic worker thread infrastructure. - ---- - dlls/vcomp/main.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 211 insertions(+), 10 deletions(-) - -diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index 26f6c67..9de9721 100644 ---- a/dlls/vcomp/main.c -+++ b/dlls/vcomp/main.c -@@ -4,6 +4,7 @@ - * - * Copyright 2011 Austin English - * Copyright 2012 Dan Kegel -+ * Copyright 2015 Sebastian Lackner - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -23,13 +24,68 @@ - #include "config.h" - - #include -+#include - - #include "windef.h" - #include "winbase.h" - #include "wine/debug.h" -+#include "wine/list.h" - - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - -+static HMODULE vcomp_module; -+static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads); -+static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES; -+static DWORD vcomp_max_threads = 32; -+static DWORD vcomp_num_threads = 1; -+ -+static RTL_CRITICAL_SECTION vcomp_section; -+static RTL_CRITICAL_SECTION_DEBUG critsect_debug = -+{ -+ 0, 0, &vcomp_section, -+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, -+ 0, 0, { (DWORD_PTR)(__FILE__ ": vcomp_section") } -+}; -+static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 }; -+ -+struct vcomp_thread_info -+{ -+ struct list entry; -+ CONDITION_VARIABLE cond; -+ -+ /* current task */ -+ struct vcomp_team_info *team; -+ DWORD thread_num; -+}; -+ -+struct vcomp_team_info -+{ -+ CONDITION_VARIABLE cond; -+ DWORD num_threads; -+ DWORD finished_threads; -+ -+ /* callback arguments */ -+ unsigned int nargs; -+ void *wrapper; -+ __ms_va_list valist; -+}; -+ -+static inline struct vcomp_thread_info *vcomp_get_thread_info(void) -+{ -+ return (struct vcomp_thread_info *)TlsGetValue(vcomp_context_tls); -+} -+ -+static inline struct vcomp_team_info *vcomp_get_team_info(void) -+{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ return thread_info ? thread_info->team : NULL; -+} -+ -+static inline void vcomp_set_thread_info(struct vcomp_thread_info *thread_info) -+{ -+ TlsSetValue(vcomp_context_tls, thread_info); -+} -+ - int CDECL omp_get_dynamic(void) - { - TRACE("stub\n"); -@@ -39,7 +95,7 @@ int CDECL omp_get_dynamic(void) - int CDECL omp_get_max_threads(void) - { - TRACE("stub\n"); -- return 1; -+ return vcomp_max_threads; - } - - int CDECL omp_get_nested(void) -@@ -56,14 +112,22 @@ int CDECL omp_get_num_procs(void) - - int CDECL omp_get_num_threads(void) - { -- TRACE("stub\n"); -- return 1; -+ struct vcomp_team_info *team_info; -+ -+ TRACE("()\n"); -+ -+ team_info = vcomp_get_team_info(); -+ return team_info ? team_info->num_threads : 1; - } - - int CDECL omp_get_thread_num(void) - { -- TRACE("stub\n"); -- return 0; -+ struct vcomp_thread_info *thread_info; -+ -+ TRACE("()\n"); -+ -+ thread_info = vcomp_get_thread_info(); -+ return thread_info ? thread_info->thread_num : 0; - } - - /* Time in seconds since "some time in the past" */ -@@ -85,6 +149,7 @@ void CDECL omp_set_nested(int nested) - void CDECL omp_set_num_threads(int num_threads) - { - TRACE("(%d): stub\n", num_threads); -+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads)); - } - - void CDECL _vcomp_barrier(void) -@@ -94,7 +159,8 @@ void CDECL _vcomp_barrier(void) - - void CDECL _vcomp_set_num_threads(int num_threads) - { -- TRACE("(%d): stub\n", num_threads); -+ TRACE("(%d)\n", num_threads); -+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads)); - } - - int CDECL _vcomp_single_begin(int flags) -@@ -110,15 +176,139 @@ void CDECL _vcomp_single_end(void) - - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); - -+static DWORD WINAPI _vcomp_fork_worker(void *param) -+{ -+ struct vcomp_thread_info *thread_info = param; -+ vcomp_set_thread_info(thread_info); -+ -+ TRACE("starting worker thread %p\n", thread_info); -+ -+ EnterCriticalSection(&vcomp_section); -+ for (;;) -+ { -+ struct vcomp_team_info *team = thread_info->team; -+ if (team != NULL) -+ { -+ /* Leave critical section and execute callback. */ -+ LeaveCriticalSection(&vcomp_section); -+ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist); -+ EnterCriticalSection(&vcomp_section); -+ -+ /* Detach current thread from team. */ -+ thread_info->team = NULL; -+ list_remove(&thread_info->entry); -+ list_add_tail(&vcomp_idle_threads, &thread_info->entry); -+ if (++team->finished_threads >= team->num_threads) -+ WakeAllConditionVariable(&team->cond); -+ } -+ -+ if (!SleepConditionVariableCS(&thread_info->cond, &vcomp_section, 5000) && -+ GetLastError() == ERROR_TIMEOUT && !thread_info->team) -+ { -+ break; -+ } -+ } -+ list_remove(&thread_info->entry); -+ LeaveCriticalSection(&vcomp_section); -+ -+ TRACE("terminating worker thread %p\n", thread_info); -+ HeapFree(GetProcessHeap(), 0, thread_info); -+ FreeLibraryAndExitThread(vcomp_module, 0); -+ return 0; -+} -+ - void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - { -- __ms_va_list valist; -+ struct vcomp_thread_info thread_info, *prev_thread_info; -+ struct vcomp_team_info team_info; -+ DWORD num_threads = vcomp_num_threads; /* FIXME */ -+ BOOL parallel = ifval; - - TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper); - -- __ms_va_start(valist, wrapper); -- _vcomp_fork_call_wrapper(wrapper, nargs, valist); -- __ms_va_end(valist); -+ /* Initialize members of team_info. */ -+ InitializeConditionVariable(&team_info.cond); -+ team_info.num_threads = 1; -+ team_info.finished_threads = 0; -+ team_info.nargs = nargs; -+ team_info.wrapper = wrapper; -+ __ms_va_start(team_info.valist, wrapper); -+ -+ /* Initialize members of thread_info. */ -+ list_init(&thread_info.entry); -+ InitializeConditionVariable(&thread_info.cond); -+ thread_info.team = &team_info; -+ thread_info.thread_num = 0; -+ -+ if (parallel) -+ { -+ struct list *ptr; -+ EnterCriticalSection(&vcomp_section); -+ -+ /* Try to reuse idle threads. */ -+ while (team_info.num_threads < num_threads && -+ (ptr = list_head( &vcomp_idle_threads ))) -+ { -+ struct vcomp_thread_info *info = LIST_ENTRY(ptr, struct vcomp_thread_info, entry); -+ list_remove(&info->entry); -+ list_add_tail(&thread_info.entry, &info->entry); -+ info->team = &team_info; -+ info->thread_num = team_info.num_threads++; -+ WakeAllConditionVariable(&info->cond); -+ } -+ -+ /* Spawn additional new threads. */ -+ while (team_info.num_threads < num_threads) -+ { -+ struct vcomp_thread_info *info; -+ HMODULE module; -+ HANDLE thread; -+ -+ info = HeapAlloc(GetProcessHeap(), 0, sizeof(*info)); -+ if (!info) break; -+ -+ InitializeConditionVariable(&info->cond); -+ info->team = &team_info; -+ info->thread_num = team_info.num_threads; -+ -+ thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL); -+ if (!thread) -+ { -+ HeapFree(GetProcessHeap(), 0, info); -+ break; -+ } -+ -+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, -+ (const WCHAR *)vcomp_module, &module); -+ -+ list_add_tail(&thread_info.entry, &info->entry); -+ team_info.num_threads++; -+ CloseHandle(thread); -+ } -+ -+ LeaveCriticalSection(&vcomp_section); -+ } -+ -+ /* Call the callback in the context of the new team. */ -+ prev_thread_info = vcomp_get_thread_info(); -+ vcomp_set_thread_info(&thread_info); -+ _vcomp_fork_call_wrapper(team_info.wrapper, team_info.nargs, team_info.valist); -+ vcomp_set_thread_info(prev_thread_info); -+ -+ /* Implicit join, wait for other tasks. */ -+ if (parallel) -+ { -+ EnterCriticalSection(&vcomp_section); -+ -+ team_info.finished_threads++; -+ while (team_info.finished_threads < team_info.num_threads) -+ SleepConditionVariableCS(&team_info.cond, &vcomp_section, INFINITE); -+ -+ LeaveCriticalSection(&vcomp_section); -+ assert(list_empty(&thread_info.entry)); -+ } -+ -+ __ms_va_end(team_info.valist); - } - - #if defined(__i386__) -@@ -208,8 +398,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ -+ - case DLL_PROCESS_ATTACH: -+ vcomp_module = hinstDLL; - DisableThreadLibraryCalls(hinstDLL); -+ if ((vcomp_context_tls = TlsAlloc()) == TLS_OUT_OF_INDEXES) -+ { -+ ERR("Failed to allocate TLS index\n"); -+ return FALSE; -+ } -+ break; -+ -+ case DLL_PROCESS_DETACH: -+ TlsFree(vcomp_context_tls); - break; - } - --- -2.4.5 - diff --git a/patches/vcomp-Functions/0002-vcomp-Add-multithreaded-implementation-for-_vcomp_fo.patch b/patches/vcomp-Functions/0002-vcomp-Add-multithreaded-implementation-for-_vcomp_fo.patch new file mode 100644 index 00000000..ebfd8a66 --- /dev/null +++ b/patches/vcomp-Functions/0002-vcomp-Add-multithreaded-implementation-for-_vcomp_fo.patch @@ -0,0 +1,259 @@ +From 6f76d9a3a8a11bc4f6d3e6ddba1fcb9a856d0b2f Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 14 Jul 2015 21:41:10 +0200 +Subject: vcomp: Add multithreaded implementation for _vcomp_fork. + +--- + dlls/vcomp/main.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 172 insertions(+), 8 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 03c085b..20aeb4f 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -4,6 +4,7 @@ + * + * Copyright 2011 Austin English + * Copyright 2012 Dan Kegel ++ * Copyright 2015 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -23,22 +24,52 @@ + #include "config.h" + + #include ++#include + + #include "windef.h" + #include "winbase.h" + #include "wine/debug.h" ++#include "wine/list.h" + + WINE_DEFAULT_DEBUG_CHANNEL(vcomp); + ++static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads); + static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES; ++static HMODULE vcomp_module; + static int vcomp_max_threads; + static int vcomp_num_threads; + static BOOL vcomp_nested_fork = FALSE; + ++static RTL_CRITICAL_SECTION vcomp_section; ++static RTL_CRITICAL_SECTION_DEBUG critsect_debug = ++{ ++ 0, 0, &vcomp_section, ++ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, ++ 0, 0, { (DWORD_PTR)(__FILE__ ": vcomp_section") } ++}; ++static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 }; ++ + struct vcomp_thread_data + { ++ struct vcomp_team_data *team; + int thread_num; + int fork_threads; ++ ++ /* only used for concurrent tasks */ ++ struct list entry; ++ CONDITION_VARIABLE cond; ++}; ++ ++struct vcomp_team_data ++{ ++ CONDITION_VARIABLE cond; ++ int num_threads; ++ int finished_threads; ++ ++ /* callback arguments */ ++ int nargs; ++ void *wrapper; ++ __ms_va_list valist; + }; + + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); +@@ -145,8 +176,9 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void) + ExitProcess(1); + } + +- thread_data->thread_num = 0; +- thread_data->fork_threads = 0; ++ thread_data->team = NULL; ++ thread_data->thread_num = 0; ++ thread_data->fork_threads = 0; + + vcomp_set_thread_data(thread_data); + return thread_data; +@@ -187,8 +219,9 @@ int CDECL omp_get_num_procs(void) + + int CDECL omp_get_num_threads(void) + { +- TRACE("stub\n"); +- return 1; ++ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team; ++ TRACE("()\n"); ++ return team_data ? team_data->num_threads : 1; + } + + int CDECL omp_get_thread_num(void) +@@ -244,15 +277,145 @@ void CDECL _vcomp_single_end(void) + TRACE("stub\n"); + } + ++static DWORD WINAPI _vcomp_fork_worker(void *param) ++{ ++ struct vcomp_thread_data *thread_data = param; ++ vcomp_set_thread_data(thread_data); ++ ++ TRACE("starting worker thread for %p\n", thread_data); ++ ++ EnterCriticalSection(&vcomp_section); ++ for (;;) ++ { ++ struct vcomp_team_data *team = thread_data->team; ++ if (team != NULL) ++ { ++ LeaveCriticalSection(&vcomp_section); ++ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist); ++ EnterCriticalSection(&vcomp_section); ++ ++ thread_data->team = NULL; ++ list_remove(&thread_data->entry); ++ list_add_tail(&vcomp_idle_threads, &thread_data->entry); ++ if (++team->finished_threads >= team->num_threads) ++ WakeAllConditionVariable(&team->cond); ++ } ++ ++ if (!SleepConditionVariableCS(&thread_data->cond, &vcomp_section, 5000) && ++ GetLastError() == ERROR_TIMEOUT && !thread_data->team) ++ { ++ break; ++ } ++ } ++ list_remove(&thread_data->entry); ++ LeaveCriticalSection(&vcomp_section); ++ ++ TRACE("terminating worker thread for %p\n", thread_data); ++ ++ HeapFree(GetProcessHeap(), 0, thread_data); ++ vcomp_set_thread_data(NULL); ++ FreeLibraryAndExitThread(vcomp_module, 0); ++ return 0; ++} ++ + void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + { +- __ms_va_list valist; ++ struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data(); ++ struct vcomp_thread_data thread_data; ++ struct vcomp_team_data team_data; ++ int num_threads; + + TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper); + +- __ms_va_start(valist, wrapper); +- _vcomp_fork_call_wrapper(wrapper, nargs, valist); +- __ms_va_end(valist); ++ if (!ifval) ++ num_threads = 1; ++ else if (prev_thread_data->team && !vcomp_nested_fork) ++ num_threads = 1; ++ else if (prev_thread_data->fork_threads) ++ num_threads = prev_thread_data->fork_threads; ++ else ++ num_threads = vcomp_num_threads; ++ ++ InitializeConditionVariable(&team_data.cond); ++ team_data.num_threads = 1; ++ team_data.finished_threads = 0; ++ team_data.nargs = nargs; ++ team_data.wrapper = wrapper; ++ __ms_va_start(team_data.valist, wrapper); ++ ++ thread_data.team = &team_data; ++ thread_data.thread_num = 0; ++ thread_data.fork_threads = 0; ++ list_init(&thread_data.entry); ++ InitializeConditionVariable(&thread_data.cond); ++ ++ if (num_threads > 1) ++ { ++ struct list *ptr; ++ EnterCriticalSection(&vcomp_section); ++ ++ /* reuse existing threads (if any) */ ++ while (team_data.num_threads < num_threads && (ptr = list_head(&vcomp_idle_threads))) ++ { ++ struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry); ++ data->team = &team_data; ++ data->thread_num = team_data.num_threads++; ++ data->fork_threads = 0; ++ list_remove(&data->entry); ++ list_add_tail(&thread_data.entry, &data->entry); ++ WakeAllConditionVariable(&data->cond); ++ } ++ ++ /* spawn additional threads */ ++ while (team_data.num_threads < num_threads) ++ { ++ struct vcomp_thread_data *data; ++ HMODULE module; ++ HANDLE thread; ++ ++ data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); ++ if (!data) break; ++ ++ data->team = &team_data; ++ data->thread_num = team_data.num_threads; ++ data->fork_threads = 0; ++ InitializeConditionVariable(&data->cond); ++ ++ thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL); ++ if (!thread) ++ { ++ HeapFree(GetProcessHeap(), 0, data); ++ break; ++ } ++ ++ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, ++ (const WCHAR *)vcomp_module, &module); ++ team_data.num_threads++; ++ list_add_tail(&thread_data.entry, &data->entry); ++ CloseHandle(thread); ++ } ++ ++ LeaveCriticalSection(&vcomp_section); ++ } ++ ++ vcomp_set_thread_data(&thread_data); ++ _vcomp_fork_call_wrapper(team_data.wrapper, team_data.nargs, team_data.valist); ++ vcomp_set_thread_data(prev_thread_data); ++ prev_thread_data->fork_threads = 0; ++ ++ if (team_data.num_threads > 1) ++ { ++ EnterCriticalSection(&vcomp_section); ++ ++ team_data.finished_threads++; ++ while (team_data.finished_threads < team_data.num_threads) ++ SleepConditionVariableCS(&team_data.cond, &vcomp_section, INFINITE); ++ ++ LeaveCriticalSection(&vcomp_section); ++ assert(list_empty(&thread_data.entry)); ++ } ++ ++ __ms_va_end(team_data.valist); + } + + BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) +@@ -275,6 +438,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) + } + + GetSystemInfo(&sysinfo); ++ vcomp_module = instance; + vcomp_max_threads = sysinfo.dwNumberOfProcessors; + vcomp_num_threads = sysinfo.dwNumberOfProcessors; + break; +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0003-vcomp-Implement-_vcomp_barrier.patch b/patches/vcomp-Functions/0003-vcomp-Implement-_vcomp_barrier.patch new file mode 100644 index 00000000..8a6ef1e1 --- /dev/null +++ b/patches/vcomp-Functions/0003-vcomp-Implement-_vcomp_barrier.patch @@ -0,0 +1,65 @@ +From 5990968a0ae43fd6f4a4001107ef5d4fcc273458 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 14 Jul 2015 21:41:27 +0200 +Subject: vcomp: Implement _vcomp_barrier. + +--- + dlls/vcomp/main.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 20aeb4f..bcaa4ea 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -70,6 +70,10 @@ struct vcomp_team_data + int nargs; + void *wrapper; + __ms_va_list valist; ++ ++ /* barrier */ ++ unsigned int barrier; ++ int barrier_count; + }; + + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); +@@ -256,7 +260,27 @@ void CDECL omp_set_num_threads(int num_threads) + + void CDECL _vcomp_barrier(void) + { +- TRACE("stub\n"); ++ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team; ++ ++ TRACE("()\n"); ++ ++ if (!team_data) ++ return; ++ ++ EnterCriticalSection(&vcomp_section); ++ if (++team_data->barrier_count >= team_data->num_threads) ++ { ++ team_data->barrier++; ++ team_data->barrier_count = 0; ++ WakeAllConditionVariable(&team_data->cond); ++ } ++ else ++ { ++ unsigned int barrier = team_data->barrier; ++ while (team_data->barrier == barrier) ++ SleepConditionVariableCS(&team_data->cond, &vcomp_section, INFINITE); ++ } ++ LeaveCriticalSection(&vcomp_section); + } + + void CDECL _vcomp_set_num_threads(int num_threads) +@@ -342,6 +366,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + team_data.nargs = nargs; + team_data.wrapper = wrapper; + __ms_va_start(team_data.valist, wrapper); ++ team_data.barrier = 0; ++ team_data.barrier_count = 0; + + thread_data.team = &team_data; + thread_data.thread_num = 0; +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch b/patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch deleted file mode 100644 index a27f62ce..00000000 --- a/patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 92cd559115925b61b980a784efacb0ccdd7029d0 Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Sat, 11 Jul 2015 03:56:04 +0200 -Subject: vcomp/tests: Add initial tests for _vcomp_fork. - ---- - configure.ac | 3 +- - dlls/vcomp/tests/Makefile.in | 7 +++ - dlls/vcomp/tests/vcomp.c | 122 ++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/tests/vcomp.manifest | 21 +++++++ - dlls/vcomp/tests/vcomp.rc | 22 ++++++++ - 5 files changed, 174 insertions(+), 1 deletion(-) - create mode 100644 dlls/vcomp/tests/Makefile.in - create mode 100644 dlls/vcomp/tests/vcomp.c - create mode 100644 dlls/vcomp/tests/vcomp.manifest - create mode 100644 dlls/vcomp/tests/vcomp.rc - -diff --git a/configure.ac b/configure.ac -index 3eaec29..a36fc4b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3321,7 +3321,8 @@ WINE_CONFIG_DLL(uxtheme,,[implib]) - WINE_CONFIG_TEST(dlls/uxtheme/tests) - WINE_CONFIG_DLL(vbscript,,[clean]) - WINE_CONFIG_TEST(dlls/vbscript/tests,[clean]) --WINE_CONFIG_DLL(vcomp) -+WINE_CONFIG_DLL(vcomp,,[implib]) -+WINE_CONFIG_TEST(dlls/vcomp/tests) - WINE_CONFIG_DLL(vcomp100) - WINE_CONFIG_DLL(vcomp90) - WINE_CONFIG_DLL(vdhcp.vxd,enable_win16) -diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in -new file mode 100644 -index 0000000..08a5b7f ---- /dev/null -+++ b/dlls/vcomp/tests/Makefile.in -@@ -0,0 +1,7 @@ -+TESTDLL = vcomp.dll -+ -+C_SRCS = \ -+ vcomp.c -+ -+RC_SRCS = \ -+ vcomp.rc -diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c -new file mode 100644 -index 0000000..5c6a861 ---- /dev/null -+++ b/dlls/vcomp/tests/vcomp.c -@@ -0,0 +1,122 @@ -+/* -+ * Unit test suite for vcomp fork/join implementation -+ * -+ * Copyright 2012 Dan Kegel -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "wine/test.h" -+ -+static const int is_win64 = (sizeof(void *) > sizeof(int)); -+ -+static HMODULE hvcomp = 0; -+static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); -+static int (CDECL *pomp_get_max_threads)(void); -+ -+#define VCOMP_GET_PROC(func) \ -+ do \ -+ { \ -+ p ## func = (void *)GetProcAddress(hvcomp, #func); \ -+ if (!p ## func) trace("Failed to get address for %s\n", #func); \ -+ } \ -+ while (0) -+ -+static BOOL init_vcomp(void) -+{ -+ hvcomp = LoadLibraryA("vcomp.dll"); -+ if (!hvcomp) -+ { -+ win_skip("vcomp.dll not installed\n"); -+ return FALSE; -+ } -+ -+ VCOMP_GET_PROC(_vcomp_fork); -+ VCOMP_GET_PROC(omp_get_max_threads); -+ -+ return TRUE; -+} -+ -+#undef VCOMP_GET_PROC -+ -+static void CDECL _test_vcomp_fork_ptr(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e) -+{ -+ InterlockedIncrement(a); -+ InterlockedIncrement(b); -+ InterlockedIncrement(c); -+ InterlockedIncrement(d); -+ InterlockedIncrement(e); -+} -+ -+static void CDECL _test_vcomp_fork_uintptr(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e) -+{ -+ ok(a == 1, "expected a = 1, got %p\n", (void *)a); -+ ok(b == MAXUINT_PTR - 2, "expected b = MAXUINT_PTR - 2, got %p\n", (void *)b); -+ ok(c == 3, "expected c = 3, got %p\n", (void *)c); -+ ok(d == MAXUINT_PTR - 4, "expected d = MAXUINT_PTR - 4, got %p\n", (void *)d); -+ ok(e == 5, "expected e = 5, got %p\n", (void *)e); -+} -+ -+static void CDECL _test_vcomp_fork_float(float a, float b, float c, float d, float e) -+{ -+ ok(1.4999 < a && a < 1.5001, "expected a = 1.5, got %f\n", a); -+ ok(2.4999 < b && b < 2.5001, "expected b = 2.5, got %f\n", b); -+ ok(3.4999 < c && c < 3.5001, "expected c = 3.5, got %f\n", c); -+ ok(4.4999 < d && d < 4.5001, "expected d = 4.5, got %f\n", d); -+ ok(5.4999 < e && e < 5.5001, "expected e = 5.5, got %f\n", e); -+} -+ -+static void test_vcomp_fork(void) -+{ -+ LONG a, b, c, d, e; -+ int n = pomp_get_max_threads(); -+ -+ a = 0; b = 1; c = 2; d = 3; e = 4; -+ p_vcomp_fork(FALSE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e); -+ ok(a == 1, "expected a = 1, got %u\n", a); -+ ok(b == 2, "expected b = 2, got %u\n", b); -+ ok(c == 3, "expected c = 3, got %u\n", c); -+ ok(d == 4, "expected d = 4, got %u\n", d); -+ ok(e == 5, "expected e = 5, got %u\n", e); -+ -+ a = 0; b = 1; c = 2; d = 3; e = 4; -+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e); -+ ok(a > 0 && a <= (n + 0), "expected a > 0 && a <= (n + 0), got %u\n", a); -+ ok(b > 1 && b <= (n + 1), "expected b > 1 && b <= (n + 1), got %u\n", b); -+ ok(c > 2 && c <= (n + 2), "expected c > 2 && c <= (n + 2), got %u\n", c); -+ ok(d > 3 && d <= (n + 3), "expected d > 3 && d <= (n + 3), got %u\n", d); -+ ok(e > 4 && e <= (n + 4), "expected e > 4 && e <= (n + 4), got %u\n", e); -+ -+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_uintptr, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2), -+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5); -+ -+ if (is_win64) -+ skip("skipping float test on x86_64\n"); -+ else -+ { -+ void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork; -+ func(TRUE, 5, _test_vcomp_fork_float, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f); -+ } -+} -+ -+START_TEST(vcomp) -+{ -+ if (!init_vcomp()) -+ return; -+ -+ test_vcomp_fork(); -+ -+ FreeLibrary(hvcomp); -+} -diff --git a/dlls/vcomp/tests/vcomp.manifest b/dlls/vcomp/tests/vcomp.manifest -new file mode 100644 -index 0000000..6c8bd91 ---- /dev/null -+++ b/dlls/vcomp/tests/vcomp.manifest -@@ -0,0 +1,21 @@ -+ -+ -+ -+Wine vcomp test suite -+ -+ -+ -+ -+ -+ -diff --git a/dlls/vcomp/tests/vcomp.rc b/dlls/vcomp/tests/vcomp.rc -new file mode 100644 -index 0000000..c5f1d25 ---- /dev/null -+++ b/dlls/vcomp/tests/vcomp.rc -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (c) 2012 Dan Kegel -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "winuser.h" -+ -+/* @makedep: vcomp.manifest */ -+1 RT_MANIFEST vcomp.manifest --- -2.4.5 - diff --git a/patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch b/patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch new file mode 100644 index 00000000..93476ef0 --- /dev/null +++ b/patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch @@ -0,0 +1,338 @@ +From 01b14a9059e5a0ade1818046b03546adc0002bde Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 14 Jul 2015 21:42:11 +0200 +Subject: vcomp/tests: Add initial tests. + +The only way to get the tests pass on all testbot machines was to dynamically +create a manifest file. Without manifest file, the vcomp library cannot be found +on all machines > Win2000, with manifest file as resource the Windows loader is +not able to load the executable for testbots without vcrun2005. +--- + configure.ac | 1 + + dlls/vcomp/tests/Makefile.in | 4 + + dlls/vcomp/tests/vcomp.c | 290 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 295 insertions(+) + create mode 100644 dlls/vcomp/tests/Makefile.in + create mode 100644 dlls/vcomp/tests/vcomp.c + +diff --git a/configure.ac b/configure.ac +index 3eaec29..f15a17a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3322,6 +3322,7 @@ WINE_CONFIG_TEST(dlls/uxtheme/tests) + WINE_CONFIG_DLL(vbscript,,[clean]) + WINE_CONFIG_TEST(dlls/vbscript/tests,[clean]) + WINE_CONFIG_DLL(vcomp) ++WINE_CONFIG_TEST(dlls/vcomp/tests) + WINE_CONFIG_DLL(vcomp100) + WINE_CONFIG_DLL(vcomp90) + WINE_CONFIG_DLL(vdhcp.vxd,enable_win16) +diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in +new file mode 100644 +index 0000000..d1b7b12 +--- /dev/null ++++ b/dlls/vcomp/tests/Makefile.in +@@ -0,0 +1,4 @@ ++TESTDLL = vcomp.dll ++ ++C_SRCS = \ ++ vcomp.c +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +new file mode 100644 +index 0000000..b084791 +--- /dev/null ++++ b/dlls/vcomp/tests/vcomp.c +@@ -0,0 +1,290 @@ ++/* ++ * Unit test suite for vcomp ++ * ++ * Copyright 2015 Sebastian Lackner ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "wine/test.h" ++ ++static char vcomp_manifest_file[MAX_PATH]; ++static HANDLE vcomp_actctx_hctx; ++static ULONG_PTR vcomp_actctx_cookie; ++static HMODULE vcomp_handle; ++ ++static HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*); ++static BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*); ++static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR); ++static VOID (WINAPI *pReleaseActCtx)(HANDLE); ++ ++static void (CDECL *p_vcomp_barrier)(void); ++static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); ++static void (CDECL *p_vcomp_set_num_threads)(int num_threads); ++static int (CDECL *pomp_get_max_threads)(void); ++static int (CDECL *pomp_get_nested)(void); ++static int (CDECL *pomp_get_num_threads)(void); ++static int (CDECL *pomp_get_thread_num)(void); ++static void (CDECL *pomp_set_nested)(int nested); ++static void (CDECL *pomp_set_num_threads)(int num_threads); ++ ++#ifdef __i386__ ++#define ARCH "x86" ++#elif defined(__x86_64__) ++#define ARCH "amd64" ++#else ++#define ARCH "none" ++#endif ++ ++static const char vcomp_manifest[] = ++ "\n" ++ "\n" ++ " \n" ++ "Wine vcomp test suite\n" ++ "\n" ++ " \n" ++ " \n" ++ " \n" ++ "\n" ++ "\n"; ++ ++#undef ARCH ++ ++static void create_vcomp_manifest(void) ++{ ++ char temp_path[MAX_PATH]; ++ HMODULE kernel32; ++ DWORD written; ++ ACTCTXA ctx; ++ HANDLE file; ++ ++ kernel32 = GetModuleHandleA("kernel32.dll"); ++ pCreateActCtxA = (void *)GetProcAddress(kernel32, "CreateActCtxA"); ++ pActivateActCtx = (void *)GetProcAddress(kernel32, "ActivateActCtx"); ++ pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx"); ++ pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx"); ++ if (!pCreateActCtxA) return; ++ ++ if (!GetTempPathA(sizeof(temp_path), temp_path) || ++ !GetTempFileNameA(temp_path, "vcomp", 0, vcomp_manifest_file)) ++ { ++ ok(0, "failed to create manifest file\n"); ++ return; ++ } ++ ++ file = CreateFileA(vcomp_manifest_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); ++ if (file == INVALID_HANDLE_VALUE) ++ { ++ ok(0, "failed to open manifest file\n"); ++ return; ++ } ++ ++ if (!WriteFile(file, vcomp_manifest, sizeof(vcomp_manifest) - 1, &written, NULL)) ++ written = 0; ++ CloseHandle(file); ++ ++ if (written != sizeof(vcomp_manifest) - 1) ++ { ++ ok(0, "failed to write manifest file\n"); ++ DeleteFileA(vcomp_manifest_file); ++ return; ++ } ++ ++ memset(&ctx, 0, sizeof(ctx)); ++ ctx.cbSize = sizeof(ctx); ++ ctx.lpSource = vcomp_manifest_file; ++ vcomp_actctx_hctx = pCreateActCtxA(&ctx); ++ if (!vcomp_actctx_hctx) ++ { ++ ok(0, "failed to create activation context\n"); ++ DeleteFileA(vcomp_manifest_file); ++ return; ++ } ++ ++ if (!pActivateActCtx(vcomp_actctx_hctx, &vcomp_actctx_cookie)) ++ { ++ win_skip("failed to activate context\n"); ++ pReleaseActCtx(vcomp_actctx_hctx); ++ DeleteFileA(vcomp_manifest_file); ++ vcomp_actctx_hctx = NULL; ++ } ++} ++ ++static void release_vcomp(void) ++{ ++ if (vcomp_handle) ++ FreeLibrary(vcomp_handle); ++ ++ if (vcomp_actctx_hctx) ++ { ++ pDeactivateActCtx(0, vcomp_actctx_cookie); ++ pReleaseActCtx(vcomp_actctx_hctx); ++ DeleteFileA(vcomp_manifest_file); ++ } ++} ++ ++#define VCOMP_GET_PROC(func) \ ++ do \ ++ { \ ++ p ## func = (void *)GetProcAddress(vcomp_handle, #func); \ ++ if (!p ## func) trace("Failed to get address for %s\n", #func); \ ++ } \ ++ while (0) ++ ++static BOOL init_vcomp(void) ++{ ++ create_vcomp_manifest(); ++ ++ vcomp_handle = LoadLibraryA("vcomp.dll"); ++ if (!vcomp_handle) ++ { ++ win_skip("vcomp.dll not installed\n"); ++ release_vcomp(); ++ return FALSE; ++ } ++ ++ VCOMP_GET_PROC(_vcomp_barrier); ++ VCOMP_GET_PROC(_vcomp_fork); ++ VCOMP_GET_PROC(_vcomp_set_num_threads); ++ VCOMP_GET_PROC(omp_get_max_threads); ++ VCOMP_GET_PROC(omp_get_nested); ++ VCOMP_GET_PROC(omp_get_num_threads); ++ VCOMP_GET_PROC(omp_get_thread_num); ++ VCOMP_GET_PROC(omp_set_nested); ++ VCOMP_GET_PROC(omp_set_num_threads); ++ ++ return TRUE; ++} ++ ++#undef VCOMP_GET_PROC ++ ++static void CDECL num_threads_cb2(LONG *count) ++{ ++ InterlockedIncrement(count); ++} ++ ++static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count) ++{ ++ int num_threads, thread_num; ++ LONG thread_count; ++ ++ InterlockedIncrement(count); ++ p_vcomp_barrier(); ++ ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == *count, "expected num_threads == %d, got %d\n", *count, num_threads); ++ thread_num = pomp_get_thread_num(); ++ ok(thread_num >= 0 && thread_num < num_threads, ++ "expected thread_num in range [0, %d], got %d\n", num_threads - 1, thread_num); ++ ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count); ++ if (nested) ++ ok(thread_count == nested_threads, "expected %d thread, got %d\n", nested_threads, thread_count); ++ else ++ ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count); ++ ++ p_vcomp_set_num_threads(4); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count); ++ if (nested) ++ ok(thread_count == 4 , "expected 4 thread, got %d\n", thread_count); ++ else ++ ok(thread_count == 1 , "expected 1 thread, got %d\n", thread_count); ++} ++ ++static void test_omp_get_num_threads(BOOL nested) ++{ ++ int is_nested, max_threads, num_threads, thread_num; ++ LONG thread_count; ++ ++ pomp_set_nested(nested); ++ is_nested = pomp_get_nested(); ++ ok(is_nested == nested, "expected %d, got %d\n", nested, is_nested); ++ ++ max_threads = pomp_get_max_threads(); ++ ok(max_threads >= 1, "expected max_threads >= 1, got %d\n", max_threads); ++ thread_num = pomp_get_thread_num(); ++ ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num); ++ ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, max_threads, &thread_count); ++ ok(thread_count == max_threads, "expected %d threads, got %d\n", max_threads, thread_count); ++ ++ pomp_set_num_threads(2); ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 2, &thread_count); ++ ok(thread_count == 2, "expected 2 threads, got %d\n", thread_count); ++ ++ pomp_set_num_threads(4); ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count); ++ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count); ++ ++ p_vcomp_set_num_threads(8); ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count); ++ ok(thread_count == 8, "expected 8 threads, got %d\n", thread_count); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count); ++ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count); ++ ++ p_vcomp_set_num_threads(0); ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count); ++ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count); ++ ++ pomp_set_num_threads(0); ++ num_threads = pomp_get_num_threads(); ++ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads); ++ thread_count = 0; ++ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count); ++ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count); ++ ++ pomp_set_num_threads(max_threads); ++ pomp_set_nested(FALSE); ++} ++ ++START_TEST(vcomp) ++{ ++ if (!init_vcomp()) ++ return; ++ ++ test_omp_get_num_threads(FALSE); ++ test_omp_get_num_threads(TRUE); ++ ++ release_vcomp(); ++} +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0005-vcomp-tests-Add-additional-tests-for-_vcomp_fork.patch b/patches/vcomp-Functions/0005-vcomp-tests-Add-additional-tests-for-_vcomp_fork.patch new file mode 100644 index 00000000..0e25b531 --- /dev/null +++ b/patches/vcomp-Functions/0005-vcomp-tests-Add-additional-tests-for-_vcomp_fork.patch @@ -0,0 +1,107 @@ +From e9d9801b549a73db5666c51c14200aeca63725b4 Mon Sep 17 00:00:00 2001 +From: Dan Kegel +Date: Tue, 14 Jul 2015 21:42:31 +0200 +Subject: vcomp/tests: Add additional tests for _vcomp_fork. + +Changes: +* The number of threads is now set to 4 before running the tests. +* Some functions were renamed. +* All fork tests are now in a single test_*() function. +* Various ok(...) messages were improved. +--- + dlls/vcomp/tests/vcomp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index b084791..a9b975d 100644 +--- a/dlls/vcomp/tests/vcomp.c ++++ b/dlls/vcomp/tests/vcomp.c +@@ -1,6 +1,7 @@ + /* + * Unit test suite for vcomp + * ++ * Copyright 2012 Dan Kegel + * Copyright 2015 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or +@@ -278,6 +279,69 @@ static void test_omp_get_num_threads(BOOL nested) + pomp_set_nested(FALSE); + } + ++static void CDECL fork_ptr_cb(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e) ++{ ++ InterlockedIncrement(a); ++ InterlockedIncrement(b); ++ InterlockedIncrement(c); ++ InterlockedIncrement(d); ++ InterlockedIncrement(e); ++} ++ ++static void CDECL fork_uintptr_cb(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e) ++{ ++ ok(a == 1, "expected a == 1, got %p\n", (void *)a); ++ ok(b == MAXUINT_PTR - 2, "expected b == MAXUINT_PTR - 2, got %p\n", (void *)b); ++ ok(c == 3, "expected c == 3, got %p\n", (void *)c); ++ ok(d == MAXUINT_PTR - 4, "expected d == MAXUINT_PTR - 4, got %p\n", (void *)d); ++ ok(e == 5, "expected e == 5, got %p\n", (void *)e); ++} ++ ++static void CDECL fork_float_cb(float a, float b, float c, float d, float e) ++{ ++ ok(1.4999 < a && a < 1.5001, "expected a == 1.5, got %f\n", a); ++ ok(2.4999 < b && b < 2.5001, "expected b == 2.5, got %f\n", b); ++ ok(3.4999 < c && c < 3.5001, "expected c == 3.5, got %f\n", c); ++ ok(4.4999 < d && d < 4.5001, "expected d == 4.5, got %f\n", d); ++ ok(5.4999 < e && e < 5.5001, "expected e == 5.5, got %f\n", e); ++} ++ ++static void test_vcomp_fork(void) ++{ ++ LONG a, b, c, d, e; ++ int max_threads = pomp_get_max_threads(); ++ pomp_set_num_threads(4); ++ ++ a = 0; b = 1; c = 2; d = 3; e = 4; ++ p_vcomp_fork(FALSE, 5, fork_ptr_cb, &a, &b, &c, &d, &e); ++ ok(a == 1, "expected a == 1, got %d\n", a); ++ ok(b == 2, "expected b == 2, got %d\n", b); ++ ok(c == 3, "expected c == 3, got %d\n", c); ++ ok(d == 4, "expected d == 4, got %d\n", d); ++ ok(e == 5, "expected e == 5, got %d\n", e); ++ ++ a = 0; b = 1; c = 2; d = 3; e = 4; ++ p_vcomp_fork(TRUE, 5, fork_ptr_cb, &a, &b, &c, &d, &e); ++ ok(a == 4, "expected a == 4, got %d\n", a); ++ ok(b == 5, "expected b == 5, got %d\n", b); ++ ok(c == 6, "expected c == 6, got %d\n", c); ++ ok(d == 7, "expected d == 7, got %d\n", d); ++ ok(e == 8, "expected e == 8, got %d\n", e); ++ ++ p_vcomp_fork(TRUE, 5, fork_uintptr_cb, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2), ++ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5); ++ ++ if (sizeof(int) < sizeof(void *)) ++ skip("skipping float test on x86_64\n"); ++ else ++ { ++ void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork; ++ func(TRUE, 5, fork_float_cb, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f); ++ } ++ ++ pomp_set_num_threads(max_threads); ++} ++ + START_TEST(vcomp) + { + if (!init_vcomp()) +@@ -285,6 +349,7 @@ START_TEST(vcomp) + + test_omp_get_num_threads(FALSE); + test_omp_get_num_threads(TRUE); ++ test_vcomp_fork(); + + release_vcomp(); + } +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch b/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch similarity index 91% rename from patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch rename to patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch index 0341780b..40b9545d 100644 --- a/patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch +++ b/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch @@ -1,4 +1,4 @@ -From f455eb53b0d527874fb95bdc652d1a31cd8fa93a Mon Sep 17 00:00:00 2001 +From 7b64b41a512320a89e7758db43343ebe99c0f563 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 18:59:41 +0200 Subject: vcomp: Implement _vcomp_for_static_simple_init and @@ -12,25 +12,25 @@ Subject: vcomp: Implement _vcomp_for_static_simple_init and 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index 9de9721..400f93a 100644 +index bcaa4ea..fcbd747 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c -@@ -174,6 +174,96 @@ void CDECL _vcomp_single_end(void) +@@ -301,6 +301,96 @@ void CDECL _vcomp_single_end(void) TRACE("stub\n"); } +void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step, BOOL forward, + unsigned int *begin, unsigned int *end) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_init_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + unsigned int iterations, per_thread, remaining; + DWORD num_threads, thread_num; + + TRACE("(%d, %d, %d, %d, %p, %p)\n", first, last, step, forward, begin, end); + -+ num_threads = team_info->num_threads; -+ thread_num = thread_info->thread_num; ++ num_threads = team_data->num_threads; ++ thread_num = thread_data->thread_num; + + if (num_threads == 1) + { @@ -109,9 +109,9 @@ index 9de9721..400f93a 100644 + TRACE("()\n"); +} + - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); - static DWORD WINAPI _vcomp_fork_worker(void *param) + { + struct vcomp_thread_data *thread_data = param; diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index d446574..b14edca 100644 --- a/dlls/vcomp/vcomp.spec diff --git a/patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch b/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch similarity index 88% rename from patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch rename to patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch index ef66aca8..a7e5079c 100644 --- a/patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch +++ b/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch @@ -1,49 +1,37 @@ -From af8411c2c51708c2edbc620b3d775bf5a08144f9 Mon Sep 17 00:00:00 2001 +From 656f0051550426759e8f6ab287391bbe6a168418 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 05:12:39 +0200 Subject: vcomp/tests: Add tests for _vcomp_for_static_simple_init. --- - dlls/vcomp/tests/vcomp.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 228 insertions(+) + dlls/vcomp/tests/vcomp.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 220 insertions(+) diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c -index 5c6a861..1971b6d 100644 +index a9b975d..34c1ebc 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c -@@ -23,8 +23,15 @@ - static const int is_win64 = (sizeof(void *) > sizeof(int)); +@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR); + static VOID (WINAPI *pReleaseActCtx)(HANDLE); - static HMODULE hvcomp = 0; -+static void (CDECL *p_vcomp_barrier)(void); + static void (CDECL *p_vcomp_barrier)(void); +static void (CDECL *p_vcomp_for_static_end)(void); +static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step, + BOOL forward, unsigned int *begin, unsigned int *end); static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); + static void (CDECL *p_vcomp_set_num_threads)(int num_threads); static int (CDECL *pomp_get_max_threads)(void); -+static int (CDECL *pomp_get_num_threads)(void); -+static int (CDECL *pomp_get_thread_num)(void); -+static void (CDECL *pomp_set_num_threads)(int num_threads); - - #define VCOMP_GET_PROC(func) \ - do \ -@@ -43,8 +50,14 @@ static BOOL init_vcomp(void) - return FALSE; +@@ -168,6 +171,8 @@ static BOOL init_vcomp(void) } -+ VCOMP_GET_PROC(_vcomp_barrier); + VCOMP_GET_PROC(_vcomp_barrier); + VCOMP_GET_PROC(_vcomp_for_static_end); + VCOMP_GET_PROC(_vcomp_for_static_simple_init); VCOMP_GET_PROC(_vcomp_fork); + VCOMP_GET_PROC(_vcomp_set_num_threads); VCOMP_GET_PROC(omp_get_max_threads); -+ VCOMP_GET_PROC(omp_get_num_threads); -+ VCOMP_GET_PROC(omp_get_thread_num); -+ VCOMP_GET_PROC(omp_set_num_threads); - - return TRUE; - } -@@ -111,12 +124,227 @@ static void test_vcomp_fork(void) - } +@@ -342,6 +347,220 @@ static void test_vcomp_fork(void) + pomp_set_num_threads(max_threads); } +static void CDECL _test_vcomp_for_static_simple_init(void) @@ -263,12 +251,13 @@ index 5c6a861..1971b6d 100644 START_TEST(vcomp) { if (!init_vcomp()) - return; - +@@ -350,6 +569,7 @@ START_TEST(vcomp) + test_omp_get_num_threads(FALSE); + test_omp_get_num_threads(TRUE); test_vcomp_fork(); + test_vcomp_for_static_simple_init(); - FreeLibrary(hvcomp); + release_vcomp(); } -- 2.4.5 diff --git a/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch b/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch deleted file mode 100644 index cdf7f380..00000000 --- a/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 8732b345bcab27edc68eda1ab35095d72a817899 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 11 Jul 2015 19:38:24 +0200 -Subject: vcomp: Implement _vcomp_barrier. - ---- - dlls/vcomp/main.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index 2eeea3b..4f3471a 100644 ---- a/dlls/vcomp/main.c -+++ b/dlls/vcomp/main.c -@@ -68,6 +68,10 @@ struct vcomp_team_info - unsigned int nargs; - void *wrapper; - __ms_va_list valist; -+ -+ /* barrier */ -+ DWORD barrier; -+ DWORD barrier_count; - }; - - static inline struct vcomp_thread_info *vcomp_get_thread_info(void) -@@ -154,7 +158,28 @@ void CDECL omp_set_num_threads(int num_threads) - - void CDECL _vcomp_barrier(void) - { -- TRACE("stub\n"); -+ struct vcomp_team_info *team_info; -+ -+ TRACE("()\n"); -+ -+ team_info = vcomp_get_team_info(); -+ EnterCriticalSection(&vcomp_section); -+ -+ team_info->barrier_count++; -+ if (team_info->barrier_count >= team_info->num_threads) -+ { -+ team_info->barrier++; -+ team_info->barrier_count = 0; -+ WakeAllConditionVariable(&team_info->cond); -+ } -+ else -+ { -+ DWORD barrier = team_info->barrier; -+ while (team_info->barrier == barrier) -+ SleepConditionVariableCS(&team_info->cond, &vcomp_section, INFINITE); -+ } -+ -+ LeaveCriticalSection(&vcomp_section); - } - - void CDECL _vcomp_set_num_threads(int num_threads) -@@ -385,6 +410,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - team_info.nargs = nargs; - team_info.wrapper = wrapper; - __ms_va_start(team_info.valist, wrapper); -+ team_info.barrier = 0; -+ team_info.barrier_count = 0; - - /* Initialize members of thread_info. */ - list_init(&thread_info.entry); --- -2.4.5 - diff --git a/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch b/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_for_static_init.patch similarity index 91% rename from patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch rename to patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_for_static_init.patch index 115b0567..bd407745 100644 --- a/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch +++ b/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_for_static_init.patch @@ -1,4 +1,4 @@ -From 721c89ed7aec4a9ae8f0a5f7b0efeee838c08985 Mon Sep 17 00:00:00 2001 +From ed0734ad10de657efb30ec7c851d20d20ba79a0a Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 19:19:00 +0200 Subject: vcomp: Implement _vcomp_for_static_init. @@ -11,26 +11,26 @@ Subject: vcomp: Implement _vcomp_for_static_init. 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index 400f93a..2eeea3b 100644 +index fcbd747..b22dd37 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c -@@ -259,6 +259,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, +@@ -386,6 +386,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, } } +void CDECL _vcomp_for_static_init(int first, int last, int step, int chunksize, unsigned int *loops, + int *begin, int *end, int *next, int *lastchunk) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + unsigned int iterations, num_chunks, per_thread, remaining; + DWORD num_threads, thread_num; + + TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p)\n", + first, last, step, chunksize, loops, begin, end, next, lastchunk); + -+ num_threads = team_info->num_threads; -+ thread_num = thread_info->thread_num; ++ num_threads = team_data->num_threads; ++ thread_num = thread_data->thread_num; + + if (chunksize < 1) + chunksize = 1; diff --git a/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch b/patches/vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch similarity index 95% rename from patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch rename to patches/vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch index 847e319f..9dfddf2e 100644 --- a/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch +++ b/patches/vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch @@ -1,4 +1,4 @@ -From 9cea1ba140eb5d8ecd70eab4a68e309cd80fd454 Mon Sep 17 00:00:00 2001 +From 39cd9028667159d38193fca46691b7cdbc0fe82b Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 06:08:08 +0200 Subject: vcomp/tests: Add tests for _vcomp_for_static_init. @@ -8,11 +8,11 @@ Subject: vcomp/tests: Add tests for _vcomp_for_static_init. 1 file changed, 199 insertions(+) diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c -index 1971b6d..96806fd 100644 +index 34c1ebc..0103af1 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c -@@ -25,6 +25,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int)); - static HMODULE hvcomp = 0; +@@ -33,6 +33,8 @@ static VOID (WINAPI *pReleaseActCtx)(HANDLE); + static void (CDECL *p_vcomp_barrier)(void); static void (CDECL *p_vcomp_for_static_end)(void); +static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops, @@ -20,15 +20,15 @@ index 1971b6d..96806fd 100644 static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step, BOOL forward, unsigned int *begin, unsigned int *end); static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); -@@ -52,6 +54,7 @@ static BOOL init_vcomp(void) +@@ -172,6 +174,7 @@ static BOOL init_vcomp(void) VCOMP_GET_PROC(_vcomp_barrier); VCOMP_GET_PROC(_vcomp_for_static_end); + VCOMP_GET_PROC(_vcomp_for_static_init); VCOMP_GET_PROC(_vcomp_for_static_simple_init); VCOMP_GET_PROC(_vcomp_fork); - VCOMP_GET_PROC(omp_get_max_threads); -@@ -338,6 +341,201 @@ static void test_vcomp_for_static_simple_init(void) + VCOMP_GET_PROC(_vcomp_set_num_threads); +@@ -561,6 +564,201 @@ static void test_vcomp_for_static_simple_init(void) } } @@ -230,13 +230,13 @@ index 1971b6d..96806fd 100644 START_TEST(vcomp) { if (!init_vcomp()) -@@ -345,6 +543,7 @@ START_TEST(vcomp) - +@@ -570,6 +768,7 @@ START_TEST(vcomp) + test_omp_get_num_threads(TRUE); test_vcomp_fork(); test_vcomp_for_static_simple_init(); + test_vcomp_for_static_init(); - FreeLibrary(hvcomp); + release_vcomp(); } -- 2.4.5 diff --git a/patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch b/patches/vcomp-Functions/0010-vcomp-Implement-omp_in_parallel.patch similarity index 87% rename from patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch rename to patches/vcomp-Functions/0010-vcomp-Implement-omp_in_parallel.patch index a18082b9..a2080897 100644 --- a/patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch +++ b/patches/vcomp-Functions/0010-vcomp-Implement-omp_in_parallel.patch @@ -1,4 +1,4 @@ -From aad24232add010020898eaa1a0934cb353c123f2 Mon Sep 17 00:00:00 2001 +From d9ec7f94c0ecefeccf49f1d09bf458eb90472faf Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 19:41:29 +0200 Subject: vcomp: Implement omp_in_parallel. @@ -11,22 +11,22 @@ Subject: vcomp: Implement omp_in_parallel. 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index 4f3471a..fccad93 100644 +index b22dd37..a9a49ce 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c -@@ -351,6 +351,12 @@ void CDECL _vcomp_for_static_end(void) +@@ -453,6 +453,12 @@ void CDECL _vcomp_for_static_end(void) TRACE("()\n"); } +int CDECL omp_in_parallel(void) +{ + TRACE("()\n"); -+ return vcomp_get_team_info() != NULL; ++ return vcomp_init_thread_data()->team != NULL; +} + - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); - static DWORD WINAPI _vcomp_fork_worker(void *param) + { + struct vcomp_thread_data *thread_data = param; diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 8bc66e8..156233f 100644 --- a/dlls/vcomp/vcomp.spec diff --git a/patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch b/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch similarity index 63% rename from patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch rename to patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch index b1b472f6..8cc17bab 100644 --- a/patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch +++ b/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch @@ -1,4 +1,4 @@ -From 77d6daebca21cfb4209a8281abac2b9db0d7a1b4 Mon Sep 17 00:00:00 2001 +From 92b615e0038571e52fb6cc22164ba80c07dcf2f5 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 21:29:41 +0200 Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and @@ -13,129 +13,127 @@ Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and 5 files changed, 104 insertions(+), 6 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index fccad93..db47ff6 100644 +index a9a49ce..31814d6 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c -@@ -56,6 +56,9 @@ struct vcomp_thread_info - /* current task */ - struct vcomp_team_info *team; - DWORD thread_num; +@@ -58,6 +58,9 @@ struct vcomp_thread_data + /* only used for concurrent tasks */ + struct list entry; + CONDITION_VARIABLE cond; + + /* section */ -+ DWORD section; ++ unsigned int section; }; - struct vcomp_team_info -@@ -72,6 +75,11 @@ struct vcomp_team_info + struct vcomp_team_data +@@ -74,6 +77,11 @@ struct vcomp_team_data /* barrier */ - DWORD barrier; - DWORD barrier_count; + unsigned int barrier; + int barrier_count; + + /* section */ -+ DWORD section; -+ DWORD num_sections; -+ DWORD section_index; ++ unsigned int section; ++ unsigned int num_sections; ++ unsigned int section_index; }; - static inline struct vcomp_thread_info *vcomp_get_thread_info(void) -@@ -357,6 +365,43 @@ int CDECL omp_in_parallel(void) - return vcomp_get_team_info() != NULL; + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); +@@ -453,6 +461,43 @@ void CDECL _vcomp_for_static_end(void) + TRACE("()\n"); } +void CDECL _vcomp_sections_init(int n) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + + TRACE("(%d)\n", n); + + EnterCriticalSection(&vcomp_section); -+ thread_info->section++; -+ if ((int)(thread_info->section - team_info->section) > 0) ++ thread_data->section++; ++ if ((int)(thread_data->section - team_data->section) > 0) + { + /* first thread in a new section */ -+ team_info->section = thread_info->section; -+ team_info->num_sections = n; -+ team_info->section_index = 0; ++ team_data->section = thread_data->section; ++ team_data->num_sections = n; ++ team_data->section_index = 0; + } + LeaveCriticalSection(&vcomp_section); +} + +int CDECL _vcomp_sections_next(void) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + int i = -1; + + TRACE("()\n"); + + EnterCriticalSection(&vcomp_section); -+ if (thread_info->section == team_info->section && -+ team_info->section_index < team_info->num_sections) ++ if (thread_data->section == team_data->section && ++ team_data->section_index < team_data->num_sections) + { -+ i = team_info->section_index++; ++ i = team_data->section_index++; + } + LeaveCriticalSection(&vcomp_section); + return i; +} + - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + int CDECL omp_in_parallel(void) + { + TRACE("()\n"); +@@ -526,10 +571,12 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + __ms_va_start(team_data.valist, wrapper); + team_data.barrier = 0; + team_data.barrier_count = 0; ++ team_data.section = 0; - static DWORD WINAPI _vcomp_fork_worker(void *param) -@@ -418,12 +463,14 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - __ms_va_start(team_info.valist, wrapper); - team_info.barrier = 0; - team_info.barrier_count = 0; -+ team_info.section = -1; + thread_data.team = &team_data; + thread_data.thread_num = 0; + thread_data.fork_threads = 0; ++ thread_data.section = 1; + list_init(&thread_data.entry); + InitializeConditionVariable(&thread_data.cond); - /* Initialize members of thread_info. */ - list_init(&thread_info.entry); - InitializeConditionVariable(&thread_info.cond); - thread_info.team = &team_info; - thread_info.thread_num = 0; -+ thread_info.section = 0; +@@ -545,6 +592,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + data->team = &team_data; + data->thread_num = team_data.num_threads++; + data->fork_threads = 0; ++ data->section = 1; + list_remove(&data->entry); + list_add_tail(&thread_data.entry, &data->entry); + WakeAllConditionVariable(&data->cond); +@@ -563,6 +611,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + data->team = &team_data; + data->thread_num = team_data.num_threads; + data->fork_threads = 0; ++ data->section = 1; + InitializeConditionVariable(&data->cond); - if (parallel) - { -@@ -439,6 +486,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - list_add_tail(&thread_info.entry, &info->entry); - info->team = &team_info; - info->thread_num = team_info.num_threads++; -+ info->section = 0; - WakeAllConditionVariable(&info->cond); - } - -@@ -455,6 +503,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - InitializeConditionVariable(&info->cond); - info->team = &team_info; - info->thread_num = team_info.num_threads; -+ info->section = 0; - - thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL); - if (!thread) + thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL); diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c -index 96806fd..902a836 100644 +index 0103af1..c962fe8 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c -@@ -30,6 +30,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i +@@ -38,6 +38,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step, BOOL forward, unsigned int *begin, unsigned int *end); static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); +static void (CDECL *p_vcomp_sections_init)(int n); +static int (CDECL *p_vcomp_sections_next)(void); + static void (CDECL *p_vcomp_set_num_threads)(int num_threads); static int (CDECL *pomp_get_max_threads)(void); - static int (CDECL *pomp_get_num_threads)(void); - static int (CDECL *pomp_get_thread_num)(void); -@@ -57,6 +59,8 @@ static BOOL init_vcomp(void) + static int (CDECL *pomp_get_nested)(void); +@@ -177,6 +179,8 @@ static BOOL init_vcomp(void) VCOMP_GET_PROC(_vcomp_for_static_init); VCOMP_GET_PROC(_vcomp_for_static_simple_init); VCOMP_GET_PROC(_vcomp_fork); + VCOMP_GET_PROC(_vcomp_sections_init); + VCOMP_GET_PROC(_vcomp_sections_next); + VCOMP_GET_PROC(_vcomp_set_num_threads); VCOMP_GET_PROC(omp_get_max_threads); - VCOMP_GET_PROC(omp_get_num_threads); - VCOMP_GET_PROC(omp_get_thread_num); -@@ -536,6 +540,50 @@ static void test_vcomp_for_static_init(void) + VCOMP_GET_PROC(omp_get_nested); +@@ -759,6 +763,50 @@ static void test_vcomp_for_static_init(void) } } @@ -186,13 +184,13 @@ index 96806fd..902a836 100644 START_TEST(vcomp) { if (!init_vcomp()) -@@ -544,6 +592,7 @@ START_TEST(vcomp) +@@ -769,6 +817,7 @@ START_TEST(vcomp) test_vcomp_fork(); test_vcomp_for_static_simple_init(); test_vcomp_for_static_init(); + test_vcomp_sections_init(); - FreeLibrary(hvcomp); + release_vcomp(); } diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 156233f..7083ce4 100644 diff --git a/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch b/patches/vcomp-Functions/0012-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch similarity index 64% rename from patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch rename to patches/vcomp-Functions/0012-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch index bd7cb22f..43075259 100644 --- a/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch +++ b/patches/vcomp-Functions/0012-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch @@ -1,4 +1,4 @@ -From f29610acbf9ce393b772520f6041acce9d1aefd8 Mon Sep 17 00:00:00 2001 +From 145ddf41060e93e9f320d5d2e4347dd2c7b8a83f Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 11 Jul 2015 23:28:31 +0200 Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next @@ -13,23 +13,23 @@ Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next 5 files changed, 152 insertions(+), 6 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index db47ff6..3a1e9ee 100644 +index 31814d6..174ce06 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c -@@ -59,6 +59,9 @@ struct vcomp_thread_info +@@ -61,6 +61,9 @@ struct vcomp_thread_data /* section */ - DWORD section; + unsigned int section; + + /* dynamic */ -+ DWORD dynamic; ++ unsigned int dynamic; }; - struct vcomp_team_info -@@ -80,6 +83,15 @@ struct vcomp_team_info - DWORD section; - DWORD num_sections; - DWORD section_index; + struct vcomp_team_data +@@ -82,6 +85,15 @@ struct vcomp_team_data + unsigned int section; + unsigned int num_sections; + unsigned int section_index; + + /* dynamic */ + DWORD dynamic; @@ -41,23 +41,23 @@ index db47ff6..3a1e9ee 100644 + DWORD dynamic_min_chunksize; }; - static inline struct vcomp_thread_info *vcomp_get_thread_info(void) -@@ -402,6 +414,83 @@ int CDECL _vcomp_sections_next(void) + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); +@@ -498,6 +510,83 @@ int CDECL _vcomp_sections_next(void) return i; } +void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int step, int chunksize) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + unsigned int iterations; + BOOL forward = (flags & 0x40) != 0; + + TRACE("(%d, %d, %d, %d, %d)\n", flags, first, last, step, chunksize); + + EnterCriticalSection(&vcomp_section); -+ thread_info->dynamic++; -+ if ((int)(thread_info->dynamic - team_info->dynamic) > 0) ++ thread_data->dynamic++; ++ if ((int)(thread_data->dynamic - team_data->dynamic) > 0) + { + /* first thread in a new for_dynamic */ + @@ -76,102 +76,100 @@ index db47ff6..3a1e9ee 100644 + iterations = 1 + (first64 - last) / step; + } + -+ team_info->dynamic = thread_info->dynamic; -+ team_info->dynamic_forward = forward; -+ team_info->dynamic_first = first; -+ team_info->dynamic_iterations = iterations; -+ team_info->dynamic_step = step; -+ team_info->dynamic_chunksize = max(1, iterations / team_info->num_threads); -+ team_info->dynamic_min_chunksize = max(1, chunksize); ++ team_data->dynamic = thread_data->dynamic; ++ team_data->dynamic_forward = forward; ++ team_data->dynamic_first = first; ++ team_data->dynamic_iterations = iterations; ++ team_data->dynamic_step = step; ++ team_data->dynamic_chunksize = max(1, iterations / team_data->num_threads); ++ team_data->dynamic_min_chunksize = max(1, chunksize); + } + LeaveCriticalSection(&vcomp_section); +} + +int CDECL _vcomp_for_dynamic_next(int *begin, int *end) +{ -+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); -+ struct vcomp_team_info *team_info = thread_info->team; ++ struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); ++ struct vcomp_team_data *team_data = thread_data->team; + unsigned int iterations = 0; + + TRACE("(%p, %p)\n", begin, end); + + EnterCriticalSection(&vcomp_section); -+ if (thread_info->dynamic == team_info->dynamic && -+ team_info->dynamic_iterations != 0) ++ if (thread_data->dynamic == team_data->dynamic && ++ team_data->dynamic_iterations != 0) + { -+ iterations = min(team_info->dynamic_iterations, team_info->dynamic_chunksize); -+ team_info->dynamic_iterations -= iterations; ++ iterations = min(team_data->dynamic_iterations, team_data->dynamic_chunksize); ++ team_data->dynamic_iterations -= iterations; + -+ if (team_info->dynamic_forward) ++ if (team_data->dynamic_forward) + { -+ *begin = team_info->dynamic_first; -+ *end = team_info->dynamic_first + (iterations - 1) * team_info->dynamic_step; -+ team_info->dynamic_first += iterations * team_info->dynamic_step; ++ *begin = team_data->dynamic_first; ++ *end = team_data->dynamic_first + (iterations - 1) * team_data->dynamic_step; ++ team_data->dynamic_first += iterations * team_data->dynamic_step; + } + else + { -+ *begin = team_info->dynamic_first; -+ *end = team_info->dynamic_first - (iterations - 1) * team_info->dynamic_step; -+ team_info->dynamic_first -= iterations * team_info->dynamic_step; ++ *begin = team_data->dynamic_first; ++ *end = team_data->dynamic_first - (iterations - 1) * team_data->dynamic_step; ++ team_data->dynamic_first -= iterations * team_data->dynamic_step; + } + -+ team_info->dynamic_chunksize = -+ max((team_info->dynamic_chunksize * 3 + 2)/4, team_info->dynamic_min_chunksize); ++ team_data->dynamic_chunksize = ++ max((team_data->dynamic_chunksize * 3 + 2)/4, team_data->dynamic_min_chunksize); + } + LeaveCriticalSection(&vcomp_section); + + return (iterations != 0); +} + - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + int CDECL omp_in_parallel(void) + { + TRACE("()\n"); +@@ -572,11 +661,13 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + team_data.barrier = 0; + team_data.barrier_count = 0; + team_data.section = 0; ++ team_data.dynamic = 0; - static DWORD WINAPI _vcomp_fork_worker(void *param) -@@ -464,6 +553,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - team_info.barrier = 0; - team_info.barrier_count = 0; - team_info.section = -1; -+ team_info.dynamic = -1; + thread_data.team = &team_data; + thread_data.thread_num = 0; + thread_data.fork_threads = 0; + thread_data.section = 1; ++ thread_data.dynamic = 1; + list_init(&thread_data.entry); + InitializeConditionVariable(&thread_data.cond); - /* Initialize members of thread_info. */ - list_init(&thread_info.entry); -@@ -471,6 +561,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - thread_info.team = &team_info; - thread_info.thread_num = 0; - thread_info.section = 0; -+ thread_info.dynamic = 0; +@@ -593,6 +684,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + data->thread_num = team_data.num_threads++; + data->fork_threads = 0; + data->section = 1; ++ data->dynamic = 1; + list_remove(&data->entry); + list_add_tail(&thread_data.entry, &data->entry); + WakeAllConditionVariable(&data->cond); +@@ -612,6 +704,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) + data->thread_num = team_data.num_threads; + data->fork_threads = 0; + data->section = 1; ++ data->dynamic = 1; + InitializeConditionVariable(&data->cond); - if (parallel) - { -@@ -487,6 +578,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - info->team = &team_info; - info->thread_num = team_info.num_threads++; - info->section = 0; -+ info->dynamic = 0; - WakeAllConditionVariable(&info->cond); - } - -@@ -504,6 +596,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) - info->team = &team_info; - info->thread_num = team_info.num_threads; - info->section = 0; -+ info->dynamic = 0; - - thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL); - if (!thread) + thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL); diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c -index 902a836..4273680 100644 +index c962fe8..af04cc9 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c -@@ -24,6 +24,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int)); +@@ -32,6 +32,8 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR); + static VOID (WINAPI *pReleaseActCtx)(HANDLE); - static HMODULE hvcomp = 0; static void (CDECL *p_vcomp_barrier)(void); +static void (CDECL *p_vcomp_for_dynamic_init)(int flags, int first, int last, int step, int chunksize); +static int (CDECL *p_vcomp_for_dynamic_next)(int *begin, int *end); static void (CDECL *p_vcomp_for_static_end)(void); static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops, int *begin, int *end, int *next, int *lastchunk); -@@ -55,6 +57,8 @@ static BOOL init_vcomp(void) +@@ -175,6 +177,8 @@ static BOOL init_vcomp(void) } VCOMP_GET_PROC(_vcomp_barrier); @@ -180,7 +178,7 @@ index 902a836..4273680 100644 VCOMP_GET_PROC(_vcomp_for_static_end); VCOMP_GET_PROC(_vcomp_for_static_init); VCOMP_GET_PROC(_vcomp_for_static_simple_init); -@@ -584,6 +588,54 @@ static void test_vcomp_sections_init(void) +@@ -807,6 +811,54 @@ static void test_vcomp_sections_init(void) } } @@ -235,13 +233,13 @@ index 902a836..4273680 100644 START_TEST(vcomp) { if (!init_vcomp()) -@@ -593,6 +645,7 @@ START_TEST(vcomp) +@@ -818,6 +870,7 @@ START_TEST(vcomp) test_vcomp_for_static_simple_init(); test_vcomp_for_static_init(); test_vcomp_sections_init(); + test_vcomp_for_dynamic_init(); - FreeLibrary(hvcomp); + release_vcomp(); } diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 7083ce4..1b02a65 100644