Added patch to implement additional stubs for vcomp dlls.

This commit is contained in:
Sebastian Lackner 2015-01-29 00:23:01 +01:00
parent 96b6186af1
commit e51f6d2439
11 changed files with 1676 additions and 1 deletions

View File

@ -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
View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
Fixes: [31640] Implement additional stubs for vcomp dlls