mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to implement additional stubs for vcomp dlls.
This commit is contained in:
parent
96b6186af1
commit
e51f6d2439
@ -38,11 +38,12 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
===================================
|
||||
|
||||
**Bugfixes and features included in the next upcoming release [3]:**
|
||||
**Bugfixes and features included in the next upcoming release [4]:**
|
||||
|
||||
* Call DriverUnload function when unloading a device driver.
|
||||
* Fix check for end_frame in RtlUnwindEx on x86_64. ([Wine Bug #34254](https://bugs.winehq.org/show_bug.cgi?id=34254))
|
||||
* Fix mouse jittering in Planetside 2 ([Wine Bug #32913](https://bugs.winehq.org/show_bug.cgi?id=32913))
|
||||
* Implement additional stubs for vcomp dlls ([Wine Bug #31640](https://bugs.winehq.org/show_bug.cgi?id=31640))
|
||||
|
||||
|
||||
**Bugs fixed in Wine Staging 1.7.35 [146]:**
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -2,6 +2,7 @@ wine-staging (1.7.36) UNRELEASED; urgency=low
|
||||
* Added patch to properly call DriverUnload when unloading device drivers.
|
||||
* Added patch to fix check for end_frame in RtlUnwindEx on x86_64.
|
||||
* Added patch to fix mouse jittering in Planetside 2.
|
||||
* Added patch to implement additional stubs for vcomp dlls.
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Sun, 25 Jan 2015 05:58:36 +0100
|
||||
|
||||
wine-staging (1.7.35) unstable; urgency=low
|
||||
|
@ -174,6 +174,7 @@ patch_enable_all ()
|
||||
enable_user32_Mouse_Message_Hwnd="$1"
|
||||
enable_user32_ScrollWindowEx="$1"
|
||||
enable_user32_WndProc="$1"
|
||||
enable_vcomp_Stub_Functions="$1"
|
||||
enable_windowscodecs_TGA_Decoder="$1"
|
||||
enable_wineboot_HKEY_DYN_DATA="$1"
|
||||
enable_winebuild_LinkerVersion="$1"
|
||||
@ -542,6 +543,9 @@ patch_enable ()
|
||||
user32-WndProc)
|
||||
enable_user32_WndProc="$2"
|
||||
;;
|
||||
vcomp-Stub_Functions)
|
||||
enable_vcomp_Stub_Functions="$2"
|
||||
;;
|
||||
windowscodecs-TGA_Decoder)
|
||||
enable_windowscodecs_TGA_Decoder="$2"
|
||||
;;
|
||||
@ -2919,6 +2923,36 @@ if test "$enable_user32_WndProc" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset vcomp-Stub_Functions
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#31640] Implement additional stubs for vcomp dlls
|
||||
# |
|
||||
# | 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,
|
||||
# | 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
|
||||
(
|
||||
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 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset windowscodecs-TGA_Decoder
|
||||
# |
|
||||
# | Modified files:
|
||||
|
@ -0,0 +1,484 @@
|
||||
From 90156f8a04061c7d0629f46dd640c09bccb0122c Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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 <stdarg.h>
|
||||
+
|
||||
+#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 @@
|
||||
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
+ <assemblyIdentity
|
||||
+ type="win32"
|
||||
+ name="Wine.vcomp.Test"
|
||||
+ version="1.0.0.0"
|
||||
+ processorArchitecture="*"
|
||||
+ />
|
||||
+<description>Wine vcomp test suite</description>
|
||||
+<dependency>
|
||||
+ <dependentAssembly>
|
||||
+ <assemblyIdentity
|
||||
+ type="win32"
|
||||
+ name="Microsoft.VC80.OpenMP"
|
||||
+ version="8.0.50608.0"
|
||||
+ processorArchitecture="*"
|
||||
+ publicKeyToken="1fc8b3b9a1e18e3b"
|
||||
+ />
|
||||
+ </dependentAssembly>
|
||||
+</dependency>
|
||||
+</assembly>
|
||||
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
|
||||
|
@ -0,0 +1,233 @@
|
||||
From c0369b34efc51c992be270a9e4eaef33b3cbf3d5 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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<i; j++)
|
||||
+ InterlockedIncrement(&nsum);
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_static_simple_init(void)
|
||||
+{
|
||||
+ ncalls = 0;
|
||||
+ nsum = 0;
|
||||
+ p_vcomp_fork(1, 0, _test_vcomp_for_static_simple_init_worker);
|
||||
+ ok(ncalls >= 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 <stdarg.h>
|
||||
+
|
||||
+#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
|
||||
|
@ -0,0 +1,153 @@
|
||||
From fadfe0d8a2483066f6f0137b2fb6d6efa3090db8 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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<i; j++)
|
||||
+ InterlockedIncrement(&nsum);
|
||||
+ }
|
||||
+ chunkstart += chunksize;
|
||||
+ chunkend += chunksize;
|
||||
+ }
|
||||
+ while (--nloops > 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
|
||||
|
@ -0,0 +1,254 @@
|
||||
From 659f7394d0c3e4c969e0b0f66689433fd133febd Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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<NLOOPS_SHORT; i++)
|
||||
+ {
|
||||
+ p_vcomp_fork(1, 1, _test_omp_in_parallel_nested_worker, psum);
|
||||
+ if (pomp_in_parallel())
|
||||
+ InterlockedIncrement(psum);
|
||||
+ Sleep(SLEEP_MS_SHORT);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_omp_in_parallel(void)
|
||||
+{
|
||||
+ int par;
|
||||
+ int old_nt;
|
||||
+ LONG volatile ncalls;
|
||||
+
|
||||
+ old_nt = pomp_get_num_threads();
|
||||
+ pomp_set_num_threads(1);
|
||||
+
|
||||
+ ncalls = 0;
|
||||
+ p_vcomp_fork(1, 1, _test_omp_in_parallel_worker, &ncalls);
|
||||
+
|
||||
+ ok(ncalls == 1 + 2 * NLOOPS_SHORT,
|
||||
+ "omp_in_parallel false in parallel region?!\n");
|
||||
+
|
||||
+ par = pomp_in_parallel();
|
||||
+ ok(par == 0, "omp_in_parallel true outside parallel region?!\n");
|
||||
+
|
||||
+ pomp_set_num_threads(old_nt);
|
||||
+}
|
||||
+
|
||||
START_TEST(fork)
|
||||
{
|
||||
if (!init())
|
||||
@@ -150,4 +199,5 @@ START_TEST(fork)
|
||||
test_vcomp_fork_ptr();
|
||||
test_vcomp_fork_uintptr();
|
||||
test_vcomp_fork_float();
|
||||
+ test_omp_in_parallel();
|
||||
}
|
||||
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/vcomp/vcomp_private.h b/dlls/vcomp/vcomp_private.h
|
||||
new file mode 100644
|
||||
index 0000000..50c4643
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/vcomp_private.h
|
||||
@@ -0,0 +1,19 @@
|
||||
+/*
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+extern DWORD vcomp_context_tls DECLSPEC_HIDDEN;
|
||||
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.2.1
|
||||
|
@ -0,0 +1,309 @@
|
||||
From 26d179bd36c65f9f416eafa4b9245f51a6ba6ecd Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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<i; j++)
|
||||
+ InterlockedIncrement(&nsum);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void CDECL _test_vcomp_for_dynamic_worker_down(void)
|
||||
+{
|
||||
+ int i, limit;
|
||||
+
|
||||
+ InterlockedIncrement(&ncalls);
|
||||
+
|
||||
+ /* pragma omp schedule(dynamic,16) */
|
||||
+ /* for (i=17; i>=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<i; j++)
|
||||
+ InterlockedIncrement(&nsum);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_dynamic(void)
|
||||
+{
|
||||
+ /* for (i=0; i<=17; i++) nsum += i; */
|
||||
+ ncalls = 0;
|
||||
+ nsum = 0;
|
||||
+ p_vcomp_fork(1, 0, _test_vcomp_for_dynamic_worker_up);
|
||||
+ ok(ncalls >= 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
|
||||
|
@ -0,0 +1,180 @@
|
||||
From 8069c24409570d48c59bb103539d1ea1fd835c36 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
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
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 5748aa15dd5e619714e9a04a033b30bd1fdae7d7 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
1
patches/vcomp-Stub_Functions/definition
Normal file
1
patches/vcomp-Stub_Functions/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [31640] Implement additional stubs for vcomp dlls
|
Loading…
Reference in New Issue
Block a user