[PATCH 4/6] vcomp: better stub for omp_in_parallel
Dan Kegel
dank at kegel.com
Tue Oct 2 23:58:04 CDT 2012
---
dlls/vcomp/fork.c | 13 ++++++++++++
dlls/vcomp/main.c | 15 ++++++++++++++
dlls/vcomp/tests/fork.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
dlls/vcomp/vcomp.spec | 2 +-
dlls/vcomp/vcomp_private.h | 34 +++++++++++++++++++++++++++++++
5 files changed, 111 insertions(+), 1 deletion(-)
create mode 100644 dlls/vcomp/vcomp_private.h
diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c
index 47a3f7f..ca80c98 100644
--- a/dlls/vcomp/fork.c
+++ b/dlls/vcomp/fork.c
@@ -25,6 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
+#include "vcomp_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
@@ -73,8 +74,13 @@ __ASM_GLOBAL_FUNC(_vcomp_fork,
void CDECL _vcomp_fork_body(DWORD parallel, int nargs, void *helper, DWORD *args)
{
+ struct vcomp_team team;
+
TRACE("(%d, %d, %p, %p): stub\n", parallel, nargs, helper, args);
+ team.parent = (struct vcomp_team *) TlsGetValue(vcomp_context_tls_idx);
+ TlsSetValue(vcomp_context_tls_idx, &team);
_vcomp_fork_call_helper(helper, nargs, args);
+ TlsSetValue(vcomp_context_tls_idx, team.parent);
}
@@ -155,3 +161,10 @@ __ASM_GLOBAL_FUNC(_vcomp_fork_call_helper,
__ASM_CFI(".cfi_same_value %rbp\n\t")
"ret\n")
#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 5faf0a1..9db3b9d 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
+DWORD vcomp_context_tls_idx;
+
int CDECL omp_get_dynamic(void)
{
TRACE("stub\n");
@@ -101,8 +103,21 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
+
+ vcomp_context_tls_idx = TlsAlloc();
+ if (vcomp_context_tls_idx == TLS_OUT_OF_INDEXES)
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to allocate TLS index, err %#x.\n", err);
+ return FALSE;
+ }
break;
case DLL_PROCESS_DETACH:
+ if (!TlsFree(vcomp_context_tls_idx))
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to free context TLS index, err %#x.\n", err);
+ }
break;
}
diff --git a/dlls/vcomp/tests/fork.c b/dlls/vcomp/tests/fork.c
index a82a77b..9c37271 100644
--- a/dlls/vcomp/tests/fork.c
+++ b/dlls/vcomp/tests/fork.c
@@ -20,6 +20,9 @@
#include "wine/test.h"
+static int CDECL (*pomp_get_num_threads)(void);
+static int CDECL (*pomp_in_parallel)(void);
+static void CDECL (*pomp_set_num_threads)(int);
static void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...);
#define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0)
@@ -32,6 +35,9 @@ static BOOL init(void)
return FALSE;
}
+ GETFUNC(omp_get_num_threads);
+ GETFUNC(omp_in_parallel);
+ GETFUNC(omp_set_num_threads);
GETFUNC(_vcomp_fork);
return TRUE;
@@ -72,10 +78,52 @@ static void test_vcomp_fork(void)
ok(ncalls >= 1, "expected >= 1 call, got %d\n", ncalls);
}
+#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;
+
+ 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())
return;
test_vcomp_fork();
+ test_omp_in_parallel();
}
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 8c8c51c..31e5b51 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..f71b55e
--- /dev/null
+++ b/dlls/vcomp/vcomp_private.h
@@ -0,0 +1,34 @@
+/*
+ * vcmp wine internal private include file
+ *
+ * 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
+ */
+
+#ifndef __WINE_VCOMP_PRIVATE_H
+#define __WINE_VCOMP_PRIVATE_H
+
+struct vcomp_team {
+ struct vcomp_team *parent;
+};
+
+extern DWORD vcomp_context_tls_idx;
+static inline struct vcomp_team *vcomp_get_team(void)
+{
+ return (struct vcomp_team *)TlsGetValue(vcomp_context_tls_idx);
+}
+
+#endif
--
1.7.9.5
More information about the wine-patches
mailing list