From 65c559753a4975d6da3851e43a819289cc3074a2 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sun, 12 Jul 2015 00:08:14 +0200 Subject: [PATCH] Added initial set of patches for multithreaded vcomp implementation. --- README.md | 2 +- debian/changelog | 1 + patches/patchinstall.sh | 53 +- ...vcomp-Implement-stub-for-_vcomp_fork.patch | 165 ++++++ ...d-basic-worker-thread-infrastructure.patch | 311 +++++++++++ ...ts-Add-initial-tests-for-_vcomp_fork.patch | 230 +++++++++ ..._vcomp_for_static_simple_init-and-_v.patch | 168 ++++++ ...tests-for-_vcomp_for_static_simple_i.patch | 275 ++++++++++ ...omp-Implement-_vcomp_for_static_init.patch | 127 +++++ ...Add-tests-for-_vcomp_for_static_init.patch | 243 +++++++++ .../0008-vcomp-Implement-_vcomp_barrier.patch | 66 +++ ...0009-vcomp-Implement-omp_in_parallel.patch | 71 +++ ..._vcomp_sections_init-and-_vcomp_sect.patch | 244 +++++++++ ..._vcomp_for_dynamic_init-and-_vcomp_f.patch | 296 +++++++++++ patches/vcomp-Functions/definition | 1 + ...readed-implementation-of-_vcomp_fork.patch | 484 ------------------ ...bs-for-_vcomp_for_static_simple_init.patch | 233 --------- ...tter-stub-for-_vcomp_for_static_init.patch | 153 ------ ...0004-vcomp-implement-omp_in_parallel.patch | 254 --------- ...bs-for-_vcomp_for_dynamic_init-_vcom.patch | 309 ----------- ...bs-for-_vcomp_sections_init-_vcomp_s.patch | 180 ------- ...ing-that-multithreading-is-not-yet-s.patch | 25 - patches/vcomp-Stub_Functions/definition | 1 - 23 files changed, 2229 insertions(+), 1663 deletions(-) create mode 100644 patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch create mode 100644 patches/vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch create mode 100644 patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch create mode 100644 patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch create mode 100644 patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch create mode 100644 patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch create mode 100644 patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch create mode 100644 patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch create mode 100644 patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch create mode 100644 patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch create mode 100644 patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch create mode 100644 patches/vcomp-Functions/definition delete mode 100644 patches/vcomp-Stub_Functions/0001-vcomp-single-threaded-implementation-of-_vcomp_fork.patch delete mode 100644 patches/vcomp-Stub_Functions/0002-vcomp-better-stubs-for-_vcomp_for_static_simple_init.patch delete mode 100644 patches/vcomp-Stub_Functions/0003-vcomp-better-stub-for-_vcomp_for_static_init.patch delete mode 100644 patches/vcomp-Stub_Functions/0004-vcomp-implement-omp_in_parallel.patch delete mode 100644 patches/vcomp-Stub_Functions/0005-vcomp-better-stubs-for-_vcomp_for_dynamic_init-_vcom.patch delete mode 100644 patches/vcomp-Stub_Functions/0006-vcomp-better-stubs-for-_vcomp_sections_init-_vcomp_s.patch delete mode 100644 patches/vcomp-Stub_Functions/0007-vcomp-Add-a-warning-that-multithreading-is-not-yet-s.patch delete mode 100644 patches/vcomp-Stub_Functions/definition diff --git a/README.md b/README.md index f26ac9a6..ae2e5550 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,6 @@ for more details.* * Implement ID3DXEffect::FindNextValidTechnique ([Wine Bug #34101](https://bugs.winehq.org/show_bug.cgi?id=34101)) * Implement IDXGIOutput::GetDesc * Implement a Microsoft Yahei replacement font ([Wine Bug #13829](https://bugs.winehq.org/show_bug.cgi?id=13829)) -* Implement additional stubs for vcomp dlls ([Wine Bug #31640](https://bugs.winehq.org/show_bug.cgi?id=31640)) * Implement an Arial replacement font ([Wine Bug #32323](https://bugs.winehq.org/show_bug.cgi?id=32323)) * Implement combase.WindowsSubstring function * Implement default homepage button in inetcpl.cpl @@ -197,6 +196,7 @@ for more details.* * ~~Implement threadpool timers~~ ([Wine Bug #37306](https://bugs.winehq.org/show_bug.cgi?id=37306)) * ~~Implement threadpool wait objects~~ * ~~Implement threadpool work items~~ ([Wine Bug #32531](https://bugs.winehq.org/show_bug.cgi?id=32531)) +* Implement various vcomp functions ([Wine Bug #31640](https://bugs.winehq.org/show_bug.cgi?id=31640)) * Improve ReadDataAvailable handling in FilePipeLocalInformation class * Improve stub for AEV_GetVolumeRange ([Wine Bug #35658](https://bugs.winehq.org/show_bug.cgi?id=35658)) * Improve stub for ID3DXEffectImpl_CloneEffect diff --git a/debian/changelog b/debian/changelog index 603bf387..03d6f351 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ wine-staging (1.7.47) UNRELEASED; urgency=low * Revert security cookie patch causing regression in multiple applications. * Added patch to use GLX_MESA_query_renderer extension to get more exact GPU infos. + * Added initial set of patches for multithreaded vcomp implementation. * Removed patch to implement kernel32.GetNumaProcessorNode (accepted upstream). * Removed patch to initialize *end with NULL on failure in msvcrt.strtod diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index ec86c27b..2f229968 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -234,7 +234,7 @@ patch_enable_all () enable_user32_Painting="$1" enable_user32_ScrollWindowEx="$1" enable_user32_WndProc="$1" - enable_vcomp_Stub_Functions="$1" + enable_vcomp_Functions="$1" enable_version_VerQueryValue="$1" enable_wbemdisp_ISWbemSecurity="$1" enable_wbemdisp_Timeout="$1" @@ -778,8 +778,8 @@ patch_enable () user32-WndProc) enable_user32_WndProc="$2" ;; - vcomp-Stub_Functions) - enable_vcomp_Stub_Functions="$2" + vcomp-Functions) + enable_vcomp_Functions="$2" ;; version-VerQueryValue) enable_version_VerQueryValue="$2" @@ -4598,33 +4598,40 @@ if test "$enable_user32_WndProc" -eq 1; then ) >> "$patchlist" fi -# Patchset vcomp-Stub_Functions +# Patchset vcomp-Functions # | # | This patchset fixes the following Wine bugs: -# | * [#31640] Implement additional stubs for vcomp dlls +# | * [#31640] Implement various vcomp functions # | # | Modified files: -# | * configure.ac, dlls/vcomp/Makefile.in, dlls/vcomp/fork.c, dlls/vcomp/main.c, dlls/vcomp/tests/Makefile.in, -# | dlls/vcomp/tests/fork.c, dlls/vcomp/tests/vcomp.manifest, dlls/vcomp/tests/vcomp.rc, dlls/vcomp/tests/work.c, -# | dlls/vcomp/vcomp.spec, dlls/vcomp/vcomp_private.h, dlls/vcomp/work.c, dlls/vcomp100/vcomp100.spec, +# | * 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 # | -if test "$enable_vcomp_Stub_Functions" -eq 1; then - patch_apply vcomp-Stub_Functions/0001-vcomp-single-threaded-implementation-of-_vcomp_fork.patch - patch_apply vcomp-Stub_Functions/0002-vcomp-better-stubs-for-_vcomp_for_static_simple_init.patch - patch_apply vcomp-Stub_Functions/0003-vcomp-better-stub-for-_vcomp_for_static_init.patch - patch_apply vcomp-Stub_Functions/0004-vcomp-implement-omp_in_parallel.patch - patch_apply vcomp-Stub_Functions/0005-vcomp-better-stubs-for-_vcomp_for_dynamic_init-_vcom.patch - patch_apply vcomp-Stub_Functions/0006-vcomp-better-stubs-for-_vcomp_sections_init-_vcomp_s.patch - patch_apply vcomp-Stub_Functions/0007-vcomp-Add-a-warning-that-multithreading-is-not-yet-s.patch +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 ( - echo '+ { "Dan Kegel", "vcomp: single-threaded implementation of _vcomp_fork.", 1 },'; - echo '+ { "Dan Kegel", "vcomp: better stubs for _vcomp_for_static_simple_init, _vcomp_for_static_end.", 1 },'; - echo '+ { "Dan Kegel", "vcomp: better stub for _vcomp_for_static_init.", 1 },'; - echo '+ { "Dan Kegel", "vcomp: implement omp_in_parallel.", 1 },'; - echo '+ { "Dan Kegel", "vcomp: better stubs for _vcomp_for_dynamic_init, _vcomp_for_dynamic_next.", 1 },'; - echo '+ { "Dan Kegel", "vcomp: better stubs for _vcomp_sections_init, _vcomp_sections_next.", 1 },'; - echo '+ { "Sebastian Lackner", "vcomp: Add a warning that multithreading is not yet supported.", 1 },'; + 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: 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 },'; ) >> "$patchlist" fi 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 new file mode 100644 index 00000000..a567d1e5 --- /dev/null +++ b/patches/vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch @@ -0,0 +1,165 @@ +From 6404654fd885acbf0e563d9b5070d321986b5b8d Mon Sep 17 00:00:00 2001 +From: Dan Kegel +Date: Sat, 11 Jul 2015 06:50:26 +0200 +Subject: vcomp: Implement stub for _vcomp_fork. + +--- + dlls/vcomp/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/vcomp.spec | 2 +- + dlls/vcomp100/vcomp100.spec | 2 +- + dlls/vcomp90/vcomp90.spec | 2 +- + 4 files changed, 96 insertions(+), 3 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index ab2a372..26f6c67 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -3,6 +3,7 @@ + * vcomp implementation + * + * Copyright 2011 Austin English ++ * 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 +@@ -107,6 +108,98 @@ void CDECL _vcomp_single_end(void) + TRACE("stub\n"); + } + ++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") ++ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") ++ "movl %esp,%ebp\n\t" ++ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") ++ "pushl %esi\n\t" ++ __ASM_CFI(".cfi_rel_offset %esi,-4\n\t") ++ "pushl %edi\n\t" ++ __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") ++ "movl 12(%ebp),%edx\n\t" ++ "movl %esp,%edi\n\t" ++ "shll $2,%edx\n\t" ++ "jz 1f\n\t" ++ "subl %edx,%edi\n\t" ++ "andl $~15,%edi\n\t" ++ "movl %edi,%esp\n\t" ++ "movl 12(%ebp),%ecx\n\t" ++ "movl 16(%ebp),%esi\n\t" ++ "cld\n\t" ++ "rep; movsl\n" ++ "1:\tcall *8(%ebp)\n\t" ++ "leal -8(%ebp),%esp\n\t" ++ "popl %edi\n\t" ++ __ASM_CFI(".cfi_same_value %edi\n\t") ++ "popl %esi\n\t" ++ __ASM_CFI(".cfi_same_value %esi\n\t") ++ "popl %ebp\n\t" ++ __ASM_CFI(".cfi_def_cfa %esp,4\n\t") ++ __ASM_CFI(".cfi_same_value %ebp\n\t") ++ "ret" ) ++ ++#elif defined(__x86_64__) ++ ++__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, ++ "pushq %rbp\n\t" ++ __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") ++ __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") ++ "movq %rsp,%rbp\n\t" ++ __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") ++ "pushq %rsi\n\t" ++ __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t") ++ "pushq %rdi\n\t" ++ __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t") ++ "movq %rcx,%rax\n\t" ++ "movq $4,%rcx\n\t" ++ "cmp %rcx,%rdx\n\t" ++ "cmovgq %rdx,%rcx\n\t" ++ "leaq 0(,%rcx,8),%rdx\n\t" ++ "subq %rdx,%rsp\n\t" ++ "andq $~15,%rsp\n\t" ++ "movq %rsp,%rdi\n\t" ++ "movq %r8,%rsi\n\t" ++ "rep; movsq\n\t" ++ "movq 0(%rsp),%rcx\n\t" ++ "movq 8(%rsp),%rdx\n\t" ++ "movq 16(%rsp),%r8\n\t" ++ "movq 24(%rsp),%r9\n\t" ++ "callq *%rax\n\t" ++ "leaq -16(%rbp),%rsp\n\t" ++ "popq %rdi\n\t" ++ __ASM_CFI(".cfi_same_value %rdi\n\t") ++ "popq %rsi\n\t" ++ __ASM_CFI(".cfi_same_value %rsi\n\t") ++ __ASM_CFI(".cfi_def_cfa_register %rsp\n\t") ++ "popq %rbp\n\t" ++ __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) ++{ ++ ERR("Not implemented for this architecture\n"); ++} ++ ++#endif ++ + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) + { + TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index 306dd15..d446574 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -64,7 +64,7 @@ + @ stub _vcomp_for_static_init_i8 + @ stub _vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 +-@ stub _vcomp_fork ++@ varargs _vcomp_fork(long long ptr) + @ stub _vcomp_get_thread_num + @ stub _vcomp_leave_critsect + @ stub _vcomp_master_barrier +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index 39cf91c..2c04e91 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -64,7 +64,7 @@ + @ stub _vcomp_for_static_init_i8 + @ stub _vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 +-@ stub _vcomp_fork ++@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork + @ stub _vcomp_get_thread_num + @ stub _vcomp_leave_critsect + @ stub _vcomp_master_barrier +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index 39cf91c..2c04e91 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -64,7 +64,7 @@ + @ stub _vcomp_for_static_init_i8 + @ stub _vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 +-@ stub _vcomp_fork ++@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork + @ stub _vcomp_get_thread_num + @ stub _vcomp_leave_critsect + @ stub _vcomp_master_barrier +-- +2.4.5 + 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 new file mode 100644 index 00000000..4ea96641 --- /dev/null +++ b/patches/vcomp-Functions/0002-vcomp-Add-basic-worker-thread-infrastructure.patch @@ -0,0 +1,311 @@ +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/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch b/patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch new file mode 100644 index 00000000..a27f62ce --- /dev/null +++ b/patches/vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch @@ -0,0 +1,230 @@ +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-Implement-_vcomp_for_static_simple_init-and-_v.patch b/patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch new file mode 100644 index 00000000..0341780b --- /dev/null +++ b/patches/vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch @@ -0,0 +1,168 @@ +From f455eb53b0d527874fb95bdc652d1a31cd8fa93a 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 + _vcomp_for_static_end. + +--- + dlls/vcomp/main.c | 90 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/vcomp.spec | 4 +- + dlls/vcomp100/vcomp100.spec | 4 +- + dlls/vcomp90/vcomp90.spec | 4 +- + 4 files changed, 96 insertions(+), 6 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 9de9721..400f93a 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -174,6 +174,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; ++ 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; ++ ++ if (num_threads == 1) ++ { ++ *begin = first; ++ *end = last; ++ return; ++ } ++ ++ if (step <= 0) ++ { ++ *begin = 0; ++ *end = forward ? -1 : 1; ++ return; ++ } ++ ++ if (forward) ++ { ++ DWORD64 last64 = last; ++ if (last64 < first) ++ last64 += 0x100000000; ++ ++ iterations = 1 + (last64 - first) / step; ++ per_thread = iterations / num_threads; ++ remaining = iterations - per_thread * num_threads; ++ ++ if (thread_num < remaining) ++ { ++ per_thread++; ++ } ++ else if (per_thread) ++ { ++ first += remaining * step; ++ } ++ else ++ { ++ *begin = first; ++ *end = first - step; ++ return; ++ } ++ ++ *begin = first + per_thread * thread_num * step; ++ *end = *begin + (per_thread - 1) * step; ++ } ++ else ++ { ++ DWORD first64 = first; ++ if (first64 < last) ++ first64 += 0x100000000; ++ ++ iterations = 1 + (first64 - last) / step; ++ per_thread = iterations / num_threads; ++ remaining = iterations - per_thread * num_threads; ++ ++ if (thread_num < remaining) ++ { ++ per_thread++; ++ } ++ else if (per_thread) ++ { ++ first64 -= remaining * step; ++ } ++ else ++ { ++ *begin = first64; ++ *end = first64 + step; ++ return; ++ } ++ ++ *begin = first64 - per_thread * thread_num * step; ++ *end = *begin - (per_thread - 1) * step; ++ } ++} ++ ++void CDECL _vcomp_for_static_end(void) ++{ ++ TRACE("()\n"); ++} ++ + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + + static DWORD WINAPI _vcomp_fork_worker(void *param) +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index d446574..b14edca 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -59,10 +59,10 @@ + @ stub _vcomp_for_dynamic_init_i8 + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 +-@ stub _vcomp_for_static_end ++@ cdecl _vcomp_for_static_end() + @ stub _vcomp_for_static_init + @ stub _vcomp_for_static_init_i8 +-@ stub _vcomp_for_static_simple_init ++@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) + @ stub _vcomp_for_static_simple_init_i8 + @ varargs _vcomp_fork(long long ptr) + @ stub _vcomp_get_thread_num +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index 2c04e91..89e0972 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -59,10 +59,10 @@ + @ stub _vcomp_for_dynamic_init_i8 + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 +-@ stub _vcomp_for_static_end ++@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end + @ stub _vcomp_for_static_init + @ stub _vcomp_for_static_init_i8 +-@ stub _vcomp_for_static_simple_init ++@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 + @ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork + @ stub _vcomp_get_thread_num +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index 2c04e91..89e0972 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -59,10 +59,10 @@ + @ stub _vcomp_for_dynamic_init_i8 + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 +-@ stub _vcomp_for_static_end ++@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end + @ stub _vcomp_for_static_init + @ stub _vcomp_for_static_init_i8 +-@ stub _vcomp_for_static_simple_init ++@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 + @ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork + @ stub _vcomp_get_thread_num +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch b/patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch new file mode 100644 index 00000000..ef66aca8 --- /dev/null +++ b/patches/vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch @@ -0,0 +1,275 @@ +From af8411c2c51708c2edbc620b3d775bf5a08144f9 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(+) + +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 5c6a861..1971b6d 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)); + + static HMODULE hvcomp = 0; ++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 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; + } + ++ 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(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) + } + } + ++static void CDECL _test_vcomp_for_static_simple_init(void) ++{ ++ static const struct ++ { ++ unsigned int first; ++ unsigned int last; ++ int step; ++ BOOL forward; ++ } ++ tests[] = ++ { ++ /* loop forward, step 1 */ ++ { 0, 0, 1, TRUE }, ++ { 0, 1, 1, TRUE }, ++ { 0, 2, 1, TRUE }, ++ { 0, 3, 1, TRUE }, ++ { 0, 0x10000000, 1, TRUE }, ++ { 0, 0x20000000, 1, TRUE }, ++ { 0, 0x40000000, 1, TRUE }, ++ { 0, 0x80000000, 1, TRUE }, ++ ++ /* loop forward, varying step */ ++ { 0, 100, 1, TRUE }, ++ { 0, 100, 5, TRUE }, ++ { 0, 100, 10, TRUE }, ++ { 0, 100, 25, TRUE }, ++ { 0, 100, 50, TRUE }, ++ { 0, 100, 75, TRUE }, ++ { 0, 100, 100, TRUE }, ++ { 0, 100, 150, TRUE }, ++ ++ /* empty loop forward, varying step */ ++ { 50, 50, 3, TRUE }, ++ { 50, 50, 2, TRUE }, ++ { 50, 50, 1, TRUE }, ++ { 50, 50, 0, TRUE }, ++ { 50, 50, -1, TRUE }, ++ { 50, 50, -2, TRUE }, ++ { 50, 50, -3, TRUE }, ++ ++ /* loop backward, step 1 */ ++ { 0, 0, 1, FALSE }, ++ { 1, 0, 1, FALSE }, ++ { 2, 0, 1, FALSE }, ++ { 3, 0, 1, FALSE }, ++ { 0x10000000, 0, 1, FALSE }, ++ { 0x20000000, 0, 1, FALSE }, ++ { 0x40000000, 0, 1, FALSE }, ++ { 0x80000000, 0, 1, FALSE }, ++ ++ /* loop backward, varying step */ ++ { 100, 0, 1, FALSE }, ++ { 100, 0, 5, FALSE }, ++ { 100, 0, 10, FALSE }, ++ { 100, 0, 25, FALSE }, ++ { 100, 0, 50, FALSE }, ++ { 100, 0, 75, FALSE }, ++ { 100, 0, 100, FALSE }, ++ { 100, 0, 150, FALSE }, ++ ++ /* empty loop backward, varying step */ ++ { 50, 50, 3, FALSE }, ++ { 50, 50, 2, FALSE }, ++ { 50, 50, 1, FALSE }, ++ { 50, 50, 0, FALSE }, ++ { 50, 50, -1, FALSE }, ++ { 50, 50, -2, FALSE }, ++ { 50, 50, -3, FALSE }, ++ ++ /* test overflow in forward loop */ ++ { 0, 0, 1, TRUE }, ++ { 1, 0, 1, TRUE }, ++ { 2, 0, 1, TRUE }, ++ { 3, 0, 1, TRUE }, ++ { 0x10000000, 0, 1, TRUE }, ++ { 0x20000000, 0, 1, TRUE }, ++ { 0x40000000, 0, 1, TRUE }, ++ { 0x80000000, 0, 1, TRUE }, ++ ++ { 100, 0, 1, TRUE }, ++ { 100, 0, 5, TRUE }, ++ { 100, 0, 10, TRUE }, ++ { 100, 0, 25, TRUE }, ++ { 100, 0, 50, TRUE }, ++ { 100, 0, 75, TRUE }, ++ { 100, 0, 100, TRUE }, ++ { 100, 0, 150, TRUE }, ++ ++ /* test overflow in backward loop */ ++ { 0, 0, 1, FALSE }, ++ { 0, 1, 1, FALSE }, ++ { 0, 2, 1, FALSE }, ++ { 0, 3, 1, FALSE }, ++ { 0, 0x10000000, 1, FALSE }, ++ { 0, 0x20000000, 1, FALSE }, ++ { 0, 0x40000000, 1, FALSE }, ++ { 0, 0x80000000, 1, FALSE }, ++ ++ { 0, 100, 1, FALSE }, ++ { 0, 100, 5, FALSE }, ++ { 0, 100, 10, FALSE }, ++ { 0, 100, 25, FALSE }, ++ { 0, 100, 50, FALSE }, ++ { 0, 100, 75, FALSE }, ++ { 0, 100, 100, FALSE }, ++ { 0, 100, 150, FALSE }, ++ }; ++ unsigned int begin, end, expected_begin, expected_end; ++ int thread_num = pomp_get_thread_num(); ++ int num_threads = pomp_get_num_threads(); ++ int i; ++ ++ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) ++ { ++ unsigned int iterations, per_thread, remaining; ++ DWORD64 first = tests[i].first; ++ DWORD64 last = tests[i].last; ++ int step = tests[i].step; ++ ++ if (num_threads == 1) ++ { ++ expected_begin = first; ++ expected_end = last; ++ goto done; ++ } ++ ++ if (tests[i].forward) ++ { ++ if (tests[i].step <= 0) ++ { ++ expected_begin = 0; ++ expected_end = -1; ++ goto done; ++ } ++ ++ if (last < first) ++ last += 0x100000000; ++ ++ iterations = 1 + (last - first) / step; ++ per_thread = iterations / num_threads; ++ remaining = iterations - per_thread * num_threads; ++ ++ if (thread_num < remaining) ++ per_thread++; ++ else if (per_thread) ++ first += remaining * step; ++ else ++ { ++ expected_begin = first; ++ expected_end = first - step; ++ goto done; ++ } ++ ++ expected_begin = first + per_thread * thread_num * step; ++ expected_end = expected_begin + (per_thread - 1) * step; ++ } ++ else ++ { ++ if (tests[i].step <= 0) ++ { ++ expected_begin = 0; ++ expected_end = 1; ++ goto done; ++ } ++ ++ if (first < last) ++ first += 0x100000000; ++ ++ iterations = 1 + (first - last) / step; ++ per_thread = iterations / num_threads; ++ remaining = iterations - per_thread * num_threads; ++ ++ if (thread_num < remaining) ++ per_thread++; ++ else if (per_thread) ++ first -= remaining * step; ++ else ++ { ++ expected_begin = first; ++ expected_end = first + step; ++ goto done; ++ } ++ ++ expected_begin = first - per_thread * thread_num * step; ++ expected_end = expected_begin - (per_thread - 1) * step; ++ } ++ ++done: ++ begin = end = 0xdeadbeef; ++ p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, ++ tests[i].forward, &begin, &end); ++ ++ ok(begin == expected_begin, "%d:%d/%d: expected begin = %u, got %u\n", ++ i, thread_num, num_threads, expected_begin, end); ++ ok(end == expected_end, "%d:%d/%d: expected end = %u, got %u\n", ++ i, thread_num, num_threads, expected_end, end); ++ ++ p_vcomp_for_static_end(); ++ p_vcomp_barrier(); ++ } ++} ++ ++static void test_vcomp_for_static_simple_init(void) ++{ ++ int i; ++ ++ for (i = 1; i <= 4; i++) ++ { ++ trace("Running tests with %d threads\n", i); ++ pomp_set_num_threads(i); ++ p_vcomp_fork(TRUE, 0, _test_vcomp_for_static_simple_init); ++ } ++} ++ + START_TEST(vcomp) + { + if (!init_vcomp()) + return; + + test_vcomp_fork(); ++ test_vcomp_for_static_simple_init(); + + FreeLibrary(hvcomp); + } +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch b/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch new file mode 100644 index 00000000..115b0567 --- /dev/null +++ b/patches/vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch @@ -0,0 +1,127 @@ +From 721c89ed7aec4a9ae8f0a5f7b0efeee838c08985 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. + +--- + dlls/vcomp/main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/vcomp.spec | 2 +- + dlls/vcomp100/vcomp100.spec | 2 +- + dlls/vcomp90/vcomp90.spec | 2 +- + 4 files changed, 65 insertions(+), 3 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 400f93a..2eeea3b 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, + } + } + ++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; ++ 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; ++ ++ if (chunksize < 1) ++ chunksize = 1; ++ ++ if (num_threads == 1 && chunksize > 1) ++ { ++ *loops = 1; ++ *begin = first; ++ *end = last; ++ *next = chunksize; ++ *lastchunk = first; ++ } ++ else if (last > first) ++ { ++ iterations = 1 + (last - first) / step; ++ num_chunks = (iterations + chunksize - 1) / chunksize; ++ per_thread = num_chunks / num_threads; ++ remaining = num_chunks - per_thread * num_threads; ++ ++ *loops = per_thread + (thread_num < remaining); ++ *begin = first + thread_num * chunksize * step; ++ *end = *begin + (chunksize - 1) * step; ++ *next = chunksize * num_threads * step; ++ *lastchunk = first + (num_chunks - 1) * chunksize * step; ++ ++ } ++ else if (last < first) ++ { ++ iterations = 1 + (first - last) / step; ++ num_chunks = (iterations + chunksize - 1) / chunksize; ++ per_thread = num_chunks / num_threads; ++ remaining = num_chunks - per_thread * num_threads; ++ ++ *loops = per_thread + (thread_num < remaining); ++ *begin = first - thread_num * chunksize * step; ++ *end = *begin - (chunksize - 1) * step; ++ *next = - chunksize * num_threads * step; ++ *lastchunk = first - (num_chunks - 1) * chunksize * step; ++ } ++ else ++ { ++ *loops = (thread_num == 0); ++ *begin = first; ++ *end = last; ++ *next = 0; ++ *lastchunk = first; ++ } ++} ++ + void CDECL _vcomp_for_static_end(void) + { + TRACE("()\n"); +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index b14edca..8bc66e8 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -60,7 +60,7 @@ + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() +-@ stub _vcomp_for_static_init ++@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) + @ stub _vcomp_for_static_init_i8 + @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) + @ stub _vcomp_for_static_simple_init_i8 +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index 89e0972..f008e2e 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -60,7 +60,7 @@ + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end +-@ stub _vcomp_for_static_init ++@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init + @ stub _vcomp_for_static_init_i8 + @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index 89e0972..f008e2e 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -60,7 +60,7 @@ + @ stub _vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end +-@ stub _vcomp_for_static_init ++@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init + @ stub _vcomp_for_static_init_i8 + @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init + @ stub _vcomp_for_static_simple_init_i8 +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch b/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch new file mode 100644 index 00000000..847e319f --- /dev/null +++ b/patches/vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch @@ -0,0 +1,243 @@ +From 9cea1ba140eb5d8ecd70eab4a68e309cd80fd454 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. + +--- + dlls/vcomp/tests/vcomp.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 199 insertions(+) + +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 1971b6d..96806fd 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; + 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, ++ int *begin, int *end, int *next, int *lastchunk); + 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) + + 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) + } + } + ++static void CDECL _test_vcomp_for_static_init(void) ++{ ++ static const struct ++ { ++ int first; ++ int last; ++ int step; ++ int chunksize; ++ } ++ tests[] = ++ { ++ /* loop forward, step 1 */ ++ { 0, 0, 1, 1 }, ++ { 0, 1, 1, 1 }, ++ { 0, 2, 1, 1 }, ++ { 0, 3, 1, 1 }, ++ { 0, 0x10000000, 1, 1 }, ++ { 0, 0x20000000, 1, 1 }, ++ { 0, 0x40000000, 1, 1 }, ++ { 0, (int)0x80000000, 1, 1 }, ++ ++ /* loop forward, varying step */ ++ {0, 100, 1, 1}, ++ {0, 100, 5, 1}, ++ {0, 100, 10, 1}, ++ {0, 100, 25, 1}, ++ {0, 100, 50, 1}, ++ {0, 100, 75, 1}, ++ {0, 100, 100, 1}, ++ {0, 100, 150, 1}, ++ ++ /* empty loop forward, varying step */ ++ { 50, 50, 3, 1 }, ++ { 50, 50, 2, 1 }, ++ { 50, 50, 1, 1 }, ++ /*{ 50, 50, 0, 1 }, - generates a division by zero exception */ ++ { 50, 50, -1, 1 }, ++ { 50, 50, -2, 1 }, ++ { 50, 50, -3, 1 }, ++ ++ /* loop backwards, step 1 */ ++ { 0, 0, 1, 1 }, ++ { 1, 0, 1, 1 }, ++ { 2, 0, 1, 1 }, ++ { 3, 0, 1, 1 }, ++ { 0x10000000, 0, 1, 1 }, ++ { 0x20000000, 0, 1, 1 }, ++ { 0x40000000, 0, 1, 1 }, ++ { (int)0x80000000, 0, 1, 1 }, ++ ++ /* loop backwards, varying step */ ++ {100, 0, 1, 1}, ++ {100, 0, 5, 1}, ++ {100, 0, 10, 1}, ++ {100, 0, 25, 1}, ++ {100, 0, 50, 1}, ++ {100, 0, 75, 1}, ++ {100, 0, 100, 1}, ++ {100, 0, 150, 1}, ++ ++ /* loop forward, varying chunksize */ ++ {0, 100, 1, 1}, ++ {0, 100, 1, 5}, ++ {0, 100, 1, 10}, ++ {0, 100, 1, 25}, ++ {0, 100, 1, 50}, ++ {0, 100, 1, 75}, ++ {0, 100, 1, 100}, ++ {0, 100, 1, 150}, ++ ++ {0, 100, 7, 1}, ++ {0, 100, 7, 5}, ++ {0, 100, 7, 10}, ++ {0, 100, 7, 25}, ++ {0, 100, 7, 50}, ++ {0, 100, 7, 75}, ++ {0, 100, 7, 100}, ++ {0, 100, 7, 150}, ++ ++ /* loop backwards, varying chunksize */ ++ {100, 0, 1, 1}, ++ {100, 0, 1, 5}, ++ {100, 0, 1, 10}, ++ {100, 0, 1, 25}, ++ {100, 0, 1, 50}, ++ {100, 0, 1, 75}, ++ {100, 0, 1, 100}, ++ {100, 0, 1, 150}, ++ ++ {100, 0, 7, 1}, ++ {100, 0, 7, 5}, ++ {100, 0, 7, 10}, ++ {100, 0, 7, 25}, ++ {100, 0, 7, 50}, ++ {100, 0, 7, 75}, ++ {100, 0, 7, 100}, ++ {100, 0, 7, 150}, ++ ++ }; ++ int begin, end, expected_begin, expected_end; ++ unsigned int loops, expected_loops; ++ int lastchunk, expected_lastchunk; ++ int chunksize, expected_chunksize; ++ int thread_num = pomp_get_thread_num(); ++ int num_threads = pomp_get_num_threads(); ++ int i; ++ ++ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) ++ { ++ unsigned int iterations, num_chunks, per_thread, remaining; ++ int first = tests[i].first; ++ int last = tests[i].last; ++ int step = tests[i].step; ++ chunksize = tests[i].chunksize; ++ ++ if (chunksize < 1) ++ chunksize = 1; ++ ++ if (num_threads == 1 && chunksize > 1) ++ { ++ expected_loops = 1; ++ expected_begin = first; ++ expected_end = last; ++ expected_chunksize = chunksize; ++ expected_lastchunk = first; ++ } ++ else if (last > first) ++ { ++ iterations = 1 + (last - first) / step; ++ num_chunks = (iterations + chunksize - 1) / chunksize; ++ per_thread = num_chunks / num_threads; ++ remaining = num_chunks - per_thread * num_threads; ++ ++ expected_loops = per_thread + (thread_num < remaining); ++ expected_begin = first + thread_num * chunksize * step; ++ expected_end = expected_begin + (chunksize - 1) * step; ++ expected_chunksize = chunksize * num_threads * step; ++ expected_lastchunk = first + (num_chunks - 1) * chunksize * step; ++ ++ } ++ else if (last < first) ++ { ++ iterations = 1 + (first - last) / step; ++ num_chunks = (iterations + chunksize - 1) / chunksize; ++ per_thread = num_chunks / num_threads; ++ remaining = num_chunks - per_thread * num_threads; ++ ++ expected_loops = per_thread + (thread_num < remaining); ++ expected_begin = first - thread_num * chunksize * step; ++ expected_end = expected_begin - (chunksize - 1) * step; ++ expected_chunksize = - chunksize * num_threads * step; ++ expected_lastchunk = first - (num_chunks - 1) * chunksize * step; ++ } ++ else ++ { ++ expected_loops = (thread_num == 0); ++ expected_begin = first; ++ expected_end = last; ++ expected_chunksize = 0; ++ expected_lastchunk = first; ++ } ++ ++ loops = begin = end = chunksize = lastchunk = 0xdeadbeef; ++ p_vcomp_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize, ++ &loops, &begin, &end, &chunksize, &lastchunk); ++ ++ ok(loops == expected_loops, "%d:%d/%d: expected loops = %u, got %u\n", ++ i, thread_num, num_threads, expected_loops, loops); ++ ok(begin == expected_begin || broken(begin == 0xdeadbeef && first == last && thread_num > 0), ++ "%d:%d/%d: expected begin = %u, got %u\n", i, thread_num, num_threads, expected_begin, end); ++ ok(end == expected_end || broken(end == 0xdeadbeef && first == last && thread_num > 0), ++ "%d:%d/%d: expected end = %u, got %u\n", i, thread_num, num_threads, expected_end, end); ++ ok(chunksize == expected_chunksize || broken(chunksize == (int)0xdeadbeef && first == last) || ++ broken(chunksize != expected_chunksize && num_threads == 1), ++ "%d:%d/%d: expected chunksize = %u, got %u\n", i, thread_num, num_threads, expected_chunksize, chunksize); ++ ok(lastchunk == expected_lastchunk || broken(lastchunk == 0xdeadbeef && first == last && thread_num > 0), ++ "%d:%d/%d: expected lastchunk = %u, got %u\n", i, thread_num, num_threads, expected_lastchunk, lastchunk); ++ ++ p_vcomp_for_static_end(); ++ p_vcomp_barrier(); ++ } ++} ++ ++static void test_vcomp_for_static_init(void) ++{ ++ int i; ++ ++ for (i = 1; i <= 4; i++) ++ { ++ trace("Running tests with %d threads\n", i); ++ pomp_set_num_threads(i); ++ p_vcomp_fork(TRUE, 0, _test_vcomp_for_static_init); ++ } ++} ++ + START_TEST(vcomp) + { + if (!init_vcomp()) +@@ -345,6 +543,7 @@ START_TEST(vcomp) + + test_vcomp_fork(); + test_vcomp_for_static_simple_init(); ++ test_vcomp_for_static_init(); + + FreeLibrary(hvcomp); + } +-- +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 new file mode 100644 index 00000000..cdf7f380 --- /dev/null +++ b/patches/vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch @@ -0,0 +1,66 @@ +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/0009-vcomp-Implement-omp_in_parallel.patch b/patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch new file mode 100644 index 00000000..a18082b9 --- /dev/null +++ b/patches/vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch @@ -0,0 +1,71 @@ +From aad24232add010020898eaa1a0934cb353c123f2 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. + +--- + dlls/vcomp/main.c | 6 ++++++ + dlls/vcomp/vcomp.spec | 2 +- + dlls/vcomp100/vcomp100.spec | 2 +- + dlls/vcomp90/vcomp90.spec | 2 +- + 4 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 4f3471a..fccad93 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -351,6 +351,12 @@ void CDECL _vcomp_for_static_end(void) + TRACE("()\n"); + } + ++int CDECL omp_in_parallel(void) ++{ ++ TRACE("()\n"); ++ return vcomp_get_team_info() != NULL; ++} ++ + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + + static DWORD WINAPI _vcomp_fork_worker(void *param) +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index 8bc66e8..156233f 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -98,7 +98,7 @@ + @ cdecl omp_get_thread_num() + @ stub omp_get_wtick + @ cdecl omp_get_wtime() +-@ stub omp_in_parallel ++@ cdecl omp_in_parallel() + @ stub omp_init_lock + @ stub omp_init_nest_lock + @ cdecl omp_set_dynamic(long) +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index f008e2e..dd276d0 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -98,7 +98,7 @@ + @ cdecl omp_get_thread_num() vcomp.omp_get_thread_num + @ stub omp_get_wtick + @ cdecl omp_get_wtime() vcomp.omp_get_wtime +-@ stub omp_in_parallel ++@ cdecl omp_in_parallel() vcomp.omp_in_parallel + @ stub omp_init_lock + @ stub omp_init_nest_lock + @ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index f008e2e..dd276d0 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -98,7 +98,7 @@ + @ cdecl omp_get_thread_num() vcomp.omp_get_thread_num + @ stub omp_get_wtick + @ cdecl omp_get_wtime() vcomp.omp_get_wtime +-@ stub omp_in_parallel ++@ cdecl omp_in_parallel() vcomp.omp_in_parallel + @ stub omp_init_lock + @ stub omp_init_nest_lock + @ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch b/patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch new file mode 100644 index 00000000..b1b472f6 --- /dev/null +++ b/patches/vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch @@ -0,0 +1,244 @@ +From 77d6daebca21cfb4209a8281abac2b9db0d7a1b4 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 + add tests. + +--- + dlls/vcomp/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/tests/vcomp.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/vcomp.spec | 4 ++-- + dlls/vcomp100/vcomp100.spec | 4 ++-- + dlls/vcomp90/vcomp90.spec | 4 ++-- + 5 files changed, 104 insertions(+), 6 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index fccad93..db47ff6 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; ++ ++ /* section */ ++ DWORD section; + }; + + struct vcomp_team_info +@@ -72,6 +75,11 @@ struct vcomp_team_info + /* barrier */ + DWORD barrier; + DWORD barrier_count; ++ ++ /* section */ ++ DWORD section; ++ DWORD num_sections; ++ DWORD 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_sections_init(int n) ++{ ++ struct vcomp_thread_info *thread_info = vcomp_get_thread_info(); ++ struct vcomp_team_info *team_info = thread_info->team; ++ ++ TRACE("(%d)\n", n); ++ ++ EnterCriticalSection(&vcomp_section); ++ thread_info->section++; ++ if ((int)(thread_info->section - team_info->section) > 0) ++ { ++ /* first thread in a new section */ ++ team_info->section = thread_info->section; ++ team_info->num_sections = n; ++ team_info->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; ++ int i = -1; ++ ++ TRACE("()\n"); ++ ++ EnterCriticalSection(&vcomp_section); ++ if (thread_info->section == team_info->section && ++ team_info->section_index < team_info->num_sections) ++ { ++ i = team_info->section_index++; ++ } ++ LeaveCriticalSection(&vcomp_section); ++ return i; ++} ++ + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + + 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; + + /* 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; + + 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) +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 96806fd..902a836 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 + 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 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) + 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(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) + } + } + ++static void CDECL _test_vcomp_sections_init(LONG *a, LONG *b, LONG *c) ++{ ++ int i; ++ ++ p_vcomp_sections_init(20); ++ while ((i = p_vcomp_sections_next()) != -1) ++ { ++ InterlockedIncrement(a); ++ Sleep(50); ++ } ++ ++ p_vcomp_sections_init(30); ++ while ((i = p_vcomp_sections_next()) != -1) ++ { ++ InterlockedIncrement(b); ++ Sleep(50); ++ } ++ ++ p_vcomp_sections_init(40); ++ while ((i = p_vcomp_sections_next()) != -1) ++ { ++ InterlockedIncrement(c); ++ Sleep(50); ++ } ++} ++ ++static void test_vcomp_sections_init(void) ++{ ++ LONG a, b, c; ++ int i; ++ ++ for (i = 1; i <= 4; i++) ++ { ++ trace("Running tests with %d threads\n", i); ++ pomp_set_num_threads(i); ++ ++ a = b = c = 0; ++ p_vcomp_fork(TRUE, 3, _test_vcomp_sections_init, &a, &b, &c); ++ ok(a == 20, "expected a = 20, got %d\n", a); ++ ok(b == 30, "expected b = 30, got %d\n", b); ++ ok(c == 40, "expected c = 40, got %d\n", c); ++ } ++} ++ + START_TEST(vcomp) + { + if (!init_vcomp()) +@@ -544,6 +592,7 @@ START_TEST(vcomp) + test_vcomp_fork(); + test_vcomp_for_static_simple_init(); + test_vcomp_for_static_init(); ++ test_vcomp_sections_init(); + + FreeLibrary(hvcomp); + } +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index 156233f..7083ce4 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -83,8 +83,8 @@ + @ stub _vcomp_reduction_u2 + @ stub _vcomp_reduction_u4 + @ stub _vcomp_reduction_u8 +-@ stub _vcomp_sections_init +-@ stub _vcomp_sections_next ++@ cdecl _vcomp_sections_init(long) ++@ cdecl _vcomp_sections_next() + @ cdecl _vcomp_set_num_threads(long) + @ cdecl _vcomp_single_begin(long) + @ cdecl _vcomp_single_end() +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index dd276d0..56c7ae3 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -83,8 +83,8 @@ + @ stub _vcomp_reduction_u2 + @ stub _vcomp_reduction_u4 + @ stub _vcomp_reduction_u8 +-@ stub _vcomp_sections_init +-@ stub _vcomp_sections_next ++@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init ++@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next + @ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads + @ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin + @ cdecl _vcomp_single_end() vcomp._vcomp_single_end +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index dd276d0..56c7ae3 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -83,8 +83,8 @@ + @ stub _vcomp_reduction_u2 + @ stub _vcomp_reduction_u4 + @ stub _vcomp_reduction_u8 +-@ stub _vcomp_sections_init +-@ stub _vcomp_sections_next ++@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init ++@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next + @ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads + @ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin + @ cdecl _vcomp_single_end() vcomp._vcomp_single_end +-- +2.4.5 + diff --git a/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch b/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch new file mode 100644 index 00000000..bd7cb22f --- /dev/null +++ b/patches/vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch @@ -0,0 +1,296 @@ +From f29610acbf9ce393b772520f6041acce9d1aefd8 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 + and add tests. + +--- + dlls/vcomp/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/vcomp/tests/vcomp.c | 53 ++++++++++++++++++++++++++ + dlls/vcomp/vcomp.spec | 4 +- + dlls/vcomp100/vcomp100.spec | 4 +- + dlls/vcomp90/vcomp90.spec | 4 +- + 5 files changed, 152 insertions(+), 6 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index db47ff6..3a1e9ee 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -59,6 +59,9 @@ struct vcomp_thread_info + + /* section */ + DWORD section; ++ ++ /* dynamic */ ++ DWORD dynamic; + }; + + struct vcomp_team_info +@@ -80,6 +83,15 @@ struct vcomp_team_info + DWORD section; + DWORD num_sections; + DWORD section_index; ++ ++ /* dynamic */ ++ DWORD dynamic; ++ DWORD dynamic_forward; ++ DWORD dynamic_first; ++ DWORD dynamic_iterations; ++ int dynamic_step; ++ DWORD dynamic_chunksize; ++ 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) + 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; ++ 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) ++ { ++ /* first thread in a new for_dynamic */ ++ ++ if (forward) ++ { ++ DWORD64 last64 = last; ++ if (last64 < first) ++ last64 += 0x100000000; ++ iterations = 1 + (last64 - first) / step; ++ } ++ else ++ { ++ DWORD first64 = first; ++ if (first64 < last) ++ first64 += 0x100000000; ++ 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); ++ } ++ 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; ++ 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) ++ { ++ iterations = min(team_info->dynamic_iterations, team_info->dynamic_chunksize); ++ team_info->dynamic_iterations -= iterations; ++ ++ if (team_info->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; ++ } ++ 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; ++ } ++ ++ team_info->dynamic_chunksize = ++ max((team_info->dynamic_chunksize * 3 + 2)/4, team_info->dynamic_min_chunksize); ++ } ++ LeaveCriticalSection(&vcomp_section); ++ ++ return (iterations != 0); ++} ++ + void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); + + 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; + + /* 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; + + 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) +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 902a836..4273680 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)); + + 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) + } + + VCOMP_GET_PROC(_vcomp_barrier); ++ VCOMP_GET_PROC(_vcomp_for_dynamic_init); ++ VCOMP_GET_PROC(_vcomp_for_dynamic_next); + 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) + } + } + ++static void CDECL _test_vcomp_for_dynamic_init(LONG *a, LONG *b, LONG *c) ++{ ++ int begin, end; ++ ++ p_vcomp_for_dynamic_init(0x40, 1, 100000, 1, 30); ++ while (p_vcomp_for_dynamic_next(&begin, &end)) ++ { ++ InterlockedExchangeAdd(a, end - begin + 1); ++ Sleep(50); ++ } ++ ++ p_vcomp_for_dynamic_init(0, 1337, 1, 1, 50); ++ while (p_vcomp_for_dynamic_next(&begin, &end)) ++ { ++ InterlockedExchangeAdd(b, begin - end + 1); ++ Sleep(50); ++ } ++ ++ p_vcomp_for_dynamic_init(0x40, 1, 100000, 7, 30); ++ while (p_vcomp_for_dynamic_next(&begin, &end)) ++ { ++ while (begin <= end) ++ { ++ InterlockedIncrement(c); ++ begin += 7; ++ } ++ Sleep(50); ++ } ++} ++ ++static void test_vcomp_for_dynamic_init(void) ++{ ++ LONG a, b, c; ++ int i; ++ ++ for (i = 1; i <= 4; i++) ++ { ++ trace("Running tests with %d threads\n", i); ++ pomp_set_num_threads(i); ++ ++ a = b = c = 0; ++ p_vcomp_fork(TRUE, 3, _test_vcomp_for_dynamic_init, &a, &b, &c); ++ ok(a == 100000, "expected a = 100000, got %d\n", a); ++ ok(b == 1337, "expected b = 1337, got %d\n", b); ++ ok(c == 14286, "expected c = 14286, got %d\n", c); ++ } ++} ++ + START_TEST(vcomp) + { + if (!init_vcomp()) +@@ -593,6 +645,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); + } +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index 7083ce4..1b02a65 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -55,9 +55,9 @@ + @ stub _vcomp_copyprivate_receive + @ stub _vcomp_enter_critsect + @ stub _vcomp_flush +-@ stub _vcomp_for_dynamic_init ++@ cdecl _vcomp_for_dynamic_init(long long long long long) + @ stub _vcomp_for_dynamic_init_i8 +-@ stub _vcomp_for_dynamic_next ++@ cdecl _vcomp_for_dynamic_next(ptr ptr) + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() + @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index 56c7ae3..ab93ec2 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -55,9 +55,9 @@ + @ stub _vcomp_copyprivate_receive + @ stub _vcomp_enter_critsect + @ stub _vcomp_flush +-@ stub _vcomp_for_dynamic_init ++@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init + @ stub _vcomp_for_dynamic_init_i8 +-@ stub _vcomp_for_dynamic_next ++@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end + @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index 56c7ae3..ab93ec2 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -55,9 +55,9 @@ + @ stub _vcomp_copyprivate_receive + @ stub _vcomp_enter_critsect + @ stub _vcomp_flush +-@ stub _vcomp_for_dynamic_init ++@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init + @ stub _vcomp_for_dynamic_init_i8 +-@ stub _vcomp_for_dynamic_next ++@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next + @ stub _vcomp_for_dynamic_next_i8 + @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end + @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init +-- +2.4.5 + diff --git a/patches/vcomp-Functions/definition b/patches/vcomp-Functions/definition new file mode 100644 index 00000000..24981f0c --- /dev/null +++ b/patches/vcomp-Functions/definition @@ -0,0 +1 @@ +Fixes: [31640] Implement various vcomp functions diff --git a/patches/vcomp-Stub_Functions/0001-vcomp-single-threaded-implementation-of-_vcomp_fork.patch b/patches/vcomp-Stub_Functions/0001-vcomp-single-threaded-implementation-of-_vcomp_fork.patch deleted file mode 100644 index 29c63217..00000000 --- a/patches/vcomp-Stub_Functions/0001-vcomp-single-threaded-implementation-of-_vcomp_fork.patch +++ /dev/null @@ -1,484 +0,0 @@ -From 90156f8a04061c7d0629f46dd640c09bccb0122c Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Fri, 12 Oct 2012 22:31:39 -0700 -Subject: vcomp: single-threaded implementation of _vcomp_fork - ---- - configure.ac | 3 +- - dlls/vcomp/Makefile.in | 1 + - dlls/vcomp/fork.c | 161 ++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/tests/Makefile.in | 8 ++ - dlls/vcomp/tests/fork.c | 153 ++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/tests/vcomp.manifest | 21 ++++++ - dlls/vcomp/tests/vcomp.rc | 22 ++++++ - dlls/vcomp/vcomp.spec | 2 +- - dlls/vcomp100/vcomp100.spec | 2 +- - dlls/vcomp90/vcomp90.spec | 2 +- - 10 files changed, 371 insertions(+), 4 deletions(-) - create mode 100644 dlls/vcomp/fork.c - create mode 100644 dlls/vcomp/tests/Makefile.in - create mode 100644 dlls/vcomp/tests/fork.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 a931730..8c51410 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3290,7 +3290,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/Makefile.in b/dlls/vcomp/Makefile.in -index a54a86f..5bd0074 100644 ---- a/dlls/vcomp/Makefile.in -+++ b/dlls/vcomp/Makefile.in -@@ -1,4 +1,5 @@ - MODULE = vcomp.dll - - C_SRCS = \ -+ fork.c \ - main.c -diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c -new file mode 100644 -index 0000000..13a7b56 ---- /dev/null -+++ b/dlls/vcomp/fork.c -@@ -0,0 +1,161 @@ -+/* -+ * 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 "config.h" -+ -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(vcomp); -+ -+void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); -+ -+/* When Visual C encounters a '#pragma omp parallel' directive, -+ * it wraps the next statement in a function, and passes the address -+ * of the wrapper function to _vcomp_fork, which calls that function-- -+ * possibly after spawning extra copies on new threads. -+ * -+ * If the directive has an if() clause, the value passed to the if clause -+ * is passed as the first argument to _vcomp_fork; if it is false, -+ * or if OMP_NUM_THREADS is 1, or omp_set_num_threads(1) has been called, -+ * or if too many threads are already in use, native _vcomp_fork doesn't spawn -+ * any extra threads, it just calls the wrapper function. -+ * -+ * The OpenMP standard allows implementations to fall back to executing -+ * everything on a single thread, so that's what we'll do for now; -+ * our _vcomp_fork will simply call the wrapper function. -+ * That's enough to make many, but not all, apps run correctly. -+ * -+ * If the statement being wrapped refers to variables from an outer scope, -+ * Visual C passes them to _vcomp_fork and thence the wrapper as follows: -+ * - Unchanging ints are always passed by value -+ * - Unchanging floats are passed by value on i386, but by reference on amd64 -+ * - Everything else is passed by reference -+ * -+ * The call to _vcomp_fork is synthesized by the compiler; -+ * user code isn't even aware that a call is being made. And the callee -+ * (_vcomp_fork) is also under Visual C's control. Thus the compiler -+ * is free to use a nonstandard ABI for this call. And it does, in that -+ * float arguments are not promoted to double. (Some apps -+ * that use floats would probably be very annoyed if they were silently -+ * promoted to doubles by "#pragma omp parallel".) -+ * -+ * The call from _vcomp_fork to the wrapper function also doesn't quite -+ * follow the normal win32/win64 calling conventions: -+ * 1) Since Visual C never passes floats or doubles by value to the -+ * wrapper on amd64, native vcomp.dll does not copy floating point parameters -+ * to registers, contrary to the win64 ABI. Manual tests confirm this. -+ * 2) Since the wrapper itself doesn't use varargs at all, _vcomp_fork can't -+ * just pass an __ms_va_list; it has to push the arguments onto the stack again. -+ * This can't be done in C, so we use assembly in _vcomp_fork_call_wrapper. -+ * (That function is a close copy of call_method in oleaut32/typelib.c, -+ * with unneeded instructions removed.) -+ */ -+ -+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") -+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") -+ "movl %esp,%ebp\n\t" -+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") -+ "pushl %esi\n\t" -+ __ASM_CFI(".cfi_rel_offset %esi,-4\n\t") -+ "pushl %edi\n\t" -+ __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") -+ "movl 12(%ebp),%edx\n\t" -+ "movl %esp,%edi\n\t" -+ "shll $2,%edx\n\t" -+ "jz 1f\n\t" -+ "subl %edx,%edi\n\t" -+ "andl $~15,%edi\n\t" -+ "movl %edi,%esp\n\t" -+ "movl 12(%ebp),%ecx\n\t" -+ "movl 16(%ebp),%esi\n\t" -+ "cld\n\t" -+ "rep; movsl\n" -+ "1:\tcall *8(%ebp)\n\t" -+ "leal -8(%ebp),%esp\n\t" -+ "popl %edi\n\t" -+ __ASM_CFI(".cfi_same_value %edi\n\t") -+ "popl %esi\n\t" -+ __ASM_CFI(".cfi_same_value %esi\n\t") -+ "popl %ebp\n\t" -+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t") -+ __ASM_CFI(".cfi_same_value %ebp\n\t") -+ "ret" ) -+ -+#elif defined(__x86_64__) -+ -+__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper, -+ "pushq %rbp\n\t" -+ __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") -+ __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") -+ "movq %rsp,%rbp\n\t" -+ __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") -+ "pushq %rsi\n\t" -+ __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t") -+ "pushq %rdi\n\t" -+ __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t") -+ "movq %rcx,%rax\n\t" -+ "movq $4,%rcx\n\t" -+ "cmp %rcx,%rdx\n\t" -+ "cmovgq %rdx,%rcx\n\t" -+ "leaq 0(,%rcx,8),%rdx\n\t" -+ "subq %rdx,%rsp\n\t" -+ "andq $~15,%rsp\n\t" -+ "movq %rsp,%rdi\n\t" -+ "movq %r8,%rsi\n\t" -+ "rep; movsq\n\t" -+ "movq 0(%rsp),%rcx\n\t" -+ "movq 8(%rsp),%rdx\n\t" -+ "movq 16(%rsp),%r8\n\t" -+ "movq 24(%rsp),%r9\n\t" -+ "callq *%rax\n\t" -+ "leaq -16(%rbp),%rsp\n\t" -+ "popq %rdi\n\t" -+ __ASM_CFI(".cfi_same_value %rdi\n\t") -+ "popq %rsi\n\t" -+ __ASM_CFI(".cfi_same_value %rsi\n\t") -+ __ASM_CFI(".cfi_def_cfa_register %rsp\n\t") -+ "popq %rbp\n\t" -+ __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) -+{ -+ ERR("Not implemented for this architecture\n"); -+} -+ -+#endif -diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in -new file mode 100644 -index 0000000..81430a3 ---- /dev/null -+++ b/dlls/vcomp/tests/Makefile.in -@@ -0,0 +1,8 @@ -+TESTDLL = vcomp.dll -+IMPORTS = vcomp -+ -+C_SRCS = \ -+ fork.c -+ -+RC_SRCS = \ -+ vcomp.rc -diff --git a/dlls/vcomp/tests/fork.c b/dlls/vcomp/tests/fork.c -new file mode 100644 -index 0000000..a6f176c ---- /dev/null -+++ b/dlls/vcomp/tests/fork.c -@@ -0,0 +1,153 @@ -+/* -+ * 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 void WINAPIV (*p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); -+static int CDECL (*pomp_get_max_threads)(void); -+ -+#define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) -+ -+static BOOL init(void) -+{ -+ HMODULE vcomp = LoadLibraryA("vcomp.dll"); -+ if (!vcomp) -+ { -+ win_skip("vcomp.dll not installed\n"); -+ return FALSE; -+ } -+ -+ GETFUNC(_vcomp_fork); -+ GETFUNC(omp_get_max_threads); -+ -+ return TRUE; -+} -+ -+/* Test whether a variety of types are passed correctly. -+ * Pass five of each because the first four parameters are -+ * handled differently on amd64, and we want to test both -+ * ways. -+ */ -+ -+static void CDECL _test_vcomp_fork_ptr_worker(LONG volatile *a, LONG volatile *b, LONG volatile *c, LONG volatile *d, LONG volatile *e) -+{ -+ InterlockedIncrement(a); -+ InterlockedIncrement(b); -+ InterlockedIncrement(c); -+ InterlockedIncrement(d); -+ InterlockedIncrement(e); -+} -+ -+static void test_vcomp_fork_ptr(void) -+{ -+ LONG volatile a, b, c, d, e; -+ int n; -+ -+ /* #pragma omp parallel if(FALSE) shared(a, b, c, d, e) -+ * { InterlockedIncrement(&a); ... InterlockedIncrement(&e); } -+ */ -+ a=0; b=1; c=2; d=3; e=4; -+ p_vcomp_fork(FALSE, 5, _test_vcomp_fork_ptr_worker, &a, &b, &c, &d, &e); -+ ok(a == 1, "a == 1\n"); -+ ok(b == 2, "a == 2\n"); -+ ok(c == 3, "a == 3\n"); -+ ok(d == 4, "a == 4\n"); -+ ok(e == 5, "a == 5\n"); -+ -+ /* #pragma omp parallel if(TRUE) shared(a, b, c, d, e) -+ * { InterlockedIncrement(&a); ... InterlockedIncrement(&e); } -+ */ -+ a=0; b=1; c=2; d=3; e=4; -+ n = pomp_get_max_threads(); -+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_ptr_worker, &a, &b, &c, &d, &e); -+ ok(a > 0 && a <= (n+0), "a > 0 && a <= (n+0)\n"); -+ ok(b > 1 && b <= (n+1), "b > 1 && b <= (n+1)\n"); -+ ok(c > 2 && c <= (n+2), "c > 2 && c <= (n+2)\n"); -+ ok(d > 3 && d <= (n+3), "d > 3 && d <= (n+3)\n"); -+ ok(e > 4 && e <= (n+4), "e > 4 && e <= (n+4)\n"); -+} -+ -+static void CDECL _test_vcomp_fork_uintptr_worker(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e) -+{ -+ ok(a == 1, "expected a == 1\n"); -+ ok(b == MAXUINT_PTR-2, "expected b == MAXUINT_PTR-2\n"); -+ ok(c == 3, "expected c == 3\n"); -+ ok(d == MAXUINT_PTR-4, "expected d == MAXUINT_PTR-4\n"); -+ ok(e == 5, "expected e == 5\n"); -+} -+ -+static void test_vcomp_fork_uintptr(void) -+{ -+ /* test_vcomp_fork_ptr ought to have been enough, but probably -+ * didn't vary all the bits of the high word, so do that here. -+ */ -+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_uintptr_worker, \ -+ (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR-2), \ -+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR)-4, (UINT_PTR) 5); -+} -+ -+static void CDECL _test_vcomp_fork_float_worker(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_float(void) -+{ -+ static void CDECL (*p_vcomp_fork_f5)(BOOL, int, void *, float, float, float, float, float); -+ -+ if (is_win64) -+ { -+ skip("Skipping float test on x86_64.\n"); -+ return; -+ } -+ -+ /* -+ * 32 bit Visual C sometimes passes 32 bit floats by value to -+ * the wrapper, so verify that here. -+ * -+ * x86-64 Visual C has not yet been observed passing 32 bit floats by -+ * value to the wrapper, and indeed _vcomp_fork does not even copy the -+ * first four args to floating point registers, so this test fails -+ * on x86-64 for the first four arguments even on native. -+ * Therefore don't run it. (It's hard to write a reliable test to show -+ * this, since the floating point registers might just happen -+ * to have the right values once in a blue moon.) -+ */ -+ -+ /* Avoid float promotion by using a prototype tailored for this call */ -+ p_vcomp_fork_f5 = (void *)p_vcomp_fork; -+ p_vcomp_fork_f5(TRUE, 5, _test_vcomp_fork_float_worker, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f); -+} -+ -+START_TEST(fork) -+{ -+ if (!init()) -+ return; -+ -+ test_vcomp_fork_ptr(); -+ test_vcomp_fork_uintptr(); -+ test_vcomp_fork_float(); -+} -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 -diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec -index 306dd15..d446574 100644 ---- a/dlls/vcomp/vcomp.spec -+++ b/dlls/vcomp/vcomp.spec -@@ -64,7 +64,7 @@ - @ stub _vcomp_for_static_init_i8 - @ stub _vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 --@ stub _vcomp_fork -+@ varargs _vcomp_fork(long long ptr) - @ stub _vcomp_get_thread_num - @ stub _vcomp_leave_critsect - @ stub _vcomp_master_barrier -diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec -index 39cf91c..2c04e91 100644 ---- a/dlls/vcomp100/vcomp100.spec -+++ b/dlls/vcomp100/vcomp100.spec -@@ -64,7 +64,7 @@ - @ stub _vcomp_for_static_init_i8 - @ stub _vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 --@ stub _vcomp_fork -+@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork - @ stub _vcomp_get_thread_num - @ stub _vcomp_leave_critsect - @ stub _vcomp_master_barrier -diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec -index 39cf91c..2c04e91 100644 ---- a/dlls/vcomp90/vcomp90.spec -+++ b/dlls/vcomp90/vcomp90.spec -@@ -64,7 +64,7 @@ - @ stub _vcomp_for_static_init_i8 - @ stub _vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 --@ stub _vcomp_fork -+@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork - @ stub _vcomp_get_thread_num - @ stub _vcomp_leave_critsect - @ stub _vcomp_master_barrier --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/0002-vcomp-better-stubs-for-_vcomp_for_static_simple_init.patch b/patches/vcomp-Stub_Functions/0002-vcomp-better-stubs-for-_vcomp_for_static_simple_init.patch deleted file mode 100644 index a977684f..00000000 --- a/patches/vcomp-Stub_Functions/0002-vcomp-better-stubs-for-_vcomp_for_static_simple_init.patch +++ /dev/null @@ -1,233 +0,0 @@ -From c0369b34efc51c992be270a9e4eaef33b3cbf3d5 Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Sun, 14 Oct 2012 20:40:31 -0700 -Subject: vcomp: better stubs for _vcomp_for_static_simple_init, - _vcomp_for_static_end - ---- - dlls/vcomp/Makefile.in | 3 +- - dlls/vcomp/tests/Makefile.in | 3 +- - dlls/vcomp/tests/work.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/vcomp.spec | 4 +-- - dlls/vcomp/work.c | 41 ++++++++++++++++++++++ - dlls/vcomp100/vcomp100.spec | 4 +-- - dlls/vcomp90/vcomp90.spec | 4 +-- - 7 files changed, 134 insertions(+), 8 deletions(-) - create mode 100644 dlls/vcomp/tests/work.c - create mode 100644 dlls/vcomp/work.c - -diff --git a/dlls/vcomp/Makefile.in b/dlls/vcomp/Makefile.in -index 5bd0074..dfff21a 100644 ---- a/dlls/vcomp/Makefile.in -+++ b/dlls/vcomp/Makefile.in -@@ -2,4 +2,5 @@ MODULE = vcomp.dll - - C_SRCS = \ - fork.c \ -- main.c -+ main.c \ -+ work.c -diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in -index 81430a3..f1479ab 100644 ---- a/dlls/vcomp/tests/Makefile.in -+++ b/dlls/vcomp/tests/Makefile.in -@@ -2,7 +2,8 @@ TESTDLL = vcomp.dll - IMPORTS = vcomp - - C_SRCS = \ -- fork.c -+ fork.c \ -+ work.c - - RC_SRCS = \ - vcomp.rc -diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c -new file mode 100644 -index 0000000..e8d3f2c ---- /dev/null -+++ b/dlls/vcomp/tests/work.c -@@ -0,0 +1,83 @@ -+/* -+ * Unit test suite for vcomp work-sharing 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 void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...); -+static void CDECL (*p_vcomp_for_static_end)(void); -+static void CDECL (*p_vcomp_for_static_simple_init)(int first, int last, int mystep, int step, int *pfirst, int *plast); -+ -+#define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) -+ -+static BOOL init(void) -+{ -+ HMODULE vcomp = LoadLibraryA("vcomp.dll"); -+ if (!vcomp) -+ { -+ win_skip("vcomp.dll not installed\n"); -+ return FALSE; -+ } -+ -+ GETFUNC(_vcomp_fork); -+ GETFUNC(_vcomp_for_static_end); -+ GETFUNC(_vcomp_for_static_simple_init); -+ -+ return TRUE; -+} -+ -+static LONG volatile ncalls; -+static LONG volatile nsum; -+ -+static void CDECL _test_vcomp_for_static_simple_init_worker(void) -+{ -+ int i, my_limit; -+ -+ InterlockedIncrement(&ncalls); -+ -+ /* for (i=0; i<=12; i++) */ -+ p_vcomp_for_static_simple_init(0, 12, 1, 1, &i, &my_limit); -+ -+ while (i <= my_limit) -+ { -+ int j; -+ for (j=0; j= 1, "expected >= 1 call, got %d\n", ncalls); -+ ok(nsum == 6*13, "expected sum 6*13, got %d\n", nsum); -+} -+ -+START_TEST(work) -+{ -+ if (!init()) -+ return; -+ -+ test_vcomp_for_static_simple_init(); -+} -diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec -index d446574..b14edca 100644 ---- a/dlls/vcomp/vcomp.spec -+++ b/dlls/vcomp/vcomp.spec -@@ -59,10 +59,10 @@ - @ stub _vcomp_for_dynamic_init_i8 - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 --@ stub _vcomp_for_static_end -+@ cdecl _vcomp_for_static_end() - @ stub _vcomp_for_static_init - @ stub _vcomp_for_static_init_i8 --@ stub _vcomp_for_static_simple_init -+@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) - @ stub _vcomp_for_static_simple_init_i8 - @ varargs _vcomp_fork(long long ptr) - @ stub _vcomp_get_thread_num -diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c -new file mode 100644 -index 0000000..0f9ff78 ---- /dev/null -+++ b/dlls/vcomp/work.c -@@ -0,0 +1,41 @@ -+/* -+ * vcomp work-sharing 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 "config.h" -+ -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(vcomp); -+ -+void CDECL _vcomp_for_static_simple_init(int first, int last, int mystep, int step, int *pfirst, int *plast) -+{ -+ TRACE("(%d, %d, %d, %d, %p, %p): stub\n", first, last, mystep, step, pfirst, plast); -+ *pfirst = first; -+ *plast = last; -+} -+ -+void CDECL _vcomp_for_static_end(void) -+{ -+ TRACE("stub\n"); -+} -diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec -index 2c04e91..89e0972 100644 ---- a/dlls/vcomp100/vcomp100.spec -+++ b/dlls/vcomp100/vcomp100.spec -@@ -59,10 +59,10 @@ - @ stub _vcomp_for_dynamic_init_i8 - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 --@ stub _vcomp_for_static_end -+@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end - @ stub _vcomp_for_static_init - @ stub _vcomp_for_static_init_i8 --@ stub _vcomp_for_static_simple_init -+@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 - @ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork - @ stub _vcomp_get_thread_num -diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec -index 2c04e91..89e0972 100644 ---- a/dlls/vcomp90/vcomp90.spec -+++ b/dlls/vcomp90/vcomp90.spec -@@ -59,10 +59,10 @@ - @ stub _vcomp_for_dynamic_init_i8 - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 --@ stub _vcomp_for_static_end -+@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end - @ stub _vcomp_for_static_init - @ stub _vcomp_for_static_init_i8 --@ stub _vcomp_for_static_simple_init -+@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 - @ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork - @ stub _vcomp_get_thread_num --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/0003-vcomp-better-stub-for-_vcomp_for_static_init.patch b/patches/vcomp-Stub_Functions/0003-vcomp-better-stub-for-_vcomp_for_static_init.patch deleted file mode 100644 index b71574d3..00000000 --- a/patches/vcomp-Stub_Functions/0003-vcomp-better-stub-for-_vcomp_for_static_init.patch +++ /dev/null @@ -1,153 +0,0 @@ -From fadfe0d8a2483066f6f0137b2fb6d6efa3090db8 Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Sun, 14 Oct 2012 20:42:35 -0700 -Subject: vcomp: better stub for _vcomp_for_static_init - ---- - dlls/vcomp/tests/work.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/vcomp.spec | 2 +- - dlls/vcomp/work.c | 11 +++++++++++ - dlls/vcomp100/vcomp100.spec | 2 +- - dlls/vcomp90/vcomp90.spec | 2 +- - 5 files changed, 59 insertions(+), 3 deletions(-) - -diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c -index e8d3f2c..2a76227 100644 ---- a/dlls/vcomp/tests/work.c -+++ b/dlls/vcomp/tests/work.c -@@ -22,6 +22,7 @@ - - static void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...); - static void CDECL (*p_vcomp_for_static_end)(void); -+static void CDECL (*p_vcomp_for_static_init)(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart); - static void CDECL (*p_vcomp_for_static_simple_init)(int first, int last, int mystep, int step, int *pfirst, int *plast); - - #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) -@@ -37,6 +38,7 @@ static BOOL init(void) - - GETFUNC(_vcomp_fork); - GETFUNC(_vcomp_for_static_end); -+ GETFUNC(_vcomp_for_static_init); - GETFUNC(_vcomp_for_static_simple_init); - - return TRUE; -@@ -45,6 +47,48 @@ static BOOL init(void) - static LONG volatile ncalls; - static LONG volatile nsum; - -+static void CDECL _test_vcomp_for_static_init_worker(void) -+{ -+ const int my_start = 0; -+ const int my_end = 12; -+ const int my_incr = 1; -+ const int my_chunksize = 1; -+ int nloops, chunkstart, chunkend, chunksize, finalchunkstart; -+ -+ InterlockedIncrement(&ncalls); -+ -+ /* for (i=0; i<=12; i++) */ -+ p_vcomp_for_static_init(my_start, my_end, my_incr, my_chunksize, -+ &nloops, &chunkstart, &chunkend, &chunksize, &finalchunkstart); -+ -+ do -+ { -+ int i; -+ if (chunkstart == finalchunkstart) chunkend = my_end; -+ -+ for (i=chunkstart; i <= chunkend; i += my_incr) -+ { -+ int j; -+ for (j=0; j 0); -+ -+ p_vcomp_for_static_end(); -+} -+ -+static void test_vcomp_for_static_init(void) -+{ -+ ncalls = 0; -+ nsum = 0; -+ p_vcomp_fork(1, 0, _test_vcomp_for_static_init_worker); -+ ok(ncalls >= 1, "expected >= 1 call, got %d\n", ncalls); -+ ok(nsum == 6*13, "expected sum 6*13, got %d\n", nsum); -+} -+ - static void CDECL _test_vcomp_for_static_simple_init_worker(void) - { - int i, my_limit; -@@ -79,5 +123,6 @@ START_TEST(work) - if (!init()) - return; - -+ test_vcomp_for_static_init(); - test_vcomp_for_static_simple_init(); - } -diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec -index b14edca..8bc66e8 100644 ---- a/dlls/vcomp/vcomp.spec -+++ b/dlls/vcomp/vcomp.spec -@@ -60,7 +60,7 @@ - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() --@ stub _vcomp_for_static_init -+@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) - @ stub _vcomp_for_static_init_i8 - @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) - @ stub _vcomp_for_static_simple_init_i8 -diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c -index 0f9ff78..82df26e 100644 ---- a/dlls/vcomp/work.c -+++ b/dlls/vcomp/work.c -@@ -28,6 +28,17 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - -+void CDECL _vcomp_for_static_init(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart) -+{ -+ TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p): stub\n", -+ first, last, mystep, chunksize, pnloops, pfirst, plast, pchunksize, pfinalchunkstart); -+ *pfirst = first; -+ *plast = last; -+ *pfinalchunkstart = last; -+ *pnloops = 1; -+ *pchunksize = 0; /* moot, since nloops=1 */ -+} -+ - void CDECL _vcomp_for_static_simple_init(int first, int last, int mystep, int step, int *pfirst, int *plast) - { - TRACE("(%d, %d, %d, %d, %p, %p): stub\n", first, last, mystep, step, pfirst, plast); -diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec -index 89e0972..f008e2e 100644 ---- a/dlls/vcomp100/vcomp100.spec -+++ b/dlls/vcomp100/vcomp100.spec -@@ -60,7 +60,7 @@ - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end --@ stub _vcomp_for_static_init -+@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init - @ stub _vcomp_for_static_init_i8 - @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 -diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec -index 89e0972..f008e2e 100644 ---- a/dlls/vcomp90/vcomp90.spec -+++ b/dlls/vcomp90/vcomp90.spec -@@ -60,7 +60,7 @@ - @ stub _vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end --@ stub _vcomp_for_static_init -+@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init - @ stub _vcomp_for_static_init_i8 - @ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init - @ stub _vcomp_for_static_simple_init_i8 --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/0004-vcomp-implement-omp_in_parallel.patch b/patches/vcomp-Stub_Functions/0004-vcomp-implement-omp_in_parallel.patch deleted file mode 100644 index 9539d196..00000000 --- a/patches/vcomp-Stub_Functions/0004-vcomp-implement-omp_in_parallel.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 659f7394d0c3e4c969e0b0f66689433fd133febd Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Wed, 17 Oct 2012 09:15:06 -0700 -Subject: vcomp: implement omp_in_parallel - ---- - dlls/vcomp/fork.c | 32 +++++++++++++++++++++++++++++ - dlls/vcomp/main.c | 12 +++++++++++ - dlls/vcomp/tests/fork.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/vcomp.spec | 2 +- - dlls/vcomp/vcomp_private.h | 19 +++++++++++++++++ - dlls/vcomp100/vcomp100.spec | 2 +- - dlls/vcomp90/vcomp90.spec | 2 +- - 7 files changed, 116 insertions(+), 3 deletions(-) - create mode 100644 dlls/vcomp/vcomp_private.h - -diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c -index 13a7b56..49399c6 100644 ---- a/dlls/vcomp/fork.c -+++ b/dlls/vcomp/fork.c -@@ -25,6 +25,22 @@ - #include "windef.h" - #include "winbase.h" - #include "wine/debug.h" -+#include "vcomp_private.h" -+ -+struct vcomp_team -+{ -+ struct vcomp_team *parent; -+}; -+ -+static inline struct vcomp_team *vcomp_get_team(void) -+{ -+ return (struct vcomp_team *)TlsGetValue(vcomp_context_tls); -+} -+ -+static inline void vcomp_set_team(struct vcomp_team *team) -+{ -+ TlsSetValue(vcomp_context_tls, team); -+} - - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - -@@ -75,10 +91,18 @@ 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; -+ struct vcomp_team team; -+ - TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper); -+ -+ team.parent = vcomp_get_team(); -+ vcomp_set_team(&team); -+ - __ms_va_start(valist, wrapper); - _vcomp_fork_call_wrapper(wrapper, nargs, valist); - __ms_va_end(valist); -+ -+ vcomp_set_team(team.parent); - } - - #if defined(__i386__) -@@ -159,3 +183,11 @@ void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args) - } - - #endif -+ -+int CDECL omp_in_parallel(void) -+{ -+ int val = (vcomp_get_team() != NULL); -+ -+ TRACE("returning %d\n", val); -+ return val; -+} -diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index ab2a372..e37cf16 100644 ---- a/dlls/vcomp/main.c -+++ b/dlls/vcomp/main.c -@@ -26,9 +26,12 @@ - #include "windef.h" - #include "winbase.h" - #include "wine/debug.h" -+#include "vcomp_private.h" - - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - -+DWORD vcomp_context_tls; -+ - int CDECL omp_get_dynamic(void) - { - TRACE("stub\n"); -@@ -117,6 +120,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - 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; - } - -diff --git a/dlls/vcomp/tests/fork.c b/dlls/vcomp/tests/fork.c -index a6f176c..3d11504 100644 ---- a/dlls/vcomp/tests/fork.c -+++ b/dlls/vcomp/tests/fork.c -@@ -24,6 +24,9 @@ static const int is_win64 = (sizeof(void *) > sizeof(int)); - - static void WINAPIV (*p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...); - static int CDECL (*pomp_get_max_threads)(void); -+static int CDECL (*pomp_get_num_threads)(void); -+static int CDECL (*pomp_in_parallel)(void); -+static void CDECL (*pomp_set_num_threads)(int); - - #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) - -@@ -36,6 +39,9 @@ static BOOL init(void) - return FALSE; - } - -+ GETFUNC(omp_get_num_threads); -+ GETFUNC(omp_in_parallel); -+ GETFUNC(omp_set_num_threads); - GETFUNC(_vcomp_fork); - GETFUNC(omp_get_max_threads); - -@@ -142,6 +148,49 @@ static void test_vcomp_fork_float(void) - p_vcomp_fork_f5(TRUE, 5, _test_vcomp_fork_float_worker, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f); - } - -+#define NLOOPS_SHORT 5 -+#define SLEEP_MS_SHORT 50 -+ -+static void CDECL _test_omp_in_parallel_nested_worker(LONG volatile *psum) -+{ -+ if (pomp_in_parallel()) -+ InterlockedIncrement(psum); -+} -+ -+static void CDECL _test_omp_in_parallel_worker(LONG volatile *psum) -+{ -+ int i; -+ InterlockedIncrement(psum); -+ for (i=0; i -Date: Mon, 15 Oct 2012 21:01:30 -0700 -Subject: vcomp: better stubs for _vcomp_for_dynamic_init, - _vcomp_for_dynamic_next - ---- - dlls/vcomp/fork.c | 15 ----------- - dlls/vcomp/tests/work.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ - dlls/vcomp/vcomp.spec | 4 +-- - dlls/vcomp/vcomp_private.h | 37 +++++++++++++++++++++++++ - dlls/vcomp/work.c | 47 ++++++++++++++++++++++++++++++++ - dlls/vcomp100/vcomp100.spec | 4 +-- - dlls/vcomp90/vcomp90.spec | 4 +-- - 7 files changed, 156 insertions(+), 21 deletions(-) - -diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c -index 49399c6..5af2021 100644 ---- a/dlls/vcomp/fork.c -+++ b/dlls/vcomp/fork.c -@@ -27,21 +27,6 @@ - #include "wine/debug.h" - #include "vcomp_private.h" - --struct vcomp_team --{ -- struct vcomp_team *parent; --}; -- --static inline struct vcomp_team *vcomp_get_team(void) --{ -- return (struct vcomp_team *)TlsGetValue(vcomp_context_tls); --} -- --static inline void vcomp_set_team(struct vcomp_team *team) --{ -- TlsSetValue(vcomp_context_tls, team); --} -- - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - - void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args); -diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c -index 2a76227..5abe0e1 100644 ---- a/dlls/vcomp/tests/work.c -+++ b/dlls/vcomp/tests/work.c -@@ -21,12 +21,18 @@ - #include "wine/test.h" - - static void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...); -+static void CDECL (*p_vcomp_for_dynamic_init)(int flags, int first, int last, int mystep, int chunksize); -+static int CDECL (*p_vcomp_for_dynamic_next)(int *pcounter, int *pchunklimit); - static void CDECL (*p_vcomp_for_static_end)(void); - static void CDECL (*p_vcomp_for_static_init)(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart); - static void CDECL (*p_vcomp_for_static_simple_init)(int first, int last, int mystep, int step, int *pfirst, int *plast); - - #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) - -+/* Matches definitions in ../vcomp_private.h */ -+#define VCOMP_DYNAMIC_FOR_FLAGS_DOWN 0x0 -+#define VCOMP_DYNAMIC_FOR_FLAGS_UP 0x40 -+ - static BOOL init(void) - { - HMODULE vcomp = LoadLibraryA("vcomp.dll"); -@@ -37,6 +43,8 @@ static BOOL init(void) - } - - GETFUNC(_vcomp_fork); -+ GETFUNC(_vcomp_for_dynamic_init); -+ GETFUNC(_vcomp_for_dynamic_next); - GETFUNC(_vcomp_for_static_end); - GETFUNC(_vcomp_for_static_init); - GETFUNC(_vcomp_for_static_simple_init); -@@ -47,6 +55,63 @@ static BOOL init(void) - static LONG volatile ncalls; - static LONG volatile nsum; - -+static void CDECL _test_vcomp_for_dynamic_worker_up(void) -+{ -+ int i, limit; -+ -+ InterlockedIncrement(&ncalls); -+ -+ /* pragma omp schedule(dynamic,16) */ -+ /* for (i=0; i<=17; i++) */ -+ p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FOR_FLAGS_UP, 0, 17, 1, 16); -+ while (p_vcomp_for_dynamic_next(&i, &limit)) -+ { -+ for (; i<=limit; i++) -+ { -+ int j; -+ for (j=0; j=0; i--) */ -+ p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FOR_FLAGS_DOWN, 17, 0, 1, 16); -+ while (p_vcomp_for_dynamic_next(&i, &limit)) -+ { -+ for (; i>=limit; i--) -+ { -+ int j; -+ for (j=0; j= 1, "expected >= 1 call, got %d\n", ncalls); -+ ok(nsum == 9*17, "expected sum 9*17, got %d\n", nsum); -+ -+ /* for (i=17; i>=0; i--) nsum += i; */ -+ ncalls = 0; -+ nsum = 0; -+ p_vcomp_fork(1, 0, _test_vcomp_for_dynamic_worker_down); -+ ok(ncalls >= 1, "expected >= 1 call, got %d\n", ncalls); -+ ok(nsum == 9*17, "expected sum 9*17, got %d\n", nsum); -+} -+ - static void CDECL _test_vcomp_for_static_init_worker(void) - { - const int my_start = 0; -@@ -123,6 +188,7 @@ START_TEST(work) - if (!init()) - return; - -+ test_vcomp_for_dynamic(); - test_vcomp_for_static_init(); - test_vcomp_for_static_simple_init(); - } -diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec -index 156233f..f603660 100644 ---- a/dlls/vcomp/vcomp.spec -+++ b/dlls/vcomp/vcomp.spec -@@ -55,9 +55,9 @@ - @ stub _vcomp_copyprivate_receive - @ stub _vcomp_enter_critsect - @ stub _vcomp_flush --@ stub _vcomp_for_dynamic_init -+@ cdecl _vcomp_for_dynamic_init(long long long long long) - @ stub _vcomp_for_dynamic_init_i8 --@ stub _vcomp_for_dynamic_next -+@ cdecl _vcomp_for_dynamic_next(ptr ptr) - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() - @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) -diff --git a/dlls/vcomp/vcomp_private.h b/dlls/vcomp/vcomp_private.h -index 50c4643..d3a7005 100644 ---- a/dlls/vcomp/vcomp_private.h -+++ b/dlls/vcomp/vcomp_private.h -@@ -1,4 +1,7 @@ - /* -+ * vcmp wine internal private include file -+ * -+ * Copyright 2012 Dan Kegel - * Copyright 2015 Sebastian Lackner - * - * This library is free software; you can redistribute it and/or -@@ -16,4 +19,38 @@ - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -+#ifndef __WINE_VCOMP_PRIVATE_H -+#define __WINE_VCOMP_PRIVATE_H -+ -+struct vcomp_team -+{ -+ struct vcomp_team *parent; -+ union -+ { -+ struct -+ { -+ int counter; -+ int step; -+ int iterations_remaining; -+ int chunksize; -+ int flags; -+ } dyn_for; -+ } work; -+}; -+ - extern DWORD vcomp_context_tls DECLSPEC_HIDDEN; -+ -+static inline struct vcomp_team *vcomp_get_team(void) -+{ -+ return (struct vcomp_team *)TlsGetValue(vcomp_context_tls); -+} -+ -+static inline void vcomp_set_team(struct vcomp_team *team) -+{ -+ TlsSetValue(vcomp_context_tls, team); -+} -+ -+#define VCOMP_DYNAMIC_FOR_FLAGS_DOWN 0x0 -+#define VCOMP_DYNAMIC_FOR_FLAGS_UP 0x40 -+ -+#endif -diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c -index 82df26e..87bce93 100644 ---- a/dlls/vcomp/work.c -+++ b/dlls/vcomp/work.c -@@ -25,9 +25,56 @@ - #include "windef.h" - #include "winbase.h" - #include "wine/debug.h" -+#include "vcomp_private.h" - - WINE_DEFAULT_DEBUG_CHANNEL(vcomp); - -+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int mystep, int chunksize) -+{ -+ struct vcomp_team *pt = vcomp_get_team(); -+ -+ TRACE("(%d, %d, %d, %d, %d): stub\n", flags, first, last, mystep, chunksize); -+ -+ pt->work.dyn_for.counter = first; -+ pt->work.dyn_for.chunksize = chunksize; -+ pt->work.dyn_for.flags = flags; -+ pt->work.dyn_for.step = mystep; -+ if (flags & VCOMP_DYNAMIC_FOR_FLAGS_UP) -+ pt->work.dyn_for.iterations_remaining = 1 + (last - first) / mystep; -+ else -+ pt->work.dyn_for.iterations_remaining = 1 + (first - last) / mystep; -+} -+ -+int CDECL _vcomp_for_dynamic_next(int *pcounter, int *pchunklimit) -+{ -+ struct vcomp_team *pt = vcomp_get_team(); -+ int n; -+ -+ TRACE("(%p, %p): stub.\n", pcounter, pchunklimit); -+ -+ n = pt->work.dyn_for.chunksize; -+ if (n > pt->work.dyn_for.iterations_remaining) -+ n = pt->work.dyn_for.iterations_remaining; -+ -+ *pcounter = pt->work.dyn_for.counter; -+ -+ if (pt->work.dyn_for.flags & VCOMP_DYNAMIC_FOR_FLAGS_UP) -+ { -+ pt->work.dyn_for.counter += pt->work.dyn_for.step * n; -+ *pchunklimit = pt->work.dyn_for.counter - 1; -+ } -+ else -+ { -+ pt->work.dyn_for.counter -= pt->work.dyn_for.step * n; -+ *pchunklimit = pt->work.dyn_for.counter + 1; -+ } -+ pt->work.dyn_for.iterations_remaining -= n; -+ -+ TRACE("counter %d, iterations_remaining %d, n %d, returning %d\n", -+ pt->work.dyn_for.counter, pt->work.dyn_for.iterations_remaining, n, (n > 0)); -+ return (n > 0); -+} -+ - void CDECL _vcomp_for_static_init(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart) - { - TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p): stub\n", -diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec -index dd276d0..48d5e3f 100644 ---- a/dlls/vcomp100/vcomp100.spec -+++ b/dlls/vcomp100/vcomp100.spec -@@ -55,9 +55,9 @@ - @ stub _vcomp_copyprivate_receive - @ stub _vcomp_enter_critsect - @ stub _vcomp_flush --@ stub _vcomp_for_dynamic_init -+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init - @ stub _vcomp_for_dynamic_init_i8 --@ stub _vcomp_for_dynamic_next -+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end - @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init -diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec -index dd276d0..48d5e3f 100644 ---- a/dlls/vcomp90/vcomp90.spec -+++ b/dlls/vcomp90/vcomp90.spec -@@ -55,9 +55,9 @@ - @ stub _vcomp_copyprivate_receive - @ stub _vcomp_enter_critsect - @ stub _vcomp_flush --@ stub _vcomp_for_dynamic_init -+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init - @ stub _vcomp_for_dynamic_init_i8 --@ stub _vcomp_for_dynamic_next -+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next - @ stub _vcomp_for_dynamic_next_i8 - @ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end - @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/0006-vcomp-better-stubs-for-_vcomp_sections_init-_vcomp_s.patch b/patches/vcomp-Stub_Functions/0006-vcomp-better-stubs-for-_vcomp_sections_init-_vcomp_s.patch deleted file mode 100644 index 6cebf0e7..00000000 --- a/patches/vcomp-Stub_Functions/0006-vcomp-better-stubs-for-_vcomp_sections_init-_vcomp_s.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 8069c24409570d48c59bb103539d1ea1fd835c36 Mon Sep 17 00:00:00 2001 -From: Dan Kegel -Date: Mon, 15 Oct 2012 21:09:56 -0700 -Subject: vcomp: better stubs for _vcomp_sections_init, _vcomp_sections_next - ---- - dlls/vcomp/tests/work.c | 34 ++++++++++++++++++++++++++++++++++ - dlls/vcomp/vcomp.spec | 4 ++-- - dlls/vcomp/vcomp_private.h | 5 +++++ - dlls/vcomp/work.c | 18 ++++++++++++++++++ - dlls/vcomp100/vcomp100.spec | 4 ++-- - dlls/vcomp90/vcomp90.spec | 4 ++-- - 6 files changed, 63 insertions(+), 6 deletions(-) - -diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c -index 5abe0e1..981f741 100644 ---- a/dlls/vcomp/tests/work.c -+++ b/dlls/vcomp/tests/work.c -@@ -20,12 +20,15 @@ - - #include "wine/test.h" - -+static void WINAPIV (*p_vcomp_barrier)(void); - static void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...); - static void CDECL (*p_vcomp_for_dynamic_init)(int flags, int first, int last, int mystep, int chunksize); - static int CDECL (*p_vcomp_for_dynamic_next)(int *pcounter, int *pchunklimit); - static void CDECL (*p_vcomp_for_static_end)(void); - static void CDECL (*p_vcomp_for_static_init)(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart); - static void CDECL (*p_vcomp_for_static_simple_init)(int first, int last, int mystep, int step, int *pfirst, int *plast); -+static void CDECL (*p_vcomp_sections_init)(int n); -+static int CDECL (*p_vcomp_sections_next)(void); - - #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0) - -@@ -42,12 +45,15 @@ static BOOL init(void) - return FALSE; - } - -+ GETFUNC(_vcomp_barrier); - GETFUNC(_vcomp_fork); - GETFUNC(_vcomp_for_dynamic_init); - GETFUNC(_vcomp_for_dynamic_next); - GETFUNC(_vcomp_for_static_end); - GETFUNC(_vcomp_for_static_init); - GETFUNC(_vcomp_for_static_simple_init); -+ GETFUNC(_vcomp_sections_init); -+ GETFUNC(_vcomp_sections_next); - - return TRUE; - } -@@ -183,6 +189,33 @@ static void test_vcomp_for_static_simple_init(void) - ok(nsum == 6*13, "expected sum 6*13, got %d\n", nsum); - } - -+int section_calls[3]; -+ -+static void CDECL _test_vcomp_sections_worker(void) -+{ -+ p_vcomp_sections_init(3); -+ -+ for (;;) -+ { -+ int i = p_vcomp_sections_next(); -+ if (i < 0 || i >= 3) break; -+ section_calls[i]++; -+ } -+ -+ p_vcomp_barrier(); -+} -+ -+static void test_vcomp_sections(void) -+{ -+ section_calls[0] = 0; -+ section_calls[1] = 0; -+ section_calls[2] = 0; -+ p_vcomp_fork(1, 0, _test_vcomp_sections_worker); -+ ok(section_calls[0] == 1, "section 0 not called once\n"); -+ ok(section_calls[1] == 1, "section 1 not called once\n"); -+ ok(section_calls[2] == 1, "section 2 not called once\n"); -+} -+ - START_TEST(work) - { - if (!init()) -@@ -191,4 +224,5 @@ START_TEST(work) - test_vcomp_for_dynamic(); - test_vcomp_for_static_init(); - test_vcomp_for_static_simple_init(); -+ test_vcomp_sections(); - } -diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec -index f603660..1b02a65 100644 ---- a/dlls/vcomp/vcomp.spec -+++ b/dlls/vcomp/vcomp.spec -@@ -83,8 +83,8 @@ - @ stub _vcomp_reduction_u2 - @ stub _vcomp_reduction_u4 - @ stub _vcomp_reduction_u8 --@ stub _vcomp_sections_init --@ stub _vcomp_sections_next -+@ cdecl _vcomp_sections_init(long) -+@ cdecl _vcomp_sections_next() - @ cdecl _vcomp_set_num_threads(long) - @ cdecl _vcomp_single_begin(long) - @ cdecl _vcomp_single_end() -diff --git a/dlls/vcomp/vcomp_private.h b/dlls/vcomp/vcomp_private.h -index d3a7005..3d6c22b 100644 ---- a/dlls/vcomp/vcomp_private.h -+++ b/dlls/vcomp/vcomp_private.h -@@ -35,6 +35,11 @@ struct vcomp_team - int chunksize; - int flags; - } dyn_for; -+ struct -+ { -+ int counter; -+ int nsect; -+ } sections; - } work; - }; - -diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c -index 87bce93..4370ec5 100644 ---- a/dlls/vcomp/work.c -+++ b/dlls/vcomp/work.c -@@ -97,3 +97,21 @@ void CDECL _vcomp_for_static_end(void) - { - TRACE("stub\n"); - } -+ -+void CDECL _vcomp_sections_init(int n) -+{ -+ struct vcomp_team *pt = vcomp_get_team(); -+ TRACE("(%d): stub\n", n); -+ pt->work.sections.counter = 0; -+ pt->work.sections.nsect = n; -+} -+ -+int CDECL _vcomp_sections_next(void) -+{ -+ struct vcomp_team *pt = vcomp_get_team(); -+ int i = pt->work.sections.counter++; -+ if (i >= pt->work.sections.nsect) -+ i = -1; -+ TRACE("stub; returning %d\n", i); -+ return i; -+} -diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec -index 48d5e3f..ab93ec2 100644 ---- a/dlls/vcomp100/vcomp100.spec -+++ b/dlls/vcomp100/vcomp100.spec -@@ -83,8 +83,8 @@ - @ stub _vcomp_reduction_u2 - @ stub _vcomp_reduction_u4 - @ stub _vcomp_reduction_u8 --@ stub _vcomp_sections_init --@ stub _vcomp_sections_next -+@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init -+@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next - @ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads - @ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin - @ cdecl _vcomp_single_end() vcomp._vcomp_single_end -diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec -index 48d5e3f..ab93ec2 100644 ---- a/dlls/vcomp90/vcomp90.spec -+++ b/dlls/vcomp90/vcomp90.spec -@@ -83,8 +83,8 @@ - @ stub _vcomp_reduction_u2 - @ stub _vcomp_reduction_u4 - @ stub _vcomp_reduction_u8 --@ stub _vcomp_sections_init --@ stub _vcomp_sections_next -+@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init -+@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next - @ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads - @ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin - @ cdecl _vcomp_single_end() vcomp._vcomp_single_end --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/0007-vcomp-Add-a-warning-that-multithreading-is-not-yet-s.patch b/patches/vcomp-Stub_Functions/0007-vcomp-Add-a-warning-that-multithreading-is-not-yet-s.patch deleted file mode 100644 index 8ac2a8df..00000000 --- a/patches/vcomp-Stub_Functions/0007-vcomp-Add-a-warning-that-multithreading-is-not-yet-s.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 5748aa15dd5e619714e9a04a033b30bd1fdae7d7 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 29 Jan 2015 00:18:47 +0100 -Subject: vcomp: Add a warning that multithreading is not yet supported. - ---- - dlls/vcomp/main.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c -index e37cf16..1dd57dd 100644 ---- a/dlls/vcomp/main.c -+++ b/dlls/vcomp/main.c -@@ -126,6 +126,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - ERR("Failed to allocate TLS index\n"); - return FALSE; - } -+ -+ FIXME("Builtin vcomp doesn't support multithreading, use native library for better performance.\n"); - break; - case DLL_PROCESS_DETACH: - TlsFree(vcomp_context_tls); --- -2.2.1 - diff --git a/patches/vcomp-Stub_Functions/definition b/patches/vcomp-Stub_Functions/definition deleted file mode 100644 index f2bb3c1a..00000000 --- a/patches/vcomp-Stub_Functions/definition +++ /dev/null @@ -1 +0,0 @@ -Fixes: [31640] Implement additional stubs for vcomp dlls