You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Rebase against 22f28d2923811b85024f63ce43e41966a864ecd0.
This commit is contained in:
@@ -1,17 +1,20 @@
|
||||
From 6404654fd885acbf0e563d9b5070d321986b5b8d Mon Sep 17 00:00:00 2001
|
||||
From d0d4b3991b691ee74e999f82dbf57a5a400fe7db Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
Date: Sat, 11 Jul 2015 06:50:26 +0200
|
||||
Date: Tue, 14 Jul 2015 21:40:36 +0200
|
||||
Subject: vcomp: Implement stub for _vcomp_fork.
|
||||
|
||||
Changes:
|
||||
* The original patch added a new file, I moved the implementation to main.c.
|
||||
* A huge comment block was removed, tests are more reliable than comments anyway. ;)
|
||||
---
|
||||
dlls/vcomp/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/main.c | 95 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 2 +-
|
||||
dlls/vcomp100/vcomp100.spec | 2 +-
|
||||
dlls/vcomp90/vcomp90.spec | 2 +-
|
||||
4 files changed, 96 insertions(+), 3 deletions(-)
|
||||
4 files changed, 98 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index ab2a372..26f6c67 100644
|
||||
index 8ec3616..03c085b 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -22,24 +25,14 @@ index ab2a372..26f6c67 100644
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -107,6 +108,98 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
@@ -40,6 +41,89 @@ struct vcomp_thread_data
|
||||
int fork_threads;
|
||||
};
|
||||
|
||||
+void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
+
|
||||
+void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+
|
||||
+ TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
+
|
||||
+ __ms_va_start(valist, wrapper);
|
||||
+ _vcomp_fork_call_wrapper(wrapper, nargs, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
+#if defined(__i386__)
|
||||
+
|
||||
+__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper,
|
||||
+ "pushl %ebp\n\t"
|
||||
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
@@ -109,6 +102,7 @@ index ab2a372..26f6c67 100644
|
||||
+ __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
|
||||
+ __ASM_CFI(".cfi_same_value %rbp\n\t")
|
||||
+ "ret")
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args)
|
||||
@@ -118,9 +112,27 @@ index ab2a372..26f6c67 100644
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
static inline struct vcomp_thread_data *vcomp_get_thread_data(void)
|
||||
{
|
||||
TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
|
||||
return (struct vcomp_thread_data *)TlsGetValue(vcomp_context_tls);
|
||||
@@ -160,6 +244,17 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
|
||||
+void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+
|
||||
+ TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
+
|
||||
+ __ms_va_start(valist, wrapper);
|
||||
+ _vcomp_fork_call_wrapper(wrapper, nargs, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
TRACE("(%p, %d, %p)\n", instance, reason, reserved);
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 306dd15..d446574 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
From e3f58ae29d504bd1f2287566878b7d6674bd5484 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 18:53:41 +0200
|
||||
Subject: vcomp: Add basic worker thread infrastructure.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 211 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 26f6c67..9de9721 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 2011 Austin English
|
||||
* Copyright 2012 Dan Kegel
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,13 +24,68 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
+#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/debug.h"
|
||||
+#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
|
||||
|
||||
+static HMODULE vcomp_module;
|
||||
+static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads);
|
||||
+static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES;
|
||||
+static DWORD vcomp_max_threads = 32;
|
||||
+static DWORD vcomp_num_threads = 1;
|
||||
+
|
||||
+static RTL_CRITICAL_SECTION vcomp_section;
|
||||
+static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
+{
|
||||
+ 0, 0, &vcomp_section,
|
||||
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
+ 0, 0, { (DWORD_PTR)(__FILE__ ": vcomp_section") }
|
||||
+};
|
||||
+static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
+
|
||||
+struct vcomp_thread_info
|
||||
+{
|
||||
+ struct list entry;
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+
|
||||
+ /* current task */
|
||||
+ struct vcomp_team_info *team;
|
||||
+ DWORD thread_num;
|
||||
+};
|
||||
+
|
||||
+struct vcomp_team_info
|
||||
+{
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+ DWORD num_threads;
|
||||
+ DWORD finished_threads;
|
||||
+
|
||||
+ /* callback arguments */
|
||||
+ unsigned int nargs;
|
||||
+ void *wrapper;
|
||||
+ __ms_va_list valist;
|
||||
+};
|
||||
+
|
||||
+static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
+{
|
||||
+ return (struct vcomp_thread_info *)TlsGetValue(vcomp_context_tls);
|
||||
+}
|
||||
+
|
||||
+static inline struct vcomp_team_info *vcomp_get_team_info(void)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ return thread_info ? thread_info->team : NULL;
|
||||
+}
|
||||
+
|
||||
+static inline void vcomp_set_thread_info(struct vcomp_thread_info *thread_info)
|
||||
+{
|
||||
+ TlsSetValue(vcomp_context_tls, thread_info);
|
||||
+}
|
||||
+
|
||||
int CDECL omp_get_dynamic(void)
|
||||
{
|
||||
TRACE("stub\n");
|
||||
@@ -39,7 +95,7 @@ int CDECL omp_get_dynamic(void)
|
||||
int CDECL omp_get_max_threads(void)
|
||||
{
|
||||
TRACE("stub\n");
|
||||
- return 1;
|
||||
+ return vcomp_max_threads;
|
||||
}
|
||||
|
||||
int CDECL omp_get_nested(void)
|
||||
@@ -56,14 +112,22 @@ int CDECL omp_get_num_procs(void)
|
||||
|
||||
int CDECL omp_get_num_threads(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
- return 1;
|
||||
+ struct vcomp_team_info *team_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ team_info = vcomp_get_team_info();
|
||||
+ return team_info ? team_info->num_threads : 1;
|
||||
}
|
||||
|
||||
int CDECL omp_get_thread_num(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
- return 0;
|
||||
+ struct vcomp_thread_info *thread_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ thread_info = vcomp_get_thread_info();
|
||||
+ return thread_info ? thread_info->thread_num : 0;
|
||||
}
|
||||
|
||||
/* Time in seconds since "some time in the past" */
|
||||
@@ -85,6 +149,7 @@ void CDECL omp_set_nested(int nested)
|
||||
void CDECL omp_set_num_threads(int num_threads)
|
||||
{
|
||||
TRACE("(%d): stub\n", num_threads);
|
||||
+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads));
|
||||
}
|
||||
|
||||
void CDECL _vcomp_barrier(void)
|
||||
@@ -94,7 +159,8 @@ void CDECL _vcomp_barrier(void)
|
||||
|
||||
void CDECL _vcomp_set_num_threads(int num_threads)
|
||||
{
|
||||
- TRACE("(%d): stub\n", num_threads);
|
||||
+ TRACE("(%d)\n", num_threads);
|
||||
+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads));
|
||||
}
|
||||
|
||||
int CDECL _vcomp_single_begin(int flags)
|
||||
@@ -110,15 +176,139 @@ void CDECL _vcomp_single_end(void)
|
||||
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
+static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = param;
|
||||
+ vcomp_set_thread_info(thread_info);
|
||||
+
|
||||
+ TRACE("starting worker thread %p\n", thread_info);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ struct vcomp_team_info *team = thread_info->team;
|
||||
+ if (team != NULL)
|
||||
+ {
|
||||
+ /* Leave critical section and execute callback. */
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist);
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ /* Detach current thread from team. */
|
||||
+ thread_info->team = NULL;
|
||||
+ list_remove(&thread_info->entry);
|
||||
+ list_add_tail(&vcomp_idle_threads, &thread_info->entry);
|
||||
+ if (++team->finished_threads >= team->num_threads)
|
||||
+ WakeAllConditionVariable(&team->cond);
|
||||
+ }
|
||||
+
|
||||
+ if (!SleepConditionVariableCS(&thread_info->cond, &vcomp_section, 5000) &&
|
||||
+ GetLastError() == ERROR_TIMEOUT && !thread_info->team)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ list_remove(&thread_info->entry);
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ TRACE("terminating worker thread %p\n", thread_info);
|
||||
+ HeapFree(GetProcessHeap(), 0, thread_info);
|
||||
+ FreeLibraryAndExitThread(vcomp_module, 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
{
|
||||
- __ms_va_list valist;
|
||||
+ struct vcomp_thread_info thread_info, *prev_thread_info;
|
||||
+ struct vcomp_team_info team_info;
|
||||
+ DWORD num_threads = vcomp_num_threads; /* FIXME */
|
||||
+ BOOL parallel = ifval;
|
||||
|
||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
|
||||
- __ms_va_start(valist, wrapper);
|
||||
- _vcomp_fork_call_wrapper(wrapper, nargs, valist);
|
||||
- __ms_va_end(valist);
|
||||
+ /* Initialize members of team_info. */
|
||||
+ InitializeConditionVariable(&team_info.cond);
|
||||
+ team_info.num_threads = 1;
|
||||
+ team_info.finished_threads = 0;
|
||||
+ team_info.nargs = nargs;
|
||||
+ team_info.wrapper = wrapper;
|
||||
+ __ms_va_start(team_info.valist, wrapper);
|
||||
+
|
||||
+ /* Initialize members of thread_info. */
|
||||
+ list_init(&thread_info.entry);
|
||||
+ InitializeConditionVariable(&thread_info.cond);
|
||||
+ thread_info.team = &team_info;
|
||||
+ thread_info.thread_num = 0;
|
||||
+
|
||||
+ if (parallel)
|
||||
+ {
|
||||
+ struct list *ptr;
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ /* Try to reuse idle threads. */
|
||||
+ while (team_info.num_threads < num_threads &&
|
||||
+ (ptr = list_head( &vcomp_idle_threads )))
|
||||
+ {
|
||||
+ struct vcomp_thread_info *info = LIST_ENTRY(ptr, struct vcomp_thread_info, entry);
|
||||
+ list_remove(&info->entry);
|
||||
+ list_add_tail(&thread_info.entry, &info->entry);
|
||||
+ info->team = &team_info;
|
||||
+ info->thread_num = team_info.num_threads++;
|
||||
+ WakeAllConditionVariable(&info->cond);
|
||||
+ }
|
||||
+
|
||||
+ /* Spawn additional new threads. */
|
||||
+ while (team_info.num_threads < num_threads)
|
||||
+ {
|
||||
+ struct vcomp_thread_info *info;
|
||||
+ HMODULE module;
|
||||
+ HANDLE thread;
|
||||
+
|
||||
+ info = HeapAlloc(GetProcessHeap(), 0, sizeof(*info));
|
||||
+ if (!info) break;
|
||||
+
|
||||
+ InitializeConditionVariable(&info->cond);
|
||||
+ info->team = &team_info;
|
||||
+ info->thread_num = team_info.num_threads;
|
||||
+
|
||||
+ thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
+ if (!thread)
|
||||
+ {
|
||||
+ HeapFree(GetProcessHeap(), 0, info);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
+ (const WCHAR *)vcomp_module, &module);
|
||||
+
|
||||
+ list_add_tail(&thread_info.entry, &info->entry);
|
||||
+ team_info.num_threads++;
|
||||
+ CloseHandle(thread);
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ }
|
||||
+
|
||||
+ /* Call the callback in the context of the new team. */
|
||||
+ prev_thread_info = vcomp_get_thread_info();
|
||||
+ vcomp_set_thread_info(&thread_info);
|
||||
+ _vcomp_fork_call_wrapper(team_info.wrapper, team_info.nargs, team_info.valist);
|
||||
+ vcomp_set_thread_info(prev_thread_info);
|
||||
+
|
||||
+ /* Implicit join, wait for other tasks. */
|
||||
+ if (parallel)
|
||||
+ {
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ team_info.finished_threads++;
|
||||
+ while (team_info.finished_threads < team_info.num_threads)
|
||||
+ SleepConditionVariableCS(&team_info.cond, &vcomp_section, INFINITE);
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ assert(list_empty(&thread_info.entry));
|
||||
+ }
|
||||
+
|
||||
+ __ms_va_end(team_info.valist);
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -208,8 +398,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
case DLL_WINE_PREATTACH:
|
||||
return FALSE; /* prefer native version */
|
||||
+
|
||||
case DLL_PROCESS_ATTACH:
|
||||
+ vcomp_module = hinstDLL;
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
+ if ((vcomp_context_tls = TlsAlloc()) == TLS_OUT_OF_INDEXES)
|
||||
+ {
|
||||
+ ERR("Failed to allocate TLS index\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DLL_PROCESS_DETACH:
|
||||
+ TlsFree(vcomp_context_tls);
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
From 6f76d9a3a8a11bc4f6d3e6ddba1fcb9a856d0b2f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Tue, 14 Jul 2015 21:41:10 +0200
|
||||
Subject: vcomp: Add multithreaded implementation for _vcomp_fork.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 172 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 03c085b..20aeb4f 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 2011 Austin English
|
||||
* Copyright 2012 Dan Kegel
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,22 +24,52 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
+#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/debug.h"
|
||||
+#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
|
||||
|
||||
+static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads);
|
||||
static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES;
|
||||
+static HMODULE vcomp_module;
|
||||
static int vcomp_max_threads;
|
||||
static int vcomp_num_threads;
|
||||
static BOOL vcomp_nested_fork = FALSE;
|
||||
|
||||
+static RTL_CRITICAL_SECTION vcomp_section;
|
||||
+static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
+{
|
||||
+ 0, 0, &vcomp_section,
|
||||
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
+ 0, 0, { (DWORD_PTR)(__FILE__ ": vcomp_section") }
|
||||
+};
|
||||
+static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
+
|
||||
struct vcomp_thread_data
|
||||
{
|
||||
+ struct vcomp_team_data *team;
|
||||
int thread_num;
|
||||
int fork_threads;
|
||||
+
|
||||
+ /* only used for concurrent tasks */
|
||||
+ struct list entry;
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+};
|
||||
+
|
||||
+struct vcomp_team_data
|
||||
+{
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+ int num_threads;
|
||||
+ int finished_threads;
|
||||
+
|
||||
+ /* callback arguments */
|
||||
+ int nargs;
|
||||
+ void *wrapper;
|
||||
+ __ms_va_list valist;
|
||||
};
|
||||
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
@@ -145,8 +176,9 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
- thread_data->thread_num = 0;
|
||||
- thread_data->fork_threads = 0;
|
||||
+ thread_data->team = NULL;
|
||||
+ thread_data->thread_num = 0;
|
||||
+ thread_data->fork_threads = 0;
|
||||
|
||||
vcomp_set_thread_data(thread_data);
|
||||
return thread_data;
|
||||
@@ -187,8 +219,9 @@ int CDECL omp_get_num_procs(void)
|
||||
|
||||
int CDECL omp_get_num_threads(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
- return 1;
|
||||
+ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team;
|
||||
+ TRACE("()\n");
|
||||
+ return team_data ? team_data->num_threads : 1;
|
||||
}
|
||||
|
||||
int CDECL omp_get_thread_num(void)
|
||||
@@ -244,15 +277,145 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
|
||||
+static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
+{
|
||||
+ struct vcomp_thread_data *thread_data = param;
|
||||
+ vcomp_set_thread_data(thread_data);
|
||||
+
|
||||
+ TRACE("starting worker thread for %p\n", thread_data);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ struct vcomp_team_data *team = thread_data->team;
|
||||
+ if (team != NULL)
|
||||
+ {
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist);
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ thread_data->team = NULL;
|
||||
+ list_remove(&thread_data->entry);
|
||||
+ list_add_tail(&vcomp_idle_threads, &thread_data->entry);
|
||||
+ if (++team->finished_threads >= team->num_threads)
|
||||
+ WakeAllConditionVariable(&team->cond);
|
||||
+ }
|
||||
+
|
||||
+ if (!SleepConditionVariableCS(&thread_data->cond, &vcomp_section, 5000) &&
|
||||
+ GetLastError() == ERROR_TIMEOUT && !thread_data->team)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ list_remove(&thread_data->entry);
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ TRACE("terminating worker thread for %p\n", thread_data);
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, thread_data);
|
||||
+ vcomp_set_thread_data(NULL);
|
||||
+ FreeLibraryAndExitThread(vcomp_module, 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
{
|
||||
- __ms_va_list valist;
|
||||
+ struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_thread_data thread_data;
|
||||
+ struct vcomp_team_data team_data;
|
||||
+ int num_threads;
|
||||
|
||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
|
||||
- __ms_va_start(valist, wrapper);
|
||||
- _vcomp_fork_call_wrapper(wrapper, nargs, valist);
|
||||
- __ms_va_end(valist);
|
||||
+ if (!ifval)
|
||||
+ num_threads = 1;
|
||||
+ else if (prev_thread_data->team && !vcomp_nested_fork)
|
||||
+ num_threads = 1;
|
||||
+ else if (prev_thread_data->fork_threads)
|
||||
+ num_threads = prev_thread_data->fork_threads;
|
||||
+ else
|
||||
+ num_threads = vcomp_num_threads;
|
||||
+
|
||||
+ InitializeConditionVariable(&team_data.cond);
|
||||
+ team_data.num_threads = 1;
|
||||
+ team_data.finished_threads = 0;
|
||||
+ team_data.nargs = nargs;
|
||||
+ team_data.wrapper = wrapper;
|
||||
+ __ms_va_start(team_data.valist, wrapper);
|
||||
+
|
||||
+ thread_data.team = &team_data;
|
||||
+ thread_data.thread_num = 0;
|
||||
+ thread_data.fork_threads = 0;
|
||||
+ list_init(&thread_data.entry);
|
||||
+ InitializeConditionVariable(&thread_data.cond);
|
||||
+
|
||||
+ if (num_threads > 1)
|
||||
+ {
|
||||
+ struct list *ptr;
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ /* reuse existing threads (if any) */
|
||||
+ while (team_data.num_threads < num_threads && (ptr = list_head(&vcomp_idle_threads)))
|
||||
+ {
|
||||
+ struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry);
|
||||
+ data->team = &team_data;
|
||||
+ data->thread_num = team_data.num_threads++;
|
||||
+ data->fork_threads = 0;
|
||||
+ list_remove(&data->entry);
|
||||
+ list_add_tail(&thread_data.entry, &data->entry);
|
||||
+ WakeAllConditionVariable(&data->cond);
|
||||
+ }
|
||||
+
|
||||
+ /* spawn additional threads */
|
||||
+ while (team_data.num_threads < num_threads)
|
||||
+ {
|
||||
+ struct vcomp_thread_data *data;
|
||||
+ HMODULE module;
|
||||
+ HANDLE thread;
|
||||
+
|
||||
+ data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
|
||||
+ if (!data) break;
|
||||
+
|
||||
+ data->team = &team_data;
|
||||
+ data->thread_num = team_data.num_threads;
|
||||
+ data->fork_threads = 0;
|
||||
+ InitializeConditionVariable(&data->cond);
|
||||
+
|
||||
+ thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
|
||||
+ if (!thread)
|
||||
+ {
|
||||
+ HeapFree(GetProcessHeap(), 0, data);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
+ (const WCHAR *)vcomp_module, &module);
|
||||
+ team_data.num_threads++;
|
||||
+ list_add_tail(&thread_data.entry, &data->entry);
|
||||
+ CloseHandle(thread);
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ }
|
||||
+
|
||||
+ vcomp_set_thread_data(&thread_data);
|
||||
+ _vcomp_fork_call_wrapper(team_data.wrapper, team_data.nargs, team_data.valist);
|
||||
+ vcomp_set_thread_data(prev_thread_data);
|
||||
+ prev_thread_data->fork_threads = 0;
|
||||
+
|
||||
+ if (team_data.num_threads > 1)
|
||||
+ {
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ team_data.finished_threads++;
|
||||
+ while (team_data.finished_threads < team_data.num_threads)
|
||||
+ SleepConditionVariableCS(&team_data.cond, &vcomp_section, INFINITE);
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ assert(list_empty(&thread_data.entry));
|
||||
+ }
|
||||
+
|
||||
+ __ms_va_end(team_data.valist);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
@@ -275,6 +438,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
}
|
||||
|
||||
GetSystemInfo(&sysinfo);
|
||||
+ vcomp_module = instance;
|
||||
vcomp_max_threads = sysinfo.dwNumberOfProcessors;
|
||||
vcomp_num_threads = sysinfo.dwNumberOfProcessors;
|
||||
break;
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 5990968a0ae43fd6f4a4001107ef5d4fcc273458 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Tue, 14 Jul 2015 21:41:27 +0200
|
||||
Subject: vcomp: Implement _vcomp_barrier.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 20aeb4f..bcaa4ea 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -70,6 +70,10 @@ struct vcomp_team_data
|
||||
int nargs;
|
||||
void *wrapper;
|
||||
__ms_va_list valist;
|
||||
+
|
||||
+ /* barrier */
|
||||
+ unsigned int barrier;
|
||||
+ int barrier_count;
|
||||
};
|
||||
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
@@ -256,7 +260,27 @@ void CDECL omp_set_num_threads(int num_threads)
|
||||
|
||||
void CDECL _vcomp_barrier(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
+ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ if (!team_data)
|
||||
+ return;
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ if (++team_data->barrier_count >= team_data->num_threads)
|
||||
+ {
|
||||
+ team_data->barrier++;
|
||||
+ team_data->barrier_count = 0;
|
||||
+ WakeAllConditionVariable(&team_data->cond);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ unsigned int barrier = team_data->barrier;
|
||||
+ while (team_data->barrier == barrier)
|
||||
+ SleepConditionVariableCS(&team_data->cond, &vcomp_section, INFINITE);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
}
|
||||
|
||||
void CDECL _vcomp_set_num_threads(int num_threads)
|
||||
@@ -342,6 +366,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_data.nargs = nargs;
|
||||
team_data.wrapper = wrapper;
|
||||
__ms_va_start(team_data.valist, wrapper);
|
||||
+ team_data.barrier = 0;
|
||||
+ team_data.barrier_count = 0;
|
||||
|
||||
thread_data.team = &team_data;
|
||||
thread_data.thread_num = 0;
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
From 92cd559115925b61b980a784efacb0ccdd7029d0 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
Date: Sat, 11 Jul 2015 03:56:04 +0200
|
||||
Subject: vcomp/tests: Add initial tests for _vcomp_fork.
|
||||
|
||||
---
|
||||
configure.ac | 3 +-
|
||||
dlls/vcomp/tests/Makefile.in | 7 +++
|
||||
dlls/vcomp/tests/vcomp.c | 122 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/tests/vcomp.manifest | 21 +++++++
|
||||
dlls/vcomp/tests/vcomp.rc | 22 ++++++++
|
||||
5 files changed, 174 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dlls/vcomp/tests/Makefile.in
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.c
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.manifest
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.rc
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 3eaec29..a36fc4b 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3321,7 +3321,8 @@ WINE_CONFIG_DLL(uxtheme,,[implib])
|
||||
WINE_CONFIG_TEST(dlls/uxtheme/tests)
|
||||
WINE_CONFIG_DLL(vbscript,,[clean])
|
||||
WINE_CONFIG_TEST(dlls/vbscript/tests,[clean])
|
||||
-WINE_CONFIG_DLL(vcomp)
|
||||
+WINE_CONFIG_DLL(vcomp,,[implib])
|
||||
+WINE_CONFIG_TEST(dlls/vcomp/tests)
|
||||
WINE_CONFIG_DLL(vcomp100)
|
||||
WINE_CONFIG_DLL(vcomp90)
|
||||
WINE_CONFIG_DLL(vdhcp.vxd,enable_win16)
|
||||
diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..08a5b7f
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/Makefile.in
|
||||
@@ -0,0 +1,7 @@
|
||||
+TESTDLL = vcomp.dll
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ vcomp.c
|
||||
+
|
||||
+RC_SRCS = \
|
||||
+ vcomp.rc
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
new file mode 100644
|
||||
index 0000000..5c6a861
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -0,0 +1,122 @@
|
||||
+/*
|
||||
+ * Unit test suite for vcomp fork/join implementation
|
||||
+ *
|
||||
+ * Copyright 2012 Dan Kegel
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "wine/test.h"
|
||||
+
|
||||
+static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
+
|
||||
+static HMODULE hvcomp = 0;
|
||||
+static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
+static int (CDECL *pomp_get_max_threads)(void);
|
||||
+
|
||||
+#define VCOMP_GET_PROC(func) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ p ## func = (void *)GetProcAddress(hvcomp, #func); \
|
||||
+ if (!p ## func) trace("Failed to get address for %s\n", #func); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+static BOOL init_vcomp(void)
|
||||
+{
|
||||
+ hvcomp = LoadLibraryA("vcomp.dll");
|
||||
+ if (!hvcomp)
|
||||
+ {
|
||||
+ win_skip("vcomp.dll not installed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ VCOMP_GET_PROC(_vcomp_fork);
|
||||
+ VCOMP_GET_PROC(omp_get_max_threads);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+#undef VCOMP_GET_PROC
|
||||
+
|
||||
+static void CDECL _test_vcomp_fork_ptr(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e)
|
||||
+{
|
||||
+ InterlockedIncrement(a);
|
||||
+ InterlockedIncrement(b);
|
||||
+ InterlockedIncrement(c);
|
||||
+ InterlockedIncrement(d);
|
||||
+ InterlockedIncrement(e);
|
||||
+}
|
||||
+
|
||||
+static void CDECL _test_vcomp_fork_uintptr(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e)
|
||||
+{
|
||||
+ ok(a == 1, "expected a = 1, got %p\n", (void *)a);
|
||||
+ ok(b == MAXUINT_PTR - 2, "expected b = MAXUINT_PTR - 2, got %p\n", (void *)b);
|
||||
+ ok(c == 3, "expected c = 3, got %p\n", (void *)c);
|
||||
+ ok(d == MAXUINT_PTR - 4, "expected d = MAXUINT_PTR - 4, got %p\n", (void *)d);
|
||||
+ ok(e == 5, "expected e = 5, got %p\n", (void *)e);
|
||||
+}
|
||||
+
|
||||
+static void CDECL _test_vcomp_fork_float(float a, float b, float c, float d, float e)
|
||||
+{
|
||||
+ ok(1.4999 < a && a < 1.5001, "expected a = 1.5, got %f\n", a);
|
||||
+ ok(2.4999 < b && b < 2.5001, "expected b = 2.5, got %f\n", b);
|
||||
+ ok(3.4999 < c && c < 3.5001, "expected c = 3.5, got %f\n", c);
|
||||
+ ok(4.4999 < d && d < 4.5001, "expected d = 4.5, got %f\n", d);
|
||||
+ ok(5.4999 < e && e < 5.5001, "expected e = 5.5, got %f\n", e);
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_fork(void)
|
||||
+{
|
||||
+ LONG a, b, c, d, e;
|
||||
+ int n = pomp_get_max_threads();
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(FALSE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e);
|
||||
+ ok(a == 1, "expected a = 1, got %u\n", a);
|
||||
+ ok(b == 2, "expected b = 2, got %u\n", b);
|
||||
+ ok(c == 3, "expected c = 3, got %u\n", c);
|
||||
+ ok(d == 4, "expected d = 4, got %u\n", d);
|
||||
+ ok(e == 5, "expected e = 5, got %u\n", e);
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e);
|
||||
+ ok(a > 0 && a <= (n + 0), "expected a > 0 && a <= (n + 0), got %u\n", a);
|
||||
+ ok(b > 1 && b <= (n + 1), "expected b > 1 && b <= (n + 1), got %u\n", b);
|
||||
+ ok(c > 2 && c <= (n + 2), "expected c > 2 && c <= (n + 2), got %u\n", c);
|
||||
+ ok(d > 3 && d <= (n + 3), "expected d > 3 && d <= (n + 3), got %u\n", d);
|
||||
+ ok(e > 4 && e <= (n + 4), "expected e > 4 && e <= (n + 4), got %u\n", e);
|
||||
+
|
||||
+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_uintptr, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2),
|
||||
+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5);
|
||||
+
|
||||
+ if (is_win64)
|
||||
+ skip("skipping float test on x86_64\n");
|
||||
+ else
|
||||
+ {
|
||||
+ void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork;
|
||||
+ func(TRUE, 5, _test_vcomp_fork_float, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+START_TEST(vcomp)
|
||||
+{
|
||||
+ if (!init_vcomp())
|
||||
+ return;
|
||||
+
|
||||
+ test_vcomp_fork();
|
||||
+
|
||||
+ FreeLibrary(hvcomp);
|
||||
+}
|
||||
diff --git a/dlls/vcomp/tests/vcomp.manifest b/dlls/vcomp/tests/vcomp.manifest
|
||||
new file mode 100644
|
||||
index 0000000..6c8bd91
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.manifest
|
||||
@@ -0,0 +1,21 @@
|
||||
+<?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
|
||||
--
|
||||
2.4.5
|
||||
|
||||
338
patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch
Normal file
338
patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch
Normal file
@@ -0,0 +1,338 @@
|
||||
From 01b14a9059e5a0ade1818046b03546adc0002bde Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Tue, 14 Jul 2015 21:42:11 +0200
|
||||
Subject: vcomp/tests: Add initial tests.
|
||||
|
||||
The only way to get the tests pass on all testbot machines was to dynamically
|
||||
create a manifest file. Without manifest file, the vcomp library cannot be found
|
||||
on all machines > Win2000, with manifest file as resource the Windows loader is
|
||||
not able to load the executable for testbots without vcrun2005.
|
||||
---
|
||||
configure.ac | 1 +
|
||||
dlls/vcomp/tests/Makefile.in | 4 +
|
||||
dlls/vcomp/tests/vcomp.c | 290 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 295 insertions(+)
|
||||
create mode 100644 dlls/vcomp/tests/Makefile.in
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 3eaec29..f15a17a 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3322,6 +3322,7 @@ WINE_CONFIG_TEST(dlls/uxtheme/tests)
|
||||
WINE_CONFIG_DLL(vbscript,,[clean])
|
||||
WINE_CONFIG_TEST(dlls/vbscript/tests,[clean])
|
||||
WINE_CONFIG_DLL(vcomp)
|
||||
+WINE_CONFIG_TEST(dlls/vcomp/tests)
|
||||
WINE_CONFIG_DLL(vcomp100)
|
||||
WINE_CONFIG_DLL(vcomp90)
|
||||
WINE_CONFIG_DLL(vdhcp.vxd,enable_win16)
|
||||
diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..d1b7b12
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/Makefile.in
|
||||
@@ -0,0 +1,4 @@
|
||||
+TESTDLL = vcomp.dll
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ vcomp.c
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
new file mode 100644
|
||||
index 0000000..b084791
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -0,0 +1,290 @@
|
||||
+/*
|
||||
+ * Unit test suite for vcomp
|
||||
+ *
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "wine/test.h"
|
||||
+
|
||||
+static char vcomp_manifest_file[MAX_PATH];
|
||||
+static HANDLE vcomp_actctx_hctx;
|
||||
+static ULONG_PTR vcomp_actctx_cookie;
|
||||
+static HMODULE vcomp_handle;
|
||||
+
|
||||
+static HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*);
|
||||
+static BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*);
|
||||
+static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
+static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
+
|
||||
+static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
+static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
|
||||
+static int (CDECL *pomp_get_max_threads)(void);
|
||||
+static int (CDECL *pomp_get_nested)(void);
|
||||
+static int (CDECL *pomp_get_num_threads)(void);
|
||||
+static int (CDECL *pomp_get_thread_num)(void);
|
||||
+static void (CDECL *pomp_set_nested)(int nested);
|
||||
+static void (CDECL *pomp_set_num_threads)(int num_threads);
|
||||
+
|
||||
+#ifdef __i386__
|
||||
+#define ARCH "x86"
|
||||
+#elif defined(__x86_64__)
|
||||
+#define ARCH "amd64"
|
||||
+#else
|
||||
+#define ARCH "none"
|
||||
+#endif
|
||||
+
|
||||
+static const char vcomp_manifest[] =
|
||||
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
+ "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
|
||||
+ " <assemblyIdentity\n"
|
||||
+ " type=\"win32\"\n"
|
||||
+ " name=\"Wine.vcomp.Test\"\n"
|
||||
+ " version=\"1.0.0.0\"\n"
|
||||
+ " processorArchitecture=\"" ARCH "\"\n"
|
||||
+ " />\n"
|
||||
+ "<description>Wine vcomp test suite</description>\n"
|
||||
+ "<dependency>\n"
|
||||
+ " <dependentAssembly>\n"
|
||||
+ " <assemblyIdentity\n"
|
||||
+ " type=\"win32\"\n"
|
||||
+ " name=\"Microsoft.VC80.OpenMP\"\n"
|
||||
+ " version=\"8.0.50608.0\"\n"
|
||||
+ " processorArchitecture=\"" ARCH "\"\n"
|
||||
+ " publicKeyToken=\"1fc8b3b9a1e18e3b\"\n"
|
||||
+ " />\n"
|
||||
+ " </dependentAssembly>\n"
|
||||
+ "</dependency>\n"
|
||||
+ "</assembly>\n";
|
||||
+
|
||||
+#undef ARCH
|
||||
+
|
||||
+static void create_vcomp_manifest(void)
|
||||
+{
|
||||
+ char temp_path[MAX_PATH];
|
||||
+ HMODULE kernel32;
|
||||
+ DWORD written;
|
||||
+ ACTCTXA ctx;
|
||||
+ HANDLE file;
|
||||
+
|
||||
+ kernel32 = GetModuleHandleA("kernel32.dll");
|
||||
+ pCreateActCtxA = (void *)GetProcAddress(kernel32, "CreateActCtxA");
|
||||
+ pActivateActCtx = (void *)GetProcAddress(kernel32, "ActivateActCtx");
|
||||
+ pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx");
|
||||
+ pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
|
||||
+ if (!pCreateActCtxA) return;
|
||||
+
|
||||
+ if (!GetTempPathA(sizeof(temp_path), temp_path) ||
|
||||
+ !GetTempFileNameA(temp_path, "vcomp", 0, vcomp_manifest_file))
|
||||
+ {
|
||||
+ ok(0, "failed to create manifest file\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ file = CreateFileA(vcomp_manifest_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
+ if (file == INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ ok(0, "failed to open manifest file\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!WriteFile(file, vcomp_manifest, sizeof(vcomp_manifest) - 1, &written, NULL))
|
||||
+ written = 0;
|
||||
+ CloseHandle(file);
|
||||
+
|
||||
+ if (written != sizeof(vcomp_manifest) - 1)
|
||||
+ {
|
||||
+ ok(0, "failed to write manifest file\n");
|
||||
+ DeleteFileA(vcomp_manifest_file);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ memset(&ctx, 0, sizeof(ctx));
|
||||
+ ctx.cbSize = sizeof(ctx);
|
||||
+ ctx.lpSource = vcomp_manifest_file;
|
||||
+ vcomp_actctx_hctx = pCreateActCtxA(&ctx);
|
||||
+ if (!vcomp_actctx_hctx)
|
||||
+ {
|
||||
+ ok(0, "failed to create activation context\n");
|
||||
+ DeleteFileA(vcomp_manifest_file);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!pActivateActCtx(vcomp_actctx_hctx, &vcomp_actctx_cookie))
|
||||
+ {
|
||||
+ win_skip("failed to activate context\n");
|
||||
+ pReleaseActCtx(vcomp_actctx_hctx);
|
||||
+ DeleteFileA(vcomp_manifest_file);
|
||||
+ vcomp_actctx_hctx = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void release_vcomp(void)
|
||||
+{
|
||||
+ if (vcomp_handle)
|
||||
+ FreeLibrary(vcomp_handle);
|
||||
+
|
||||
+ if (vcomp_actctx_hctx)
|
||||
+ {
|
||||
+ pDeactivateActCtx(0, vcomp_actctx_cookie);
|
||||
+ pReleaseActCtx(vcomp_actctx_hctx);
|
||||
+ DeleteFileA(vcomp_manifest_file);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define VCOMP_GET_PROC(func) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ p ## func = (void *)GetProcAddress(vcomp_handle, #func); \
|
||||
+ if (!p ## func) trace("Failed to get address for %s\n", #func); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+static BOOL init_vcomp(void)
|
||||
+{
|
||||
+ create_vcomp_manifest();
|
||||
+
|
||||
+ vcomp_handle = LoadLibraryA("vcomp.dll");
|
||||
+ if (!vcomp_handle)
|
||||
+ {
|
||||
+ win_skip("vcomp.dll not installed\n");
|
||||
+ release_vcomp();
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ VCOMP_GET_PROC(_vcomp_barrier);
|
||||
+ VCOMP_GET_PROC(_vcomp_fork);
|
||||
+ VCOMP_GET_PROC(_vcomp_set_num_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_max_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_nested);
|
||||
+ VCOMP_GET_PROC(omp_get_num_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_thread_num);
|
||||
+ VCOMP_GET_PROC(omp_set_nested);
|
||||
+ VCOMP_GET_PROC(omp_set_num_threads);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+#undef VCOMP_GET_PROC
|
||||
+
|
||||
+static void CDECL num_threads_cb2(LONG *count)
|
||||
+{
|
||||
+ InterlockedIncrement(count);
|
||||
+}
|
||||
+
|
||||
+static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count)
|
||||
+{
|
||||
+ int num_threads, thread_num;
|
||||
+ LONG thread_count;
|
||||
+
|
||||
+ InterlockedIncrement(count);
|
||||
+ p_vcomp_barrier();
|
||||
+
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == *count, "expected num_threads == %d, got %d\n", *count, num_threads);
|
||||
+ thread_num = pomp_get_thread_num();
|
||||
+ ok(thread_num >= 0 && thread_num < num_threads,
|
||||
+ "expected thread_num in range [0, %d], got %d\n", num_threads - 1, thread_num);
|
||||
+
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
|
||||
+ if (nested)
|
||||
+ ok(thread_count == nested_threads, "expected %d thread, got %d\n", nested_threads, thread_count);
|
||||
+ else
|
||||
+ ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
+
|
||||
+ p_vcomp_set_num_threads(4);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
|
||||
+ if (nested)
|
||||
+ ok(thread_count == 4 , "expected 4 thread, got %d\n", thread_count);
|
||||
+ else
|
||||
+ ok(thread_count == 1 , "expected 1 thread, got %d\n", thread_count);
|
||||
+}
|
||||
+
|
||||
+static void test_omp_get_num_threads(BOOL nested)
|
||||
+{
|
||||
+ int is_nested, max_threads, num_threads, thread_num;
|
||||
+ LONG thread_count;
|
||||
+
|
||||
+ pomp_set_nested(nested);
|
||||
+ is_nested = pomp_get_nested();
|
||||
+ ok(is_nested == nested, "expected %d, got %d\n", nested, is_nested);
|
||||
+
|
||||
+ max_threads = pomp_get_max_threads();
|
||||
+ ok(max_threads >= 1, "expected max_threads >= 1, got %d\n", max_threads);
|
||||
+ thread_num = pomp_get_thread_num();
|
||||
+ ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num);
|
||||
+
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, max_threads, &thread_count);
|
||||
+ ok(thread_count == max_threads, "expected %d threads, got %d\n", max_threads, thread_count);
|
||||
+
|
||||
+ pomp_set_num_threads(2);
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 2, &thread_count);
|
||||
+ ok(thread_count == 2, "expected 2 threads, got %d\n", thread_count);
|
||||
+
|
||||
+ pomp_set_num_threads(4);
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
|
||||
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
+
|
||||
+ p_vcomp_set_num_threads(8);
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
|
||||
+ ok(thread_count == 8, "expected 8 threads, got %d\n", thread_count);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
|
||||
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
+
|
||||
+ p_vcomp_set_num_threads(0);
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
|
||||
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
+
|
||||
+ pomp_set_num_threads(0);
|
||||
+ num_threads = pomp_get_num_threads();
|
||||
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
|
||||
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
+
|
||||
+ pomp_set_num_threads(max_threads);
|
||||
+ pomp_set_nested(FALSE);
|
||||
+}
|
||||
+
|
||||
+START_TEST(vcomp)
|
||||
+{
|
||||
+ if (!init_vcomp())
|
||||
+ return;
|
||||
+
|
||||
+ test_omp_get_num_threads(FALSE);
|
||||
+ test_omp_get_num_threads(TRUE);
|
||||
+
|
||||
+ release_vcomp();
|
||||
+}
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
From e9d9801b549a73db5666c51c14200aeca63725b4 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
Date: Tue, 14 Jul 2015 21:42:31 +0200
|
||||
Subject: vcomp/tests: Add additional tests for _vcomp_fork.
|
||||
|
||||
Changes:
|
||||
* The number of threads is now set to 4 before running the tests.
|
||||
* Some functions were renamed.
|
||||
* All fork tests are now in a single test_*() function.
|
||||
* Various ok(...) messages were improved.
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 65 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index b084791..a9b975d 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Unit test suite for vcomp
|
||||
*
|
||||
+ * Copyright 2012 Dan Kegel
|
||||
* Copyright 2015 Sebastian Lackner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -278,6 +279,69 @@ static void test_omp_get_num_threads(BOOL nested)
|
||||
pomp_set_nested(FALSE);
|
||||
}
|
||||
|
||||
+static void CDECL fork_ptr_cb(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e)
|
||||
+{
|
||||
+ InterlockedIncrement(a);
|
||||
+ InterlockedIncrement(b);
|
||||
+ InterlockedIncrement(c);
|
||||
+ InterlockedIncrement(d);
|
||||
+ InterlockedIncrement(e);
|
||||
+}
|
||||
+
|
||||
+static void CDECL fork_uintptr_cb(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e)
|
||||
+{
|
||||
+ ok(a == 1, "expected a == 1, got %p\n", (void *)a);
|
||||
+ ok(b == MAXUINT_PTR - 2, "expected b == MAXUINT_PTR - 2, got %p\n", (void *)b);
|
||||
+ ok(c == 3, "expected c == 3, got %p\n", (void *)c);
|
||||
+ ok(d == MAXUINT_PTR - 4, "expected d == MAXUINT_PTR - 4, got %p\n", (void *)d);
|
||||
+ ok(e == 5, "expected e == 5, got %p\n", (void *)e);
|
||||
+}
|
||||
+
|
||||
+static void CDECL fork_float_cb(float a, float b, float c, float d, float e)
|
||||
+{
|
||||
+ ok(1.4999 < a && a < 1.5001, "expected a == 1.5, got %f\n", a);
|
||||
+ ok(2.4999 < b && b < 2.5001, "expected b == 2.5, got %f\n", b);
|
||||
+ ok(3.4999 < c && c < 3.5001, "expected c == 3.5, got %f\n", c);
|
||||
+ ok(4.4999 < d && d < 4.5001, "expected d == 4.5, got %f\n", d);
|
||||
+ ok(5.4999 < e && e < 5.5001, "expected e == 5.5, got %f\n", e);
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_fork(void)
|
||||
+{
|
||||
+ LONG a, b, c, d, e;
|
||||
+ int max_threads = pomp_get_max_threads();
|
||||
+ pomp_set_num_threads(4);
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(FALSE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
|
||||
+ ok(a == 1, "expected a == 1, got %d\n", a);
|
||||
+ ok(b == 2, "expected b == 2, got %d\n", b);
|
||||
+ ok(c == 3, "expected c == 3, got %d\n", c);
|
||||
+ ok(d == 4, "expected d == 4, got %d\n", d);
|
||||
+ ok(e == 5, "expected e == 5, got %d\n", e);
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(TRUE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
|
||||
+ ok(a == 4, "expected a == 4, got %d\n", a);
|
||||
+ ok(b == 5, "expected b == 5, got %d\n", b);
|
||||
+ ok(c == 6, "expected c == 6, got %d\n", c);
|
||||
+ ok(d == 7, "expected d == 7, got %d\n", d);
|
||||
+ ok(e == 8, "expected e == 8, got %d\n", e);
|
||||
+
|
||||
+ p_vcomp_fork(TRUE, 5, fork_uintptr_cb, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2),
|
||||
+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5);
|
||||
+
|
||||
+ if (sizeof(int) < sizeof(void *))
|
||||
+ skip("skipping float test on x86_64\n");
|
||||
+ else
|
||||
+ {
|
||||
+ void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork;
|
||||
+ func(TRUE, 5, fork_float_cb, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f);
|
||||
+ }
|
||||
+
|
||||
+ pomp_set_num_threads(max_threads);
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -285,6 +349,7 @@ START_TEST(vcomp)
|
||||
|
||||
test_omp_get_num_threads(FALSE);
|
||||
test_omp_get_num_threads(TRUE);
|
||||
+ test_vcomp_fork();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From f455eb53b0d527874fb95bdc652d1a31cd8fa93a Mon Sep 17 00:00:00 2001
|
||||
From 7b64b41a512320a89e7758db43343ebe99c0f563 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 18:59:41 +0200
|
||||
Subject: vcomp: Implement _vcomp_for_static_simple_init and
|
||||
@@ -12,25 +12,25 @@ Subject: vcomp: Implement _vcomp_for_static_simple_init and
|
||||
4 files changed, 96 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 9de9721..400f93a 100644
|
||||
index bcaa4ea..fcbd747 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -174,6 +174,96 @@ void CDECL _vcomp_single_end(void)
|
||||
@@ -301,6 +301,96 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step, BOOL forward,
|
||||
+ unsigned int *begin, unsigned int *end)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations, per_thread, remaining;
|
||||
+ DWORD num_threads, thread_num;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %p, %p)\n", first, last, step, forward, begin, end);
|
||||
+
|
||||
+ num_threads = team_info->num_threads;
|
||||
+ thread_num = thread_info->thread_num;
|
||||
+ num_threads = team_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+
|
||||
+ if (num_threads == 1)
|
||||
+ {
|
||||
@@ -109,9 +109,9 @@ index 9de9721..400f93a 100644
|
||||
+ TRACE("()\n");
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index d446574..b14edca 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
@@ -1,49 +1,37 @@
|
||||
From af8411c2c51708c2edbc620b3d775bf5a08144f9 Mon Sep 17 00:00:00 2001
|
||||
From 656f0051550426759e8f6ab287391bbe6a168418 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 05:12:39 +0200
|
||||
Subject: vcomp/tests: Add tests for _vcomp_for_static_simple_init.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 228 insertions(+)
|
||||
dlls/vcomp/tests/vcomp.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 220 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 5c6a861..1971b6d 100644
|
||||
index a9b975d..34c1ebc 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -23,8 +23,15 @@
|
||||
static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static HMODULE hvcomp = 0;
|
||||
+static void (CDECL *p_vcomp_barrier)(void);
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (CDECL *p_vcomp_for_static_end)(void);
|
||||
+static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
+ BOOL forward, unsigned int *begin, unsigned int *end);
|
||||
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
|
||||
static int (CDECL *pomp_get_max_threads)(void);
|
||||
+static int (CDECL *pomp_get_num_threads)(void);
|
||||
+static int (CDECL *pomp_get_thread_num)(void);
|
||||
+static void (CDECL *pomp_set_num_threads)(int num_threads);
|
||||
|
||||
#define VCOMP_GET_PROC(func) \
|
||||
do \
|
||||
@@ -43,8 +50,14 @@ static BOOL init_vcomp(void)
|
||||
return FALSE;
|
||||
@@ -168,6 +171,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
+ VCOMP_GET_PROC(_vcomp_barrier);
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
VCOMP_GET_PROC(_vcomp_fork);
|
||||
VCOMP_GET_PROC(_vcomp_set_num_threads);
|
||||
VCOMP_GET_PROC(omp_get_max_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_num_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_thread_num);
|
||||
+ VCOMP_GET_PROC(omp_set_num_threads);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -111,12 +124,227 @@ static void test_vcomp_fork(void)
|
||||
}
|
||||
@@ -342,6 +347,220 @@ static void test_vcomp_fork(void)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+static void CDECL _test_vcomp_for_static_simple_init(void)
|
||||
@@ -263,12 +251,13 @@ index 5c6a861..1971b6d 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
return;
|
||||
|
||||
@@ -350,6 +569,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(FALSE);
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
+ test_vcomp_for_static_simple_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
@@ -1,66 +0,0 @@
|
||||
From 8732b345bcab27edc68eda1ab35095d72a817899 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 19:38:24 +0200
|
||||
Subject: vcomp: Implement _vcomp_barrier.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 29 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 2eeea3b..4f3471a 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -68,6 +68,10 @@ struct vcomp_team_info
|
||||
unsigned int nargs;
|
||||
void *wrapper;
|
||||
__ms_va_list valist;
|
||||
+
|
||||
+ /* barrier */
|
||||
+ DWORD barrier;
|
||||
+ DWORD barrier_count;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -154,7 +158,28 @@ void CDECL omp_set_num_threads(int num_threads)
|
||||
|
||||
void CDECL _vcomp_barrier(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
+ struct vcomp_team_info *team_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ team_info = vcomp_get_team_info();
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ team_info->barrier_count++;
|
||||
+ if (team_info->barrier_count >= team_info->num_threads)
|
||||
+ {
|
||||
+ team_info->barrier++;
|
||||
+ team_info->barrier_count = 0;
|
||||
+ WakeAllConditionVariable(&team_info->cond);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ DWORD barrier = team_info->barrier;
|
||||
+ while (team_info->barrier == barrier)
|
||||
+ SleepConditionVariableCS(&team_info->cond, &vcomp_section, INFINITE);
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
}
|
||||
|
||||
void CDECL _vcomp_set_num_threads(int num_threads)
|
||||
@@ -385,6 +410,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_info.nargs = nargs;
|
||||
team_info.wrapper = wrapper;
|
||||
__ms_va_start(team_info.valist, wrapper);
|
||||
+ team_info.barrier = 0;
|
||||
+ team_info.barrier_count = 0;
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
--
|
||||
2.4.5
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From 721c89ed7aec4a9ae8f0a5f7b0efeee838c08985 Mon Sep 17 00:00:00 2001
|
||||
From ed0734ad10de657efb30ec7c851d20d20ba79a0a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 19:19:00 +0200
|
||||
Subject: vcomp: Implement _vcomp_for_static_init.
|
||||
@@ -11,26 +11,26 @@ Subject: vcomp: Implement _vcomp_for_static_init.
|
||||
4 files changed, 65 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 400f93a..2eeea3b 100644
|
||||
index fcbd747..b22dd37 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -259,6 +259,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
@@ -386,6 +386,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
}
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_static_init(int first, int last, int step, int chunksize, unsigned int *loops,
|
||||
+ int *begin, int *end, int *next, int *lastchunk)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations, num_chunks, per_thread, remaining;
|
||||
+ DWORD num_threads, thread_num;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p)\n",
|
||||
+ first, last, step, chunksize, loops, begin, end, next, lastchunk);
|
||||
+
|
||||
+ num_threads = team_info->num_threads;
|
||||
+ thread_num = thread_info->thread_num;
|
||||
+ num_threads = team_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+
|
||||
+ if (chunksize < 1)
|
||||
+ chunksize = 1;
|
||||
@@ -1,4 +1,4 @@
|
||||
From 9cea1ba140eb5d8ecd70eab4a68e309cd80fd454 Mon Sep 17 00:00:00 2001
|
||||
From 39cd9028667159d38193fca46691b7cdbc0fe82b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 06:08:08 +0200
|
||||
Subject: vcomp/tests: Add tests for _vcomp_for_static_init.
|
||||
@@ -8,11 +8,11 @@ Subject: vcomp/tests: Add tests for _vcomp_for_static_init.
|
||||
1 file changed, 199 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 1971b6d..96806fd 100644
|
||||
index 34c1ebc..0103af1 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -25,6 +25,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
static HMODULE hvcomp = 0;
|
||||
@@ -33,6 +33,8 @@ static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
static void (CDECL *p_vcomp_for_static_end)(void);
|
||||
+static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops,
|
||||
@@ -20,15 +20,15 @@ index 1971b6d..96806fd 100644
|
||||
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
BOOL forward, unsigned int *begin, unsigned int *end);
|
||||
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
@@ -52,6 +54,7 @@ static BOOL init_vcomp(void)
|
||||
@@ -172,6 +174,7 @@ static BOOL init_vcomp(void)
|
||||
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
VCOMP_GET_PROC(_vcomp_fork);
|
||||
VCOMP_GET_PROC(omp_get_max_threads);
|
||||
@@ -338,6 +341,201 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
VCOMP_GET_PROC(_vcomp_set_num_threads);
|
||||
@@ -561,6 +564,201 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,13 +230,13 @@ index 1971b6d..96806fd 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -345,6 +543,7 @@ START_TEST(vcomp)
|
||||
|
||||
@@ -570,6 +768,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
test_vcomp_for_static_simple_init();
|
||||
+ test_vcomp_for_static_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
@@ -1,4 +1,4 @@
|
||||
From aad24232add010020898eaa1a0934cb353c123f2 Mon Sep 17 00:00:00 2001
|
||||
From d9ec7f94c0ecefeccf49f1d09bf458eb90472faf Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 19:41:29 +0200
|
||||
Subject: vcomp: Implement omp_in_parallel.
|
||||
@@ -11,22 +11,22 @@ Subject: vcomp: Implement omp_in_parallel.
|
||||
4 files changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 4f3471a..fccad93 100644
|
||||
index b22dd37..a9a49ce 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -351,6 +351,12 @@ void CDECL _vcomp_for_static_end(void)
|
||||
@@ -453,6 +453,12 @@ void CDECL _vcomp_for_static_end(void)
|
||||
TRACE("()\n");
|
||||
}
|
||||
|
||||
+int CDECL omp_in_parallel(void)
|
||||
+{
|
||||
+ TRACE("()\n");
|
||||
+ return vcomp_get_team_info() != NULL;
|
||||
+ return vcomp_init_thread_data()->team != NULL;
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 8bc66e8..156233f 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
@@ -1,4 +1,4 @@
|
||||
From 77d6daebca21cfb4209a8281abac2b9db0d7a1b4 Mon Sep 17 00:00:00 2001
|
||||
From 92b615e0038571e52fb6cc22164ba80c07dcf2f5 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 21:29:41 +0200
|
||||
Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and
|
||||
@@ -13,129 +13,127 @@ Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and
|
||||
5 files changed, 104 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index fccad93..db47ff6 100644
|
||||
index a9a49ce..31814d6 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -56,6 +56,9 @@ struct vcomp_thread_info
|
||||
/* current task */
|
||||
struct vcomp_team_info *team;
|
||||
DWORD thread_num;
|
||||
@@ -58,6 +58,9 @@ struct vcomp_thread_data
|
||||
/* only used for concurrent tasks */
|
||||
struct list entry;
|
||||
CONDITION_VARIABLE cond;
|
||||
+
|
||||
+ /* section */
|
||||
+ DWORD section;
|
||||
+ unsigned int section;
|
||||
};
|
||||
|
||||
struct vcomp_team_info
|
||||
@@ -72,6 +75,11 @@ struct vcomp_team_info
|
||||
struct vcomp_team_data
|
||||
@@ -74,6 +77,11 @@ struct vcomp_team_data
|
||||
/* barrier */
|
||||
DWORD barrier;
|
||||
DWORD barrier_count;
|
||||
unsigned int barrier;
|
||||
int barrier_count;
|
||||
+
|
||||
+ /* section */
|
||||
+ DWORD section;
|
||||
+ DWORD num_sections;
|
||||
+ DWORD section_index;
|
||||
+ unsigned int section;
|
||||
+ unsigned int num_sections;
|
||||
+ unsigned int section_index;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -357,6 +365,43 @@ int CDECL omp_in_parallel(void)
|
||||
return vcomp_get_team_info() != NULL;
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
@@ -453,6 +461,43 @@ void CDECL _vcomp_for_static_end(void)
|
||||
TRACE("()\n");
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_sections_init(int n)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+
|
||||
+ TRACE("(%d)\n", n);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ thread_info->section++;
|
||||
+ if ((int)(thread_info->section - team_info->section) > 0)
|
||||
+ thread_data->section++;
|
||||
+ if ((int)(thread_data->section - team_data->section) > 0)
|
||||
+ {
|
||||
+ /* first thread in a new section */
|
||||
+ team_info->section = thread_info->section;
|
||||
+ team_info->num_sections = n;
|
||||
+ team_info->section_index = 0;
|
||||
+ team_data->section = thread_data->section;
|
||||
+ team_data->num_sections = n;
|
||||
+ team_data->section_index = 0;
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+}
|
||||
+
|
||||
+int CDECL _vcomp_sections_next(void)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ int i = -1;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ if (thread_info->section == team_info->section &&
|
||||
+ team_info->section_index < team_info->num_sections)
|
||||
+ if (thread_data->section == team_data->section &&
|
||||
+ team_data->section_index < team_data->num_sections)
|
||||
+ {
|
||||
+ i = team_info->section_index++;
|
||||
+ i = team_data->section_index++;
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
int CDECL omp_in_parallel(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
@@ -526,10 +571,12 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
__ms_va_start(team_data.valist, wrapper);
|
||||
team_data.barrier = 0;
|
||||
team_data.barrier_count = 0;
|
||||
+ team_data.section = 0;
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
@@ -418,12 +463,14 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
__ms_va_start(team_info.valist, wrapper);
|
||||
team_info.barrier = 0;
|
||||
team_info.barrier_count = 0;
|
||||
+ team_info.section = -1;
|
||||
thread_data.team = &team_data;
|
||||
thread_data.thread_num = 0;
|
||||
thread_data.fork_threads = 0;
|
||||
+ thread_data.section = 1;
|
||||
list_init(&thread_data.entry);
|
||||
InitializeConditionVariable(&thread_data.cond);
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
InitializeConditionVariable(&thread_info.cond);
|
||||
thread_info.team = &team_info;
|
||||
thread_info.thread_num = 0;
|
||||
+ thread_info.section = 0;
|
||||
@@ -545,6 +592,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->team = &team_data;
|
||||
data->thread_num = team_data.num_threads++;
|
||||
data->fork_threads = 0;
|
||||
+ data->section = 1;
|
||||
list_remove(&data->entry);
|
||||
list_add_tail(&thread_data.entry, &data->entry);
|
||||
WakeAllConditionVariable(&data->cond);
|
||||
@@ -563,6 +611,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->team = &team_data;
|
||||
data->thread_num = team_data.num_threads;
|
||||
data->fork_threads = 0;
|
||||
+ data->section = 1;
|
||||
InitializeConditionVariable(&data->cond);
|
||||
|
||||
if (parallel)
|
||||
{
|
||||
@@ -439,6 +486,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
list_add_tail(&thread_info.entry, &info->entry);
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads++;
|
||||
+ info->section = 0;
|
||||
WakeAllConditionVariable(&info->cond);
|
||||
}
|
||||
|
||||
@@ -455,6 +503,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
InitializeConditionVariable(&info->cond);
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads;
|
||||
+ info->section = 0;
|
||||
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
if (!thread)
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 96806fd..902a836 100644
|
||||
index 0103af1..c962fe8 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -30,6 +30,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i
|
||||
@@ -38,6 +38,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i
|
||||
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
BOOL forward, unsigned int *begin, unsigned int *end);
|
||||
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
+static void (CDECL *p_vcomp_sections_init)(int n);
|
||||
+static int (CDECL *p_vcomp_sections_next)(void);
|
||||
static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
|
||||
static int (CDECL *pomp_get_max_threads)(void);
|
||||
static int (CDECL *pomp_get_num_threads)(void);
|
||||
static int (CDECL *pomp_get_thread_num)(void);
|
||||
@@ -57,6 +59,8 @@ static BOOL init_vcomp(void)
|
||||
static int (CDECL *pomp_get_nested)(void);
|
||||
@@ -177,6 +179,8 @@ static BOOL init_vcomp(void)
|
||||
VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
VCOMP_GET_PROC(_vcomp_fork);
|
||||
+ VCOMP_GET_PROC(_vcomp_sections_init);
|
||||
+ VCOMP_GET_PROC(_vcomp_sections_next);
|
||||
VCOMP_GET_PROC(_vcomp_set_num_threads);
|
||||
VCOMP_GET_PROC(omp_get_max_threads);
|
||||
VCOMP_GET_PROC(omp_get_num_threads);
|
||||
VCOMP_GET_PROC(omp_get_thread_num);
|
||||
@@ -536,6 +540,50 @@ static void test_vcomp_for_static_init(void)
|
||||
VCOMP_GET_PROC(omp_get_nested);
|
||||
@@ -759,6 +763,50 @@ static void test_vcomp_for_static_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,13 +184,13 @@ index 96806fd..902a836 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -544,6 +592,7 @@ START_TEST(vcomp)
|
||||
@@ -769,6 +817,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_fork();
|
||||
test_vcomp_for_static_simple_init();
|
||||
test_vcomp_for_static_init();
|
||||
+ test_vcomp_sections_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 156233f..7083ce4 100644
|
||||
@@ -1,4 +1,4 @@
|
||||
From f29610acbf9ce393b772520f6041acce9d1aefd8 Mon Sep 17 00:00:00 2001
|
||||
From 145ddf41060e93e9f320d5d2e4347dd2c7b8a83f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 23:28:31 +0200
|
||||
Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next
|
||||
@@ -13,23 +13,23 @@ Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next
|
||||
5 files changed, 152 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index db47ff6..3a1e9ee 100644
|
||||
index 31814d6..174ce06 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -59,6 +59,9 @@ struct vcomp_thread_info
|
||||
@@ -61,6 +61,9 @@ struct vcomp_thread_data
|
||||
|
||||
/* section */
|
||||
DWORD section;
|
||||
unsigned int section;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ DWORD dynamic;
|
||||
+ unsigned int dynamic;
|
||||
};
|
||||
|
||||
struct vcomp_team_info
|
||||
@@ -80,6 +83,15 @@ struct vcomp_team_info
|
||||
DWORD section;
|
||||
DWORD num_sections;
|
||||
DWORD section_index;
|
||||
struct vcomp_team_data
|
||||
@@ -82,6 +85,15 @@ struct vcomp_team_data
|
||||
unsigned int section;
|
||||
unsigned int num_sections;
|
||||
unsigned int section_index;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ DWORD dynamic;
|
||||
@@ -41,23 +41,23 @@ index db47ff6..3a1e9ee 100644
|
||||
+ DWORD dynamic_min_chunksize;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -402,6 +414,83 @@ int CDECL _vcomp_sections_next(void)
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
@@ -498,6 +510,83 @@ int CDECL _vcomp_sections_next(void)
|
||||
return i;
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int step, int chunksize)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations;
|
||||
+ BOOL forward = (flags & 0x40) != 0;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %d)\n", flags, first, last, step, chunksize);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ thread_info->dynamic++;
|
||||
+ if ((int)(thread_info->dynamic - team_info->dynamic) > 0)
|
||||
+ thread_data->dynamic++;
|
||||
+ if ((int)(thread_data->dynamic - team_data->dynamic) > 0)
|
||||
+ {
|
||||
+ /* first thread in a new for_dynamic */
|
||||
+
|
||||
@@ -76,102 +76,100 @@ index db47ff6..3a1e9ee 100644
|
||||
+ iterations = 1 + (first64 - last) / step;
|
||||
+ }
|
||||
+
|
||||
+ team_info->dynamic = thread_info->dynamic;
|
||||
+ team_info->dynamic_forward = forward;
|
||||
+ team_info->dynamic_first = first;
|
||||
+ team_info->dynamic_iterations = iterations;
|
||||
+ team_info->dynamic_step = step;
|
||||
+ team_info->dynamic_chunksize = max(1, iterations / team_info->num_threads);
|
||||
+ team_info->dynamic_min_chunksize = max(1, chunksize);
|
||||
+ team_data->dynamic = thread_data->dynamic;
|
||||
+ team_data->dynamic_forward = forward;
|
||||
+ team_data->dynamic_first = first;
|
||||
+ team_data->dynamic_iterations = iterations;
|
||||
+ team_data->dynamic_step = step;
|
||||
+ team_data->dynamic_chunksize = max(1, iterations / team_data->num_threads);
|
||||
+ team_data->dynamic_min_chunksize = max(1, chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+}
|
||||
+
|
||||
+int CDECL _vcomp_for_dynamic_next(int *begin, int *end)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations = 0;
|
||||
+
|
||||
+ TRACE("(%p, %p)\n", begin, end);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ if (thread_info->dynamic == team_info->dynamic &&
|
||||
+ team_info->dynamic_iterations != 0)
|
||||
+ if (thread_data->dynamic == team_data->dynamic &&
|
||||
+ team_data->dynamic_iterations != 0)
|
||||
+ {
|
||||
+ iterations = min(team_info->dynamic_iterations, team_info->dynamic_chunksize);
|
||||
+ team_info->dynamic_iterations -= iterations;
|
||||
+ iterations = min(team_data->dynamic_iterations, team_data->dynamic_chunksize);
|
||||
+ team_data->dynamic_iterations -= iterations;
|
||||
+
|
||||
+ if (team_info->dynamic_forward)
|
||||
+ if (team_data->dynamic_forward)
|
||||
+ {
|
||||
+ *begin = team_info->dynamic_first;
|
||||
+ *end = team_info->dynamic_first + (iterations - 1) * team_info->dynamic_step;
|
||||
+ team_info->dynamic_first += iterations * team_info->dynamic_step;
|
||||
+ *begin = team_data->dynamic_first;
|
||||
+ *end = team_data->dynamic_first + (iterations - 1) * team_data->dynamic_step;
|
||||
+ team_data->dynamic_first += iterations * team_data->dynamic_step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = team_info->dynamic_first;
|
||||
+ *end = team_info->dynamic_first - (iterations - 1) * team_info->dynamic_step;
|
||||
+ team_info->dynamic_first -= iterations * team_info->dynamic_step;
|
||||
+ *begin = team_data->dynamic_first;
|
||||
+ *end = team_data->dynamic_first - (iterations - 1) * team_data->dynamic_step;
|
||||
+ team_data->dynamic_first -= iterations * team_data->dynamic_step;
|
||||
+ }
|
||||
+
|
||||
+ team_info->dynamic_chunksize =
|
||||
+ max((team_info->dynamic_chunksize * 3 + 2)/4, team_info->dynamic_min_chunksize);
|
||||
+ team_data->dynamic_chunksize =
|
||||
+ max((team_data->dynamic_chunksize * 3 + 2)/4, team_data->dynamic_min_chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ return (iterations != 0);
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
int CDECL omp_in_parallel(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
@@ -572,11 +661,13 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_data.barrier = 0;
|
||||
team_data.barrier_count = 0;
|
||||
team_data.section = 0;
|
||||
+ team_data.dynamic = 0;
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
@@ -464,6 +553,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_info.barrier = 0;
|
||||
team_info.barrier_count = 0;
|
||||
team_info.section = -1;
|
||||
+ team_info.dynamic = -1;
|
||||
thread_data.team = &team_data;
|
||||
thread_data.thread_num = 0;
|
||||
thread_data.fork_threads = 0;
|
||||
thread_data.section = 1;
|
||||
+ thread_data.dynamic = 1;
|
||||
list_init(&thread_data.entry);
|
||||
InitializeConditionVariable(&thread_data.cond);
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
@@ -471,6 +561,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
thread_info.team = &team_info;
|
||||
thread_info.thread_num = 0;
|
||||
thread_info.section = 0;
|
||||
+ thread_info.dynamic = 0;
|
||||
@@ -593,6 +684,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->thread_num = team_data.num_threads++;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
+ data->dynamic = 1;
|
||||
list_remove(&data->entry);
|
||||
list_add_tail(&thread_data.entry, &data->entry);
|
||||
WakeAllConditionVariable(&data->cond);
|
||||
@@ -612,6 +704,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->thread_num = team_data.num_threads;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
+ data->dynamic = 1;
|
||||
InitializeConditionVariable(&data->cond);
|
||||
|
||||
if (parallel)
|
||||
{
|
||||
@@ -487,6 +578,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads++;
|
||||
info->section = 0;
|
||||
+ info->dynamic = 0;
|
||||
WakeAllConditionVariable(&info->cond);
|
||||
}
|
||||
|
||||
@@ -504,6 +596,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads;
|
||||
info->section = 0;
|
||||
+ info->dynamic = 0;
|
||||
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
if (!thread)
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 902a836..4273680 100644
|
||||
index c962fe8..af04cc9 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -24,6 +24,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
@@ -32,6 +32,8 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static HMODULE hvcomp = 0;
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (CDECL *p_vcomp_for_dynamic_init)(int flags, int first, int last, int step, int chunksize);
|
||||
+static int (CDECL *p_vcomp_for_dynamic_next)(int *begin, int *end);
|
||||
static void (CDECL *p_vcomp_for_static_end)(void);
|
||||
static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops,
|
||||
int *begin, int *end, int *next, int *lastchunk);
|
||||
@@ -55,6 +57,8 @@ static BOOL init_vcomp(void)
|
||||
@@ -175,6 +177,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
@@ -180,7 +178,7 @@ index 902a836..4273680 100644
|
||||
VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
@@ -584,6 +588,54 @@ static void test_vcomp_sections_init(void)
|
||||
@@ -807,6 +811,54 @@ static void test_vcomp_sections_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,13 +233,13 @@ index 902a836..4273680 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -593,6 +645,7 @@ START_TEST(vcomp)
|
||||
@@ -818,6 +870,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_for_static_simple_init();
|
||||
test_vcomp_for_static_init();
|
||||
test_vcomp_sections_init();
|
||||
+ test_vcomp_for_dynamic_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 7083ce4..1b02a65 100644
|
||||
Reference in New Issue
Block a user