mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
vcomp-Functions: Update vcomp patches and add various improvements.
This commit is contained in:
parent
c1c337b07c
commit
679a5cef17
@ -4485,19 +4485,25 @@ fi
|
||||
# | dlls/vcomp90/vcomp90.spec
|
||||
# |
|
||||
if test "$enable_vcomp_Functions" -eq 1; then
|
||||
patch_apply vcomp-Functions/0001-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch
|
||||
patch_apply vcomp-Functions/0002-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch
|
||||
patch_apply vcomp-Functions/0003-vcomp-Implement-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0004-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0005-vcomp-Implement-omp_in_parallel.patch
|
||||
patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch
|
||||
patch_apply vcomp-Functions/0001-vcomp-Split-team-data-and-task-data.patch
|
||||
patch_apply vcomp-Functions/0002-vcomp-Fix-handling-of-_vcomp_fork-with-ifval-FALSE.patch
|
||||
patch_apply vcomp-Functions/0003-vcomp-Implement-omp_in_parallel-and-add-tests.patch
|
||||
patch_apply vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch
|
||||
patch_apply vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch
|
||||
patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0008-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch
|
||||
patch_apply vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_dynamic_init.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Split team data and task data.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Fix handling of _vcomp_fork with ifval == FALSE.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement omp_in_parallel and add tests.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_simple_init and _vcomp_for_static_end.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_simple_init.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_init.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_init.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement omp_in_parallel.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next and add tests.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_dynamic_init.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
@ -0,0 +1,192 @@
|
||||
From 52ef17d8550f05778f548cc01fce2a0eaa3b223b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Jul 2015 17:22:01 +0200
|
||||
Subject: vcomp: Split team data and task data.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 47 ++++++++++++++++++++++++++++++++++-------------
|
||||
dlls/vcomp/tests/vcomp.c | 20 ++++++++++++++++++++
|
||||
2 files changed, 54 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 0f8a272..8866b15 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -52,6 +52,7 @@ static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
struct vcomp_thread_data
|
||||
{
|
||||
struct vcomp_team_data *team;
|
||||
+ struct vcomp_task_data *task;
|
||||
int thread_num;
|
||||
int fork_threads;
|
||||
|
||||
@@ -77,7 +78,10 @@ struct vcomp_team_data
|
||||
/* barrier */
|
||||
unsigned int barrier;
|
||||
int barrier_count;
|
||||
+};
|
||||
|
||||
+struct vcomp_task_data
|
||||
+{
|
||||
/* section */
|
||||
unsigned int section;
|
||||
int num_sections;
|
||||
@@ -177,20 +181,32 @@ static inline void vcomp_set_thread_data(struct vcomp_thread_data *thread_data)
|
||||
TlsSetValue(vcomp_context_tls, thread_data);
|
||||
}
|
||||
|
||||
+struct vcomp_thread_and_task_data
|
||||
+{
|
||||
+ struct vcomp_thread_data thread;
|
||||
+ struct vcomp_task_data task;
|
||||
+};
|
||||
+
|
||||
static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_task_data *task_data;
|
||||
if (thread_data) return thread_data;
|
||||
|
||||
- if (!(thread_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*thread_data))))
|
||||
+ if (!(thread_data = HeapAlloc(GetProcessHeap(), 0, sizeof(struct vcomp_thread_and_task_data))))
|
||||
{
|
||||
ERR("could not create thread data\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
+ task_data = &((struct vcomp_thread_and_task_data *)thread_data)->task;
|
||||
+ task_data->section = 0;
|
||||
+
|
||||
thread_data->team = NULL;
|
||||
+ thread_data->task = task_data;
|
||||
thread_data->thread_num = 0;
|
||||
thread_data->fork_threads = 0;
|
||||
+ thread_data->section = 1;
|
||||
|
||||
vcomp_set_thread_data(thread_data);
|
||||
return thread_data;
|
||||
@@ -311,35 +327,35 @@ void CDECL _vcomp_single_end(void)
|
||||
|
||||
void CDECL _vcomp_sections_init(int n)
|
||||
{
|
||||
- struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
- struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_task_data *task_data = thread_data->task;
|
||||
|
||||
TRACE("(%d)\n", n);
|
||||
|
||||
EnterCriticalSection(&vcomp_section);
|
||||
thread_data->section++;
|
||||
- if ((int)(thread_data->section - team_data->section) > 0)
|
||||
+ if ((int)(thread_data->section - task_data->section) > 0)
|
||||
{
|
||||
- team_data->section = thread_data->section;
|
||||
- team_data->num_sections = n;
|
||||
- team_data->section_index = 0;
|
||||
+ task_data->section = thread_data->section;
|
||||
+ task_data->num_sections = n;
|
||||
+ task_data->section_index = 0;
|
||||
}
|
||||
LeaveCriticalSection(&vcomp_section);
|
||||
}
|
||||
|
||||
int CDECL _vcomp_sections_next(void)
|
||||
{
|
||||
- struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
- struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_task_data *task_data = thread_data->task;
|
||||
int i = -1;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
EnterCriticalSection(&vcomp_section);
|
||||
- if (thread_data->section == team_data->section &&
|
||||
- team_data->section_index != team_data->num_sections)
|
||||
+ if (thread_data->section == task_data->section &&
|
||||
+ task_data->section_index != task_data->num_sections)
|
||||
{
|
||||
- i = team_data->section_index++;
|
||||
+ i = task_data->section_index++;
|
||||
}
|
||||
LeaveCriticalSection(&vcomp_section);
|
||||
return i;
|
||||
@@ -391,6 +407,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data();
|
||||
struct vcomp_thread_data thread_data;
|
||||
struct vcomp_team_data team_data;
|
||||
+ struct vcomp_task_data task_data;
|
||||
int num_threads;
|
||||
|
||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
@@ -412,9 +429,11 @@ 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;
|
||||
+
|
||||
+ task_data.section = 0;
|
||||
|
||||
thread_data.team = &team_data;
|
||||
+ thread_data.task = &task_data;
|
||||
thread_data.thread_num = 0;
|
||||
thread_data.fork_threads = 0;
|
||||
thread_data.section = 1;
|
||||
@@ -431,6 +450,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
{
|
||||
struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry);
|
||||
data->team = &team_data;
|
||||
+ data->task = &task_data;
|
||||
data->thread_num = team_data.num_threads++;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
@@ -450,6 +470,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
if (!data) break;
|
||||
|
||||
data->team = &team_data;
|
||||
+ data->task = &task_data;
|
||||
data->thread_num = team_data.num_threads;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index c433991..a933a4e 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -378,6 +378,20 @@ static void test_vcomp_sections_init(void)
|
||||
int max_threads = pomp_get_max_threads();
|
||||
int i;
|
||||
|
||||
+if (0)
|
||||
+{
|
||||
+ /* calling _vcomp_sections_next without prior _vcomp_sections_init
|
||||
+ * returns uninitialized memory on Windows. */
|
||||
+ i = p_vcomp_sections_next();
|
||||
+ ok(i == -1, "expected -1, got %d\n", i);
|
||||
+}
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ section_cb(&a, &b, &c);
|
||||
+ ok(a == 20, "expected a = 20, got %d\n", a);
|
||||
+ ok(b == 30, "expected b = 30, got %d\n", b);
|
||||
+ ok(c == 40, "expected c = 40, got %d\n", c);
|
||||
+
|
||||
for (i = 1; i <= 4; i++)
|
||||
{
|
||||
pomp_set_num_threads(i);
|
||||
@@ -387,6 +401,12 @@ static void test_vcomp_sections_init(void)
|
||||
ok(a == 20, "expected a = 20, got %d\n", a);
|
||||
ok(b == 30, "expected b = 30, got %d\n", b);
|
||||
ok(c == 40, "expected c = 40, got %d\n", c);
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ p_vcomp_fork(FALSE, 3, section_cb, &a, &b, &c);
|
||||
+ ok(a == 20, "expected a = 20, got %d\n", a);
|
||||
+ ok(b == 30, "expected b = 30, got %d\n", b);
|
||||
+ ok(c == 40, "expected c = 40, got %d\n", c);
|
||||
}
|
||||
|
||||
pomp_set_num_threads(max_threads);
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,122 @@
|
||||
From fea70f187f3f04cfecd4c38014d51ea6a29d53c6 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Jul 2015 18:00:45 +0200
|
||||
Subject: vcomp: Fix handling of _vcomp_fork with ifval == FALSE.
|
||||
|
||||
Nested forks are still possible in this case, when it is not running inside
|
||||
of a parallel block.
|
||||
---
|
||||
dlls/vcomp/main.c | 10 ++++++++--
|
||||
dlls/vcomp/tests/vcomp.c | 23 ++++++++++++++++++++---
|
||||
2 files changed, 28 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 8866b15..8526d86 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -54,6 +54,7 @@ struct vcomp_thread_data
|
||||
struct vcomp_team_data *team;
|
||||
struct vcomp_task_data *task;
|
||||
int thread_num;
|
||||
+ BOOL parallel;
|
||||
int fork_threads;
|
||||
|
||||
/* only used for concurrent tasks */
|
||||
@@ -205,6 +206,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||
thread_data->team = NULL;
|
||||
thread_data->task = task_data;
|
||||
thread_data->thread_num = 0;
|
||||
+ thread_data->parallel = FALSE;
|
||||
thread_data->fork_threads = 0;
|
||||
thread_data->section = 1;
|
||||
|
||||
@@ -412,10 +414,11 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
|
||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
|
||||
+ if (prev_thread_data->parallel && !vcomp_nested_fork)
|
||||
+ ifval = FALSE;
|
||||
+
|
||||
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
|
||||
@@ -435,6 +438,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
thread_data.team = &team_data;
|
||||
thread_data.task = &task_data;
|
||||
thread_data.thread_num = 0;
|
||||
+ thread_data.parallel = ifval || prev_thread_data->parallel;
|
||||
thread_data.fork_threads = 0;
|
||||
thread_data.section = 1;
|
||||
list_init(&thread_data.entry);
|
||||
@@ -452,6 +456,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->team = &team_data;
|
||||
data->task = &task_data;
|
||||
data->thread_num = team_data.num_threads++;
|
||||
+ data->parallel = thread_data.parallel;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
list_remove(&data->entry);
|
||||
@@ -472,6 +477,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->team = &team_data;
|
||||
data->task = &task_data;
|
||||
data->thread_num = team_data.num_threads;
|
||||
+ data->parallel = thread_data.parallel;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
InitializeConditionVariable(&data->cond);
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index a933a4e..4dae41f 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -208,17 +208,21 @@ static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count)
|
||||
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);
|
||||
+ ok(thread_count == nested_threads, "expected %d threads, got %d\n", nested_threads, thread_count);
|
||||
else
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
|
||||
+ thread_count = 0;
|
||||
+ p_vcomp_fork(FALSE, 1, num_threads_cb2, &thread_count);
|
||||
+ 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);
|
||||
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
else
|
||||
- ok(thread_count == 1 , "expected 1 thread, got %d\n", thread_count);
|
||||
+ ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
}
|
||||
|
||||
static void test_omp_get_num_threads(BOOL nested)
|
||||
@@ -241,6 +245,19 @@ static void test_omp_get_num_threads(BOOL nested)
|
||||
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);
|
||||
|
||||
+ 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(FALSE, 3, num_threads_cb, TRUE, max_threads, &thread_count);
|
||||
+ ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
+
|
||||
+ pomp_set_num_threads(1);
|
||||
+ 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, 1, &thread_count);
|
||||
+ ok(thread_count == 1, "expected 1 thread, got %d\n", 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);
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,264 +0,0 @@
|
||||
From abd9917d138e9e7c4f4fa9c13c15c44072d604f8 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 | 220 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 220 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index c433991..bba1fe3 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
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_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);
|
||||
@@ -170,6 +173,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
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_sections_init);
|
||||
VCOMP_GET_PROC(_vcomp_sections_next);
|
||||
@@ -392,6 +397,220 @@ static void test_vcomp_sections_init(void)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+static void CDECL _test_vcomp_for_static_simple_init(void)
|
||||
+{
|
||||
+ static const struct
|
||||
+ {
|
||||
+ unsigned int first;
|
||||
+ unsigned int last;
|
||||
+ int step;
|
||||
+ BOOL forward;
|
||||
+ }
|
||||
+ tests[] =
|
||||
+ {
|
||||
+ /* loop forward, step 1 */
|
||||
+ { 0, 0, 1, TRUE },
|
||||
+ { 0, 1, 1, TRUE },
|
||||
+ { 0, 2, 1, TRUE },
|
||||
+ { 0, 3, 1, TRUE },
|
||||
+ { 0, 0x10000000, 1, TRUE },
|
||||
+ { 0, 0x20000000, 1, TRUE },
|
||||
+ { 0, 0x40000000, 1, TRUE },
|
||||
+ { 0, 0x80000000, 1, TRUE },
|
||||
+
|
||||
+ /* loop forward, varying step */
|
||||
+ { 0, 100, 1, TRUE },
|
||||
+ { 0, 100, 5, TRUE },
|
||||
+ { 0, 100, 10, TRUE },
|
||||
+ { 0, 100, 25, TRUE },
|
||||
+ { 0, 100, 50, TRUE },
|
||||
+ { 0, 100, 75, TRUE },
|
||||
+ { 0, 100, 100, TRUE },
|
||||
+ { 0, 100, 150, TRUE },
|
||||
+
|
||||
+ /* empty loop forward, varying step */
|
||||
+ { 50, 50, 3, TRUE },
|
||||
+ { 50, 50, 2, TRUE },
|
||||
+ { 50, 50, 1, TRUE },
|
||||
+ { 50, 50, 0, TRUE },
|
||||
+ { 50, 50, -1, TRUE },
|
||||
+ { 50, 50, -2, TRUE },
|
||||
+ { 50, 50, -3, TRUE },
|
||||
+
|
||||
+ /* loop backward, step 1 */
|
||||
+ { 0, 0, 1, FALSE },
|
||||
+ { 1, 0, 1, FALSE },
|
||||
+ { 2, 0, 1, FALSE },
|
||||
+ { 3, 0, 1, FALSE },
|
||||
+ { 0x10000000, 0, 1, FALSE },
|
||||
+ { 0x20000000, 0, 1, FALSE },
|
||||
+ { 0x40000000, 0, 1, FALSE },
|
||||
+ { 0x80000000, 0, 1, FALSE },
|
||||
+
|
||||
+ /* loop backward, varying step */
|
||||
+ { 100, 0, 1, FALSE },
|
||||
+ { 100, 0, 5, FALSE },
|
||||
+ { 100, 0, 10, FALSE },
|
||||
+ { 100, 0, 25, FALSE },
|
||||
+ { 100, 0, 50, FALSE },
|
||||
+ { 100, 0, 75, FALSE },
|
||||
+ { 100, 0, 100, FALSE },
|
||||
+ { 100, 0, 150, FALSE },
|
||||
+
|
||||
+ /* empty loop backward, varying step */
|
||||
+ { 50, 50, 3, FALSE },
|
||||
+ { 50, 50, 2, FALSE },
|
||||
+ { 50, 50, 1, FALSE },
|
||||
+ { 50, 50, 0, FALSE },
|
||||
+ { 50, 50, -1, FALSE },
|
||||
+ { 50, 50, -2, FALSE },
|
||||
+ { 50, 50, -3, FALSE },
|
||||
+
|
||||
+ /* test overflow in forward loop */
|
||||
+ { 0, 0, 1, TRUE },
|
||||
+ { 1, 0, 1, TRUE },
|
||||
+ { 2, 0, 1, TRUE },
|
||||
+ { 3, 0, 1, TRUE },
|
||||
+ { 0x10000000, 0, 1, TRUE },
|
||||
+ { 0x20000000, 0, 1, TRUE },
|
||||
+ { 0x40000000, 0, 1, TRUE },
|
||||
+ { 0x80000000, 0, 1, TRUE },
|
||||
+
|
||||
+ { 100, 0, 1, TRUE },
|
||||
+ { 100, 0, 5, TRUE },
|
||||
+ { 100, 0, 10, TRUE },
|
||||
+ { 100, 0, 25, TRUE },
|
||||
+ { 100, 0, 50, TRUE },
|
||||
+ { 100, 0, 75, TRUE },
|
||||
+ { 100, 0, 100, TRUE },
|
||||
+ { 100, 0, 150, TRUE },
|
||||
+
|
||||
+ /* test overflow in backward loop */
|
||||
+ { 0, 0, 1, FALSE },
|
||||
+ { 0, 1, 1, FALSE },
|
||||
+ { 0, 2, 1, FALSE },
|
||||
+ { 0, 3, 1, FALSE },
|
||||
+ { 0, 0x10000000, 1, FALSE },
|
||||
+ { 0, 0x20000000, 1, FALSE },
|
||||
+ { 0, 0x40000000, 1, FALSE },
|
||||
+ { 0, 0x80000000, 1, FALSE },
|
||||
+
|
||||
+ { 0, 100, 1, FALSE },
|
||||
+ { 0, 100, 5, FALSE },
|
||||
+ { 0, 100, 10, FALSE },
|
||||
+ { 0, 100, 25, FALSE },
|
||||
+ { 0, 100, 50, FALSE },
|
||||
+ { 0, 100, 75, FALSE },
|
||||
+ { 0, 100, 100, FALSE },
|
||||
+ { 0, 100, 150, FALSE },
|
||||
+ };
|
||||
+ unsigned int begin, end, expected_begin, expected_end;
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||
+ {
|
||||
+ unsigned int iterations, per_thread, remaining;
|
||||
+ DWORD64 first = tests[i].first;
|
||||
+ DWORD64 last = tests[i].last;
|
||||
+ int step = tests[i].step;
|
||||
+
|
||||
+ if (num_threads == 1)
|
||||
+ {
|
||||
+ expected_begin = first;
|
||||
+ expected_end = last;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (tests[i].forward)
|
||||
+ {
|
||||
+ if (tests[i].step <= 0)
|
||||
+ {
|
||||
+ expected_begin = 0;
|
||||
+ expected_end = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (last < first)
|
||||
+ last += 0x100000000;
|
||||
+
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ per_thread++;
|
||||
+ else if (per_thread)
|
||||
+ first += remaining * step;
|
||||
+ else
|
||||
+ {
|
||||
+ expected_begin = first;
|
||||
+ expected_end = first - step;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ expected_begin = first + per_thread * thread_num * step;
|
||||
+ expected_end = expected_begin + (per_thread - 1) * step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (tests[i].step <= 0)
|
||||
+ {
|
||||
+ expected_begin = 0;
|
||||
+ expected_end = 1;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (first < last)
|
||||
+ first += 0x100000000;
|
||||
+
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ per_thread++;
|
||||
+ else if (per_thread)
|
||||
+ first -= remaining * step;
|
||||
+ else
|
||||
+ {
|
||||
+ expected_begin = first;
|
||||
+ expected_end = first + step;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ expected_begin = first - per_thread * thread_num * step;
|
||||
+ expected_end = expected_begin - (per_thread - 1) * step;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ begin = end = 0xdeadbeef;
|
||||
+ p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step,
|
||||
+ tests[i].forward, &begin, &end);
|
||||
+
|
||||
+ ok(begin == expected_begin, "%d:%d/%d: expected begin = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, expected_begin, end);
|
||||
+ ok(end == expected_end, "%d:%d/%d: expected end = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, expected_end, end);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_static_simple_init(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ trace("Running tests with %d threads\n", i);
|
||||
+ pomp_set_num_threads(i);
|
||||
+ p_vcomp_fork(TRUE, 0, _test_vcomp_for_static_simple_init);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -401,6 +620,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
test_vcomp_sections_init();
|
||||
+ test_vcomp_for_static_simple_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,244 @@
|
||||
From 8f71eb6dce0bf634c75a5dc7a5137f45594a530a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Jul 2015 23:39:01 +0200
|
||||
Subject: vcomp: Implement omp_in_parallel and add tests.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 6 +++++
|
||||
dlls/vcomp/tests/vcomp.c | 59 ++++++++++++++++++++++++++++++++++-----------
|
||||
dlls/vcomp/vcomp.spec | 2 +-
|
||||
dlls/vcomp100/vcomp100.spec | 2 +-
|
||||
dlls/vcomp90/vcomp90.spec | 2 +-
|
||||
5 files changed, 54 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 8526d86..a17407c 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -363,6 +363,12 @@ int CDECL _vcomp_sections_next(void)
|
||||
return i;
|
||||
}
|
||||
|
||||
+BOOL CDECL omp_in_parallel(void)
|
||||
+{
|
||||
+ TRACE("()\n");
|
||||
+ return vcomp_init_thread_data()->parallel;
|
||||
+}
|
||||
+
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 4dae41f..6b22d48 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -40,6 +40,7 @@ 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 BOOL (CDECL *pomp_in_parallel)(void);
|
||||
static void (CDECL *pomp_set_nested)(int nested);
|
||||
static void (CDECL *pomp_set_num_threads)(int num_threads);
|
||||
|
||||
@@ -178,6 +179,7 @@ static BOOL init_vcomp(void)
|
||||
VCOMP_GET_PROC(omp_get_nested);
|
||||
VCOMP_GET_PROC(omp_get_num_threads);
|
||||
VCOMP_GET_PROC(omp_get_thread_num);
|
||||
+ VCOMP_GET_PROC(omp_in_parallel);
|
||||
VCOMP_GET_PROC(omp_set_nested);
|
||||
VCOMP_GET_PROC(omp_set_num_threads);
|
||||
|
||||
@@ -186,15 +188,19 @@ static BOOL init_vcomp(void)
|
||||
|
||||
#undef VCOMP_GET_PROC
|
||||
|
||||
-static void CDECL num_threads_cb2(LONG *count)
|
||||
+static void CDECL num_threads_cb2(BOOL parallel, LONG *count)
|
||||
{
|
||||
+ BOOL is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == parallel, "expected %u, got %u\n", parallel, is_parallel);
|
||||
+
|
||||
InterlockedIncrement(count);
|
||||
}
|
||||
|
||||
-static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count)
|
||||
+static void CDECL num_threads_cb(BOOL nested, BOOL parallel, int nested_threads, LONG *count)
|
||||
{
|
||||
int num_threads, thread_num;
|
||||
LONG thread_count;
|
||||
+ BOOL is_parallel;
|
||||
|
||||
InterlockedIncrement(count);
|
||||
p_vcomp_barrier();
|
||||
@@ -205,30 +211,43 @@ static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count)
|
||||
ok(thread_num >= 0 && thread_num < num_threads,
|
||||
"expected thread_num in range [0, %d], got %d\n", num_threads - 1, thread_num);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == parallel, "expected %u, got %u\n", parallel, is_parallel);
|
||||
+
|
||||
thread_count = 0;
|
||||
- p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
|
||||
+ p_vcomp_fork(TRUE, 2, num_threads_cb2, TRUE, &thread_count);
|
||||
if (nested)
|
||||
ok(thread_count == nested_threads, "expected %d threads, got %d\n", nested_threads, thread_count);
|
||||
else
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == parallel, "expected %u, got %u\n", parallel, is_parallel);
|
||||
+
|
||||
thread_count = 0;
|
||||
- p_vcomp_fork(FALSE, 1, num_threads_cb2, &thread_count);
|
||||
+ p_vcomp_fork(FALSE, 2, num_threads_cb2, parallel, &thread_count);
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == parallel, "expected %u, got %u\n", parallel, is_parallel);
|
||||
+
|
||||
p_vcomp_set_num_threads(4);
|
||||
thread_count = 0;
|
||||
- p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
|
||||
+ p_vcomp_fork(TRUE, 2, num_threads_cb2, TRUE, &thread_count);
|
||||
if (nested)
|
||||
ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
else
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
+
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == parallel, "expected %u, got %u\n", parallel, is_parallel);
|
||||
}
|
||||
|
||||
static void test_omp_get_num_threads(BOOL nested)
|
||||
{
|
||||
int is_nested, max_threads, num_threads, thread_num;
|
||||
LONG thread_count;
|
||||
+ BOOL is_parallel;
|
||||
|
||||
pomp_set_nested(nested);
|
||||
is_nested = pomp_get_nested();
|
||||
@@ -239,61 +258,73 @@ static void test_omp_get_num_threads(BOOL nested)
|
||||
thread_num = pomp_get_thread_num();
|
||||
ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == FALSE, "expected FALSE, got %u\n", is_parallel);
|
||||
+
|
||||
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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, max_threads, &thread_count);
|
||||
ok(thread_count == max_threads, "expected %d threads, got %d\n", max_threads, thread_count);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == FALSE, "expected FALSE, got %u\n", is_parallel);
|
||||
+
|
||||
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(FALSE, 3, num_threads_cb, TRUE, max_threads, &thread_count);
|
||||
+ p_vcomp_fork(FALSE, 4, num_threads_cb, TRUE, FALSE, max_threads, &thread_count);
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == FALSE, "expected FALSE, got %u\n", is_parallel);
|
||||
+
|
||||
pomp_set_num_threads(1);
|
||||
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, 1, &thread_count);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 1, &thread_count);
|
||||
ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
|
||||
|
||||
+ is_parallel = pomp_in_parallel();
|
||||
+ ok(is_parallel == FALSE, "expected FALSE, got %u\n", is_parallel);
|
||||
+
|
||||
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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 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);
|
||||
+ p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
|
||||
ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
|
||||
|
||||
pomp_set_num_threads(max_threads);
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index dfbd184..5a5b114 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -98,7 +98,7 @@
|
||||
@ cdecl omp_get_thread_num()
|
||||
@ stub omp_get_wtick
|
||||
@ cdecl omp_get_wtime()
|
||||
-@ stub omp_in_parallel
|
||||
+@ cdecl omp_in_parallel()
|
||||
@ stub omp_init_lock
|
||||
@ stub omp_init_nest_lock
|
||||
@ cdecl omp_set_dynamic(long)
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index 6eb6ae5..debc5ff 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 6eb6ae5..debc5ff 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -98,7 +98,7 @@
|
||||
@ cdecl omp_get_thread_num() vcomp.omp_get_thread_num
|
||||
@ stub omp_get_wtick
|
||||
@ cdecl omp_get_wtime() vcomp.omp_get_wtime
|
||||
-@ stub omp_in_parallel
|
||||
+@ cdecl omp_in_parallel() vcomp.omp_in_parallel
|
||||
@ stub omp_init_lock
|
||||
@ stub omp_init_nest_lock
|
||||
@ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,36 +1,34 @@
|
||||
From 3ebb9a8afbb3592c6988eb4b6cc2f0872fef45fb Mon Sep 17 00:00:00 2001
|
||||
From a2e77ca2e3e956aaabaa5190a0e8cc822349f1a8 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
|
||||
_vcomp_for_static_end.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 90 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 4 +-
|
||||
dlls/vcomp100/vcomp100.spec | 4 +-
|
||||
dlls/vcomp90/vcomp90.spec | 4 +-
|
||||
4 files changed, 96 insertions(+), 6 deletions(-)
|
||||
dlls/vcomp/main.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 4 ++--
|
||||
dlls/vcomp100/vcomp100.spec | 4 ++--
|
||||
dlls/vcomp90/vcomp90.spec | 4 ++--
|
||||
4 files changed, 63 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 0f8a272..7000e1b 100644
|
||||
index a17407c..b647bb1 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -345,6 +345,96 @@ int CDECL _vcomp_sections_next(void)
|
||||
@@ -363,6 +363,63 @@ int CDECL _vcomp_sections_next(void)
|
||||
return i;
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step, BOOL forward,
|
||||
+ unsigned int *begin, unsigned int *end)
|
||||
+void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step,
|
||||
+ BOOL increment, unsigned int *begin, unsigned int *end)
|
||||
+{
|
||||
+ unsigned int iterations, per_thread, remaining;
|
||||
+ 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;
|
||||
+ int num_threads = team_data ? team_data->num_threads : 1;
|
||||
+ int thread_num = thread_data->thread_num;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %p, %p)\n", first, last, step, forward, begin, end);
|
||||
+
|
||||
+ num_threads = team_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+ TRACE("(%u, %u, %d, %u, %p, %p)\n", first, last, step, increment, begin, end);
|
||||
+
|
||||
+ if (num_threads == 1)
|
||||
+ {
|
||||
@ -42,78 +40,47 @@ index 0f8a272..7000e1b 100644
|
||||
+ if (step <= 0)
|
||||
+ {
|
||||
+ *begin = 0;
|
||||
+ *end = forward ? -1 : 1;
|
||||
+ *end = increment ? -1 : 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (forward)
|
||||
+ {
|
||||
+ DWORD64 last64 = last;
|
||||
+ if (last64 < first)
|
||||
+ last64 += 0x100000000;
|
||||
+
|
||||
+ iterations = 1 + (last64 - first) / step;
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ {
|
||||
+ per_thread++;
|
||||
+ }
|
||||
+ else if (per_thread)
|
||||
+ {
|
||||
+ first += remaining * step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = first;
|
||||
+ *end = first - step;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *begin = first + per_thread * thread_num * step;
|
||||
+ *end = *begin + (per_thread - 1) * step;
|
||||
+ }
|
||||
+ if (increment)
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ else
|
||||
+ {
|
||||
+ DWORD first64 = first;
|
||||
+ if (first64 < last)
|
||||
+ first64 += 0x100000000;
|
||||
+
|
||||
+ iterations = 1 + (first64 - last) / step;
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ {
|
||||
+ per_thread++;
|
||||
+ }
|
||||
+ else if (per_thread)
|
||||
+ {
|
||||
+ first64 -= remaining * step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = first64;
|
||||
+ *end = first64 + step;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *begin = first64 - per_thread * thread_num * step;
|
||||
+ *end = *begin - (per_thread - 1) * step;
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ step *= -1;
|
||||
+ }
|
||||
+
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ per_thread++;
|
||||
+ else if (per_thread)
|
||||
+ first += remaining * step;
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = first;
|
||||
+ *end = first - step;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *begin = first + per_thread * thread_num * step;
|
||||
+ *end = *begin + (per_thread - 1) * step;
|
||||
+}
|
||||
+
|
||||
+void CDECL _vcomp_for_static_end(void)
|
||||
+{
|
||||
+ TRACE("()\n");
|
||||
+ /* nothing to do here */
|
||||
+}
|
||||
+
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
BOOL CDECL omp_in_parallel(void)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
TRACE("()\n");
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index dfbd184..51dc13c 100644
|
||||
index 5a5b114..d6b8bf5 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -59,10 +59,10 @@
|
||||
@ -130,7 +97,7 @@ index dfbd184..51dc13c 100644
|
||||
@ varargs _vcomp_fork(long long ptr)
|
||||
@ stub _vcomp_get_thread_num
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index 6eb6ae5..c2c644a 100644
|
||||
index debc5ff..a6933c8 100644
|
||||
--- a/dlls/vcomp100/vcomp100.spec
|
||||
+++ b/dlls/vcomp100/vcomp100.spec
|
||||
@@ -59,10 +59,10 @@
|
||||
@ -147,7 +114,7 @@ index 6eb6ae5..c2c644a 100644
|
||||
@ 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 6eb6ae5..c2c644a 100644
|
||||
index debc5ff..a6933c8 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -59,10 +59,10 @@
|
@ -1,243 +0,0 @@
|
||||
From 9d2c0d36fecd34e7b111fa342aa73315bc26342a 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.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 199 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index bba1fe3..8de4510b 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -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,
|
||||
+ int *begin, int *end, int *next, int *lastchunk);
|
||||
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
BOOL forward, unsigned int *begin, unsigned int *end);
|
||||
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
@@ -174,6 +176,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(_vcomp_sections_init);
|
||||
@@ -611,6 +614,201 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void CDECL _test_vcomp_for_static_init(void)
|
||||
+{
|
||||
+ static const struct
|
||||
+ {
|
||||
+ int first;
|
||||
+ int last;
|
||||
+ int step;
|
||||
+ int chunksize;
|
||||
+ }
|
||||
+ tests[] =
|
||||
+ {
|
||||
+ /* loop forward, step 1 */
|
||||
+ { 0, 0, 1, 1 },
|
||||
+ { 0, 1, 1, 1 },
|
||||
+ { 0, 2, 1, 1 },
|
||||
+ { 0, 3, 1, 1 },
|
||||
+ { 0, 0x10000000, 1, 1 },
|
||||
+ { 0, 0x20000000, 1, 1 },
|
||||
+ { 0, 0x40000000, 1, 1 },
|
||||
+ { 0, (int)0x80000000, 1, 1 },
|
||||
+
|
||||
+ /* loop forward, varying step */
|
||||
+ {0, 100, 1, 1},
|
||||
+ {0, 100, 5, 1},
|
||||
+ {0, 100, 10, 1},
|
||||
+ {0, 100, 25, 1},
|
||||
+ {0, 100, 50, 1},
|
||||
+ {0, 100, 75, 1},
|
||||
+ {0, 100, 100, 1},
|
||||
+ {0, 100, 150, 1},
|
||||
+
|
||||
+ /* empty loop forward, varying step */
|
||||
+ { 50, 50, 3, 1 },
|
||||
+ { 50, 50, 2, 1 },
|
||||
+ { 50, 50, 1, 1 },
|
||||
+ /*{ 50, 50, 0, 1 }, - generates a division by zero exception */
|
||||
+ { 50, 50, -1, 1 },
|
||||
+ { 50, 50, -2, 1 },
|
||||
+ { 50, 50, -3, 1 },
|
||||
+
|
||||
+ /* loop backwards, step 1 */
|
||||
+ { 0, 0, 1, 1 },
|
||||
+ { 1, 0, 1, 1 },
|
||||
+ { 2, 0, 1, 1 },
|
||||
+ { 3, 0, 1, 1 },
|
||||
+ { 0x10000000, 0, 1, 1 },
|
||||
+ { 0x20000000, 0, 1, 1 },
|
||||
+ { 0x40000000, 0, 1, 1 },
|
||||
+ { (int)0x80000000, 0, 1, 1 },
|
||||
+
|
||||
+ /* loop backwards, varying step */
|
||||
+ {100, 0, 1, 1},
|
||||
+ {100, 0, 5, 1},
|
||||
+ {100, 0, 10, 1},
|
||||
+ {100, 0, 25, 1},
|
||||
+ {100, 0, 50, 1},
|
||||
+ {100, 0, 75, 1},
|
||||
+ {100, 0, 100, 1},
|
||||
+ {100, 0, 150, 1},
|
||||
+
|
||||
+ /* loop forward, varying chunksize */
|
||||
+ {0, 100, 1, 1},
|
||||
+ {0, 100, 1, 5},
|
||||
+ {0, 100, 1, 10},
|
||||
+ {0, 100, 1, 25},
|
||||
+ {0, 100, 1, 50},
|
||||
+ {0, 100, 1, 75},
|
||||
+ {0, 100, 1, 100},
|
||||
+ {0, 100, 1, 150},
|
||||
+
|
||||
+ {0, 100, 7, 1},
|
||||
+ {0, 100, 7, 5},
|
||||
+ {0, 100, 7, 10},
|
||||
+ {0, 100, 7, 25},
|
||||
+ {0, 100, 7, 50},
|
||||
+ {0, 100, 7, 75},
|
||||
+ {0, 100, 7, 100},
|
||||
+ {0, 100, 7, 150},
|
||||
+
|
||||
+ /* loop backwards, varying chunksize */
|
||||
+ {100, 0, 1, 1},
|
||||
+ {100, 0, 1, 5},
|
||||
+ {100, 0, 1, 10},
|
||||
+ {100, 0, 1, 25},
|
||||
+ {100, 0, 1, 50},
|
||||
+ {100, 0, 1, 75},
|
||||
+ {100, 0, 1, 100},
|
||||
+ {100, 0, 1, 150},
|
||||
+
|
||||
+ {100, 0, 7, 1},
|
||||
+ {100, 0, 7, 5},
|
||||
+ {100, 0, 7, 10},
|
||||
+ {100, 0, 7, 25},
|
||||
+ {100, 0, 7, 50},
|
||||
+ {100, 0, 7, 75},
|
||||
+ {100, 0, 7, 100},
|
||||
+ {100, 0, 7, 150},
|
||||
+
|
||||
+ };
|
||||
+ int begin, end, expected_begin, expected_end;
|
||||
+ unsigned int loops, expected_loops;
|
||||
+ int lastchunk, expected_lastchunk;
|
||||
+ int chunksize, expected_chunksize;
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||
+ {
|
||||
+ unsigned int iterations, num_chunks, per_thread, remaining;
|
||||
+ int first = tests[i].first;
|
||||
+ int last = tests[i].last;
|
||||
+ int step = tests[i].step;
|
||||
+ chunksize = tests[i].chunksize;
|
||||
+
|
||||
+ if (chunksize < 1)
|
||||
+ chunksize = 1;
|
||||
+
|
||||
+ if (num_threads == 1 && chunksize > 1)
|
||||
+ {
|
||||
+ expected_loops = 1;
|
||||
+ expected_begin = first;
|
||||
+ expected_end = last;
|
||||
+ expected_chunksize = chunksize;
|
||||
+ expected_lastchunk = first;
|
||||
+ }
|
||||
+ else if (last > first)
|
||||
+ {
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ num_chunks = (iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+
|
||||
+ expected_loops = per_thread + (thread_num < remaining);
|
||||
+ expected_begin = first + thread_num * chunksize * step;
|
||||
+ expected_end = expected_begin + (chunksize - 1) * step;
|
||||
+ expected_chunksize = chunksize * num_threads * step;
|
||||
+ expected_lastchunk = first + (num_chunks - 1) * chunksize * step;
|
||||
+
|
||||
+ }
|
||||
+ else if (last < first)
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ num_chunks = (iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+
|
||||
+ expected_loops = per_thread + (thread_num < remaining);
|
||||
+ expected_begin = first - thread_num * chunksize * step;
|
||||
+ expected_end = expected_begin - (chunksize - 1) * step;
|
||||
+ expected_chunksize = - chunksize * num_threads * step;
|
||||
+ expected_lastchunk = first - (num_chunks - 1) * chunksize * step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ expected_loops = (thread_num == 0);
|
||||
+ expected_begin = first;
|
||||
+ expected_end = last;
|
||||
+ expected_chunksize = 0;
|
||||
+ expected_lastchunk = first;
|
||||
+ }
|
||||
+
|
||||
+ loops = begin = end = chunksize = lastchunk = 0xdeadbeef;
|
||||
+ p_vcomp_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
|
||||
+ &loops, &begin, &end, &chunksize, &lastchunk);
|
||||
+
|
||||
+ ok(loops == expected_loops, "%d:%d/%d: expected loops = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, expected_loops, loops);
|
||||
+ ok(begin == expected_begin || broken(begin == 0xdeadbeef && first == last && thread_num > 0),
|
||||
+ "%d:%d/%d: expected begin = %u, got %u\n", i, thread_num, num_threads, expected_begin, end);
|
||||
+ ok(end == expected_end || broken(end == 0xdeadbeef && first == last && thread_num > 0),
|
||||
+ "%d:%d/%d: expected end = %u, got %u\n", i, thread_num, num_threads, expected_end, end);
|
||||
+ ok(chunksize == expected_chunksize || broken(chunksize == (int)0xdeadbeef && first == last) ||
|
||||
+ broken(chunksize != expected_chunksize && num_threads == 1),
|
||||
+ "%d:%d/%d: expected chunksize = %u, got %u\n", i, thread_num, num_threads, expected_chunksize, chunksize);
|
||||
+ ok(lastchunk == expected_lastchunk || broken(lastchunk == 0xdeadbeef && first == last && thread_num > 0),
|
||||
+ "%d:%d/%d: expected lastchunk = %u, got %u\n", i, thread_num, num_threads, expected_lastchunk, lastchunk);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_static_init(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ trace("Running tests with %d threads\n", i);
|
||||
+ pomp_set_num_threads(i);
|
||||
+ p_vcomp_fork(TRUE, 0, _test_vcomp_for_static_init);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -621,6 +819,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_fork();
|
||||
test_vcomp_sections_init();
|
||||
test_vcomp_for_static_simple_init();
|
||||
+ test_vcomp_for_static_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,71 +0,0 @@
|
||||
From c9cf03f4ce4830885ee991ea8e8a5807532be6e5 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.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 6 ++++++
|
||||
dlls/vcomp/vcomp.spec | 2 +-
|
||||
dlls/vcomp100/vcomp100.spec | 2 +-
|
||||
dlls/vcomp90/vcomp90.spec | 2 +-
|
||||
4 files changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index f09fdda..af6fe61 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -497,6 +497,12 @@ void CDECL _vcomp_for_static_end(void)
|
||||
TRACE("()\n");
|
||||
}
|
||||
|
||||
+int CDECL omp_in_parallel(void)
|
||||
+{
|
||||
+ TRACE("()\n");
|
||||
+ return vcomp_init_thread_data()->team != NULL;
|
||||
+}
|
||||
+
|
||||
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 718f80e..7083ce4 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -98,7 +98,7 @@
|
||||
@ cdecl omp_get_thread_num()
|
||||
@ stub omp_get_wtick
|
||||
@ cdecl omp_get_wtime()
|
||||
-@ stub omp_in_parallel
|
||||
+@ cdecl omp_in_parallel()
|
||||
@ stub omp_init_lock
|
||||
@ stub omp_init_nest_lock
|
||||
@ cdecl omp_set_dynamic(long)
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index c0b3d98..56c7ae3 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 c0b3d98..56c7ae3 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -98,7 +98,7 @@
|
||||
@ cdecl omp_get_thread_num() vcomp.omp_get_thread_num
|
||||
@ stub omp_get_wtick
|
||||
@ cdecl omp_get_wtime() vcomp.omp_get_wtime
|
||||
-@ stub omp_in_parallel
|
||||
+@ cdecl omp_in_parallel() vcomp.omp_in_parallel
|
||||
@ stub omp_init_lock
|
||||
@ stub omp_init_nest_lock
|
||||
@ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,217 @@
|
||||
From fdcc5db8904f22d5fe4eb8ad393e371dd5026b31 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Jul 2015 04:09:01 +0200
|
||||
Subject: vcomp/tests: Add tests for _vcomp_for_static_simple_init.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 173 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 6b22d48..bab9f41 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
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_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
+ BOOL increment, 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);
|
||||
@@ -171,6 +174,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
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_sections_init);
|
||||
VCOMP_GET_PROC(_vcomp_sections_next);
|
||||
@@ -460,6 +465,173 @@ if (0)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+static void my_for_static_simple_init(unsigned int first, unsigned int last, int step,
|
||||
+ BOOL increment, unsigned int *begin, unsigned int *end)
|
||||
+{
|
||||
+ unsigned int iterations, per_thread, remaining;
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+
|
||||
+ if (num_threads == 1)
|
||||
+ {
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (step <= 0)
|
||||
+ {
|
||||
+ *begin = 0;
|
||||
+ *end = increment ? -1 : 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (increment)
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ else
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ step *= -1;
|
||||
+ }
|
||||
+
|
||||
+ per_thread = iterations / num_threads;
|
||||
+ remaining = iterations - per_thread * num_threads;
|
||||
+
|
||||
+ if (thread_num < remaining)
|
||||
+ per_thread++;
|
||||
+ else if (per_thread)
|
||||
+ first += remaining * step;
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = first;
|
||||
+ *end = first - step;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *begin = first + per_thread * thread_num * step;
|
||||
+ *end = *begin + (per_thread - 1) * step;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void CDECL for_static_simple_cb(void)
|
||||
+{
|
||||
+ static const struct
|
||||
+ {
|
||||
+ unsigned int first;
|
||||
+ unsigned int last;
|
||||
+ int step;
|
||||
+ }
|
||||
+ tests[] =
|
||||
+ {
|
||||
+ { 0, 0, 1 }, /* 0 */
|
||||
+ { 0, 1, 1 },
|
||||
+ { 0, 2, 1 },
|
||||
+ { 0, 3, 1 },
|
||||
+ { 0, 100, 0 },
|
||||
+ { 0, 100, 1 },
|
||||
+ { 0, 100, 2 },
|
||||
+ { 0, 100, 3 },
|
||||
+ { 0, 100, -1 },
|
||||
+ { 0, 100, -2 },
|
||||
+ { 0, 100, -3 }, /* 10 */
|
||||
+ { 0, 100, 10 },
|
||||
+ { 0, 100, 50 },
|
||||
+ { 0, 100, 100 },
|
||||
+ { 0, 100, 150 },
|
||||
+ { 0, 0x80000000, 1 },
|
||||
+ { 0, 0xfffffffe, 1 },
|
||||
+ { 0, 0xffffffff, 1 },
|
||||
+ { 50, 50, 0 },
|
||||
+ { 50, 50, 1 },
|
||||
+ { 50, 50, 2 }, /* 20 */
|
||||
+ { 50, 50, 3 },
|
||||
+ { 50, 50, -1 },
|
||||
+ { 50, 50, -2 },
|
||||
+ { 50, 50, -3 },
|
||||
+ { 100, 200, 1 },
|
||||
+ { 100, 200, 5 },
|
||||
+ { 100, 200, 10 },
|
||||
+ { 100, 200, 50 },
|
||||
+ { 100, 200, 100 },
|
||||
+ { 100, 200, 150 }, /* 30 */
|
||||
+ };
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||
+ {
|
||||
+ unsigned int my_begin, my_end, begin, end;
|
||||
+
|
||||
+ begin = end = 0xdeadbeef;
|
||||
+ my_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, FALSE, &my_begin, &my_end);
|
||||
+ p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, FALSE, &begin, &end);
|
||||
+
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_begin, end);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+
|
||||
+ begin = end = 0xdeadbeef;
|
||||
+ my_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, TRUE, &my_begin, &my_end);
|
||||
+ p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, TRUE, &begin, &end);
|
||||
+
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_begin, end);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+
|
||||
+ if (tests[i].first == tests[i].last) continue;
|
||||
+
|
||||
+ begin = end = 0xdeadbeef;
|
||||
+ my_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, FALSE, &my_begin, &my_end);
|
||||
+ p_vcomp_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, FALSE, &begin, &end);
|
||||
+
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_begin, end);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+
|
||||
+ begin = end = 0xdeadbeef;
|
||||
+ my_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, TRUE, &my_begin, &my_end);
|
||||
+ p_vcomp_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, TRUE, &begin, &end);
|
||||
+
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_begin, end);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end = %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_static_simple_init(void)
|
||||
+{
|
||||
+ int max_threads = pomp_get_max_threads();
|
||||
+ int i;
|
||||
+
|
||||
+ for_static_simple_cb();
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ pomp_set_num_threads(i);
|
||||
+ p_vcomp_fork(TRUE, 0, for_static_simple_cb);
|
||||
+ p_vcomp_fork(FALSE, 0, for_static_simple_cb);
|
||||
+ }
|
||||
+
|
||||
+ pomp_set_num_threads(max_threads);
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -469,6 +641,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
test_vcomp_sections_init();
|
||||
+ test_vcomp_for_static_simple_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,294 +0,0 @@
|
||||
From 2884d2c0e05a7bf26fe340774fd3d6a29a1de416 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
|
||||
and add tests.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/tests/vcomp.c | 53 ++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 4 +-
|
||||
dlls/vcomp100/vcomp100.spec | 4 +-
|
||||
dlls/vcomp90/vcomp90.spec | 4 +-
|
||||
5 files changed, 152 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index af6fe61..9771841 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -61,6 +61,9 @@ struct vcomp_thread_data
|
||||
|
||||
/* section */
|
||||
unsigned int section;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ unsigned int dynamic;
|
||||
};
|
||||
|
||||
struct vcomp_team_data
|
||||
@@ -82,6 +85,15 @@ struct vcomp_team_data
|
||||
unsigned int section;
|
||||
int num_sections;
|
||||
int section_index;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ DWORD dynamic;
|
||||
+ DWORD dynamic_forward;
|
||||
+ DWORD dynamic_first;
|
||||
+ DWORD dynamic_iterations;
|
||||
+ int dynamic_step;
|
||||
+ DWORD dynamic_chunksize;
|
||||
+ DWORD dynamic_min_chunksize;
|
||||
};
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -497,6 +509,83 @@ void CDECL _vcomp_for_static_end(void)
|
||||
TRACE("()\n");
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int step, int chunksize)
|
||||
+{
|
||||
+ 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_data->dynamic++;
|
||||
+ if ((int)(thread_data->dynamic - team_data->dynamic) > 0)
|
||||
+ {
|
||||
+ /* first thread in a new for_dynamic */
|
||||
+
|
||||
+ if (forward)
|
||||
+ {
|
||||
+ DWORD64 last64 = last;
|
||||
+ if (last64 < first)
|
||||
+ last64 += 0x100000000;
|
||||
+ iterations = 1 + (last64 - first) / step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ DWORD first64 = first;
|
||||
+ if (first64 < last)
|
||||
+ first64 += 0x100000000;
|
||||
+ iterations = 1 + (first64 - last) / step;
|
||||
+ }
|
||||
+
|
||||
+ team_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_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_data->dynamic == team_data->dynamic &&
|
||||
+ team_data->dynamic_iterations != 0)
|
||||
+ {
|
||||
+ iterations = min(team_data->dynamic_iterations, team_data->dynamic_chunksize);
|
||||
+ team_data->dynamic_iterations -= iterations;
|
||||
+
|
||||
+ if (team_data->dynamic_forward)
|
||||
+ {
|
||||
+ *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_data->dynamic_first;
|
||||
+ *end = team_data->dynamic_first - (iterations - 1) * team_data->dynamic_step;
|
||||
+ team_data->dynamic_first -= iterations * team_data->dynamic_step;
|
||||
+ }
|
||||
+
|
||||
+ team_data->dynamic_chunksize =
|
||||
+ max((team_data->dynamic_chunksize * 3 + 2)/4, team_data->dynamic_min_chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ return (iterations != 0);
|
||||
+}
|
||||
+
|
||||
int CDECL omp_in_parallel(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
@@ -571,11 +660,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;
|
||||
|
||||
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);
|
||||
|
||||
@@ -592,6 +683,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);
|
||||
@@ -611,6 +703,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);
|
||||
|
||||
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 8de4510b..3992bda 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -32,6 +32,8 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
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);
|
||||
@@ -175,6 +177,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_dynamic_init);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_dynamic_next);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
@@ -809,6 +813,54 @@ static void test_vcomp_for_static_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void CDECL _test_vcomp_for_dynamic_init(LONG *a, LONG *b, LONG *c)
|
||||
+{
|
||||
+ int begin, end;
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0x40, 1, 100000, 1, 30);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ InterlockedExchangeAdd(a, end - begin + 1);
|
||||
+ Sleep(50);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0, 1337, 1, 1, 50);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ InterlockedExchangeAdd(b, begin - end + 1);
|
||||
+ Sleep(50);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0x40, 1, 100000, 7, 30);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ while (begin <= end)
|
||||
+ {
|
||||
+ InterlockedIncrement(c);
|
||||
+ begin += 7;
|
||||
+ }
|
||||
+ Sleep(50);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_dynamic_init(void)
|
||||
+{
|
||||
+ LONG a, b, c;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ trace("Running tests with %d threads\n", i);
|
||||
+ pomp_set_num_threads(i);
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, _test_vcomp_for_dynamic_init, &a, &b, &c);
|
||||
+ ok(a == 100000, "expected a = 100000, got %d\n", a);
|
||||
+ ok(b == 1337, "expected b = 1337, got %d\n", b);
|
||||
+ ok(c == 14286, "expected c = 14286, got %d\n", c);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -820,6 +872,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_sections_init();
|
||||
test_vcomp_for_static_simple_init();
|
||||
test_vcomp_for_static_init();
|
||||
+ test_vcomp_for_dynamic_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 7083ce4..1b02a65 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long)
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr)
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end()
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index 56c7ae3..ab93ec2 100644
|
||||
--- a/dlls/vcomp100/vcomp100.spec
|
||||
+++ b/dlls/vcomp100/vcomp100.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
|
||||
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
|
||||
index 56c7ae3..ab93ec2 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,90 +1,91 @@
|
||||
From bbced4bb965ecd2f773783ffb19f76b6e908f109 Mon Sep 17 00:00:00 2001
|
||||
From bf7251bea46154f6ef2f61182b87d8e19964f4e8 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 19:19:00 +0200
|
||||
Date: Sat, 18 Jul 2015 20:38:36 +0200
|
||||
Subject: vcomp: Implement _vcomp_for_static_init.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/main.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 2 +-
|
||||
dlls/vcomp100/vcomp100.spec | 2 +-
|
||||
dlls/vcomp90/vcomp90.spec | 2 +-
|
||||
4 files changed, 65 insertions(+), 3 deletions(-)
|
||||
4 files changed, 66 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 7000e1b..f09fdda 100644
|
||||
index b647bb1..0148c8b 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -430,6 +430,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
}
|
||||
@@ -414,6 +414,69 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
*end = *begin + (per_thread - 1) * step;
|
||||
}
|
||||
|
||||
+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_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;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ int num_threads = team_data ? team_data->num_threads : 1;
|
||||
+ int thread_num = thread_data->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_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+ if (num_threads == 1 && chunksize != 1)
|
||||
+ {
|
||||
+ *loops = 1;
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = 0;
|
||||
+ *lastchunk = first;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (first == last)
|
||||
+ {
|
||||
+ *loops = !thread_num;
|
||||
+ if (!thread_num)
|
||||
+ {
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = 0;
|
||||
+ *lastchunk = first;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (step <= 0)
|
||||
+ {
|
||||
+ *loops = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (first < last)
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ else
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ step *= -1;
|
||||
+ }
|
||||
+
|
||||
+ if (chunksize < 1)
|
||||
+ chunksize = 1;
|
||||
+
|
||||
+ if (num_threads == 1 && chunksize > 1)
|
||||
+ {
|
||||
+ *loops = 1;
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = chunksize;
|
||||
+ *lastchunk = first;
|
||||
+ }
|
||||
+ else if (last > first)
|
||||
+ {
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ num_chunks = (iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+ num_chunks = ((DWORD64)iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+
|
||||
+ *loops = per_thread + (thread_num < remaining);
|
||||
+ *begin = first + thread_num * chunksize * step;
|
||||
+ *end = *begin + (chunksize - 1) * step;
|
||||
+ *next = chunksize * num_threads * step;
|
||||
+ *lastchunk = first + (num_chunks - 1) * chunksize * step;
|
||||
+
|
||||
+ }
|
||||
+ else if (last < first)
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ num_chunks = (iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+
|
||||
+ *loops = per_thread + (thread_num < remaining);
|
||||
+ *begin = first - thread_num * chunksize * step;
|
||||
+ *end = *begin - (chunksize - 1) * step;
|
||||
+ *next = - chunksize * num_threads * step;
|
||||
+ *lastchunk = first - (num_chunks - 1) * chunksize * step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *loops = (thread_num == 0);
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = 0;
|
||||
+ *lastchunk = first;
|
||||
+ }
|
||||
+ *loops = per_thread + (thread_num < remaining);
|
||||
+ *begin = first + thread_num * chunksize * step;
|
||||
+ *end = *begin + (chunksize - 1) * step;
|
||||
+ *next = chunksize * num_threads * step;
|
||||
+ *lastchunk = first + (num_chunks - 1) * chunksize * step;
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_for_static_end(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 51dc13c..718f80e 100644
|
||||
index d6b8bf5..7083ce4 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -60,7 +60,7 @@
|
||||
@ -97,7 +98,7 @@ index 51dc13c..718f80e 100644
|
||||
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
|
||||
@ stub _vcomp_for_static_simple_init_i8
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index c2c644a..c0b3d98 100644
|
||||
index a6933c8..56c7ae3 100644
|
||||
--- a/dlls/vcomp100/vcomp100.spec
|
||||
+++ b/dlls/vcomp100/vcomp100.spec
|
||||
@@ -60,7 +60,7 @@
|
||||
@ -110,7 +111,7 @@ index c2c644a..c0b3d98 100644
|
||||
@ 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 c2c644a..c0b3d98 100644
|
||||
index a6933c8..56c7ae3 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -60,7 +60,7 @@
|
@ -0,0 +1,287 @@
|
||||
From b330549979468af9a322b980f0c2cb73031a5b3b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Jul 2015 20:38:54 +0200
|
||||
Subject: vcomp/tests: Add tests for _vcomp_for_static_init.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 243 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 243 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index bab9f41..205899d 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -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,
|
||||
+ int *begin, int *end, int *next, int *lastchunk);
|
||||
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
|
||||
BOOL increment, unsigned int *begin, unsigned int *end);
|
||||
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
@@ -175,6 +177,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(_vcomp_sections_init);
|
||||
@@ -632,6 +635,245 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+#define VCOMP_FOR_STATIC_BROKEN_LOOP 1
|
||||
+#define VCOMP_FOR_STATIC_BROKEN_NEXT 2
|
||||
+
|
||||
+DWORD CDECL my_for_static_init(int first, int last, int step, int chunksize, unsigned int *loops,
|
||||
+ int *begin, int *end, int *next, int *lastchunk)
|
||||
+{
|
||||
+ unsigned int iterations, num_chunks, per_thread, remaining;
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+
|
||||
+ if (num_threads == 1 && chunksize != 1)
|
||||
+ {
|
||||
+ *loops = 1;
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = 0;
|
||||
+ *lastchunk = first;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (first == last)
|
||||
+ {
|
||||
+ *loops = !thread_num;
|
||||
+ if (!thread_num)
|
||||
+ {
|
||||
+ /* The value in *next on Windows is either uninitialized, or contains
|
||||
+ * garbage. The value shouldn't matter for *loops <= 1, so no need to
|
||||
+ * reproduce that. */
|
||||
+ *begin = first;
|
||||
+ *end = last;
|
||||
+ *next = 0;
|
||||
+ *lastchunk = first;
|
||||
+ }
|
||||
+ return thread_num ? 0 : VCOMP_FOR_STATIC_BROKEN_NEXT;
|
||||
+ }
|
||||
+
|
||||
+ if (step <= 0)
|
||||
+ {
|
||||
+ /* The total number of iterations depends on the number of threads here,
|
||||
+ * which doesn't make any sense. This is most likely a bug in the Windows
|
||||
+ * implementation. */
|
||||
+ return VCOMP_FOR_STATIC_BROKEN_LOOP;
|
||||
+ }
|
||||
+
|
||||
+ if (first < last)
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ else
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ step *= -1;
|
||||
+ }
|
||||
+
|
||||
+ if (chunksize < 1)
|
||||
+ chunksize = 1;
|
||||
+
|
||||
+ num_chunks = ((DWORD64)iterations + chunksize - 1) / chunksize;
|
||||
+ per_thread = num_chunks / num_threads;
|
||||
+ remaining = num_chunks - per_thread * num_threads;
|
||||
+
|
||||
+ *loops = per_thread + (thread_num < remaining);
|
||||
+ *begin = first + thread_num * chunksize * step;
|
||||
+ *end = *begin + (chunksize - 1) * step;
|
||||
+ *next = chunksize * num_threads * step;
|
||||
+ *lastchunk = first + (num_chunks - 1) * chunksize * step;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void CDECL for_static_cb(void)
|
||||
+{
|
||||
+ static const struct
|
||||
+ {
|
||||
+ int first;
|
||||
+ int last;
|
||||
+ int step;
|
||||
+ int chunksize;
|
||||
+ }
|
||||
+ tests[] =
|
||||
+ {
|
||||
+ { 0, 0, 1, 1 },
|
||||
+ { 0, 0, 5, 1 },
|
||||
+ { 0, 1, 1, 1 },
|
||||
+ { 0, 2, 1, 1 },
|
||||
+ { 0, 3, 1, 1 },
|
||||
+ { 0, 100, 1, 1 },
|
||||
+ { 0, 100, 1, 5 },
|
||||
+ { 0, 100, 1, 10 },
|
||||
+ { 0, 100, 1, 50 },
|
||||
+ { 0, 100, 1, 100 },
|
||||
+ { 0, 100, 1, 150 },
|
||||
+ { 0, 100, 5, 1 },
|
||||
+ { 0, 100, 7, 0 },
|
||||
+ { 0, 100, 7, 1 },
|
||||
+ { 0, 100, 7, 5 },
|
||||
+ { 0, 100, 7, 10 },
|
||||
+ { 0, 100, 7, 50 },
|
||||
+ { 0, 100, 7, 100 },
|
||||
+ { 0, 100, 7, 150 },
|
||||
+ { 0, 100, -7, 0 },
|
||||
+ { 0, 100, -7, 1 },
|
||||
+ { 0, 100, -7, 5 },
|
||||
+ { 0, 100, -7, 10 },
|
||||
+ { 0, 100, -7, 50 },
|
||||
+ { 0, 100, -7, 100 },
|
||||
+ { 0, 100, -7, 150 },
|
||||
+ { 0, 100, 10, 1 },
|
||||
+ { 0, 100, 50, 1 },
|
||||
+ { 0, 100, 100, 1 },
|
||||
+ { 0, 100, 150, 1 },
|
||||
+ { 0, 100, -150, -5 },
|
||||
+ { 0, 0x10000000, 1, 1 },
|
||||
+ { 0, 0x10000000, 1, -500 },
|
||||
+ { 0, 0x20000000, 1, 1 },
|
||||
+ { 0, 0x20000000, 1, -500 },
|
||||
+ { 0, 0x20000000, -1, 1 },
|
||||
+ { 0, 0x20000000, -100, 1 },
|
||||
+ { 0, 0x20000000, -0x80000000, 1 },
|
||||
+ { 0, 0x40000000, 1, 1 },
|
||||
+ { 0, 0x40000000, 1, -500 },
|
||||
+ { 0, -0x80000000, 1, 1 },
|
||||
+ { 0, -0x80000000, 1, -500 },
|
||||
+ { 50, 50, 1, 1 },
|
||||
+ { 50, 50, 1, -1 },
|
||||
+ { 50, 50, 2, 1 },
|
||||
+ { 50, 50, 2, -1 },
|
||||
+ { 50, 50, 3, 1 },
|
||||
+ { 50, 50, 3, -1 },
|
||||
+ { 50, 50, -1, 1 },
|
||||
+ { 50, 50, -1, -1 },
|
||||
+ { 50, 50, -2, 1 },
|
||||
+ { 50, 50, -2, -1 },
|
||||
+ { 50, 50, -3, 1 },
|
||||
+ { 50, 50, -3, -1 },
|
||||
+ { 50, 50, -100, 1 },
|
||||
+ { 50, 50, -100, -1 },
|
||||
+ { 100, 200, 13, 1 },
|
||||
+ { 100, 200, 13, 5 },
|
||||
+ { 0x10000000, 0x20000000, -1, 1 },
|
||||
+ { 0x10000000, 0x20000000, -100, 1 },
|
||||
+ { 0x10000000, 0x20000000, -0x80000000, 1 },
|
||||
+ { 0x20000000, 0, 1, 1 },
|
||||
+ { 0x40000000, 0, 1, 1 },
|
||||
+ { 0x7FFFFFFE, -0x80000000, 1, 0x1000 },
|
||||
+ { 0x7FFFFFFF, -0x80000000, 1, 0x1000 },
|
||||
+ { -0x10000000, -0x20000000, -0x80000000, -1 },
|
||||
+ { -0x80000000, 0, 1, 1 },
|
||||
+ };
|
||||
+ int num_threads = pomp_get_num_threads();
|
||||
+ int thread_num = pomp_get_thread_num();
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||
+ {
|
||||
+ int my_begin, my_end, my_next, my_lastchunk;
|
||||
+ int begin, end, next, lastchunk;
|
||||
+ unsigned int my_loops, loops;
|
||||
+ DWORD broken_flags;
|
||||
+
|
||||
+ my_loops = my_begin = my_end = my_next = my_lastchunk = 0xdeadbeef;
|
||||
+ loops = begin = end = next = lastchunk = 0xdeadbeef;
|
||||
+ broken_flags = my_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
|
||||
+ &my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
|
||||
+ p_vcomp_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
|
||||
+ &loops, &begin, &end, &next, &lastchunk);
|
||||
+
|
||||
+ if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
|
||||
+ {
|
||||
+ ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %d\n",
|
||||
+ i, thread_num, num_threads, loops);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_loops, loops);
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_begin, begin);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+ ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
|
||||
+ "test %d, thread %d/%d: expected next == %d, got %d\n", i, thread_num, num_threads, my_next, next);
|
||||
+ ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_lastchunk, lastchunk);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+
|
||||
+ if (tests[i].first == tests[i].last) continue;
|
||||
+
|
||||
+ my_loops = my_begin = my_end = my_next = my_lastchunk = 0xdeadbeef;
|
||||
+ loops = begin = end = next = lastchunk = 0xdeadbeef;
|
||||
+ broken_flags = my_for_static_init(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
|
||||
+ &my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
|
||||
+ p_vcomp_for_static_init(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
|
||||
+ &loops, &begin, &end, &next, &lastchunk);
|
||||
+
|
||||
+ if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
|
||||
+ {
|
||||
+ ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %d\n",
|
||||
+ i, thread_num, num_threads, loops);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_loops, loops);
|
||||
+ ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_begin, begin);
|
||||
+ ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
|
||||
+ i, thread_num, num_threads, my_end, end);
|
||||
+ ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
|
||||
+ "test %d, thread %d/%d: expected next == %d, got %d\n", i, thread_num, num_threads, my_next, next);
|
||||
+ ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %d, got %d\n",
|
||||
+ i, thread_num, num_threads, my_lastchunk, lastchunk);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_static_end();
|
||||
+ p_vcomp_barrier();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#undef VCOMP_FOR_STATIC_BROKEN_LOOP
|
||||
+#undef VCOMP_FOR_STATIC_BROKEN_NEXT
|
||||
+
|
||||
+static void test_vcomp_for_static_init(void)
|
||||
+{
|
||||
+ int max_threads = pomp_get_max_threads();
|
||||
+ int i;
|
||||
+
|
||||
+ for_static_cb();
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ pomp_set_num_threads(i);
|
||||
+ p_vcomp_fork(TRUE, 0, for_static_cb);
|
||||
+ p_vcomp_fork(FALSE, 0, for_static_cb);
|
||||
+ }
|
||||
+
|
||||
+ pomp_set_num_threads(max_threads);
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -642,6 +884,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_fork();
|
||||
test_vcomp_sections_init();
|
||||
test_vcomp_for_static_simple_init();
|
||||
+ test_vcomp_for_static_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,207 @@
|
||||
From 669a548a8daa2c8477a81160cfc473844e0a2e1d Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 19 Jul 2015 01:01:28 +0200
|
||||
Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 4 +--
|
||||
dlls/vcomp100/vcomp100.spec | 4 +--
|
||||
dlls/vcomp90/vcomp90.spec | 4 +--
|
||||
4 files changed, 83 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 0148c8b..c565dc8 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -63,6 +63,9 @@ struct vcomp_thread_data
|
||||
|
||||
/* section */
|
||||
unsigned int section;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ unsigned int dynamic;
|
||||
};
|
||||
|
||||
struct vcomp_team_data
|
||||
@@ -87,6 +90,14 @@ struct vcomp_task_data
|
||||
unsigned int section;
|
||||
int num_sections;
|
||||
int section_index;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ unsigned int dynamic;
|
||||
+ unsigned int dynamic_first;
|
||||
+ unsigned int dynamic_iterations;
|
||||
+ int dynamic_step;
|
||||
+ unsigned int dynamic_chunksize;
|
||||
+ unsigned int dynamic_min_chunksize;
|
||||
};
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -202,6 +213,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||
|
||||
task_data = &((struct vcomp_thread_and_task_data *)thread_data)->task;
|
||||
task_data->section = 0;
|
||||
+ task_data->dynamic = 0;
|
||||
|
||||
thread_data->team = NULL;
|
||||
thread_data->task = task_data;
|
||||
@@ -209,6 +221,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||
thread_data->parallel = FALSE;
|
||||
thread_data->fork_threads = 0;
|
||||
thread_data->section = 1;
|
||||
+ thread_data->dynamic = 1;
|
||||
|
||||
vcomp_set_thread_data(thread_data);
|
||||
return thread_data;
|
||||
@@ -483,6 +496,66 @@ void CDECL _vcomp_for_static_end(void)
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_dynamic_init(unsigned int flags, unsigned int first, unsigned int last,
|
||||
+ int step, unsigned int chunksize)
|
||||
+{
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_task_data *task_data = thread_data->task;
|
||||
+
|
||||
+ TRACE("(%u, %u, %u, %d, %u)\n", flags, first, last, step, chunksize);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ thread_data->dynamic++;
|
||||
+ if ((int)(thread_data->dynamic - task_data->dynamic) > 0)
|
||||
+ {
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ int num_threads = team_data ? team_data->num_threads : 1;
|
||||
+ unsigned int iterations;
|
||||
+
|
||||
+ if (flags & 0x40)
|
||||
+ iterations = 1 + (last - first) / step;
|
||||
+ else
|
||||
+ {
|
||||
+ iterations = 1 + (first - last) / step;
|
||||
+ step *= -1;
|
||||
+ }
|
||||
+
|
||||
+ task_data->dynamic = thread_data->dynamic;
|
||||
+ task_data->dynamic_first = first;
|
||||
+ task_data->dynamic_iterations = iterations;
|
||||
+ task_data->dynamic_step = step;
|
||||
+ task_data->dynamic_chunksize = max(1, iterations / num_threads);
|
||||
+ task_data->dynamic_min_chunksize = max(1, chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+}
|
||||
+
|
||||
+BOOL CDECL _vcomp_for_dynamic_next(unsigned int *begin, unsigned int *end)
|
||||
+{
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_task_data *task_data = thread_data->task;
|
||||
+ unsigned int iterations = 0;
|
||||
+
|
||||
+ TRACE("(%p, %p)\n", begin, end);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ if (thread_data->dynamic == task_data->dynamic &&
|
||||
+ task_data->dynamic_iterations != 0)
|
||||
+ {
|
||||
+ iterations = min(task_data->dynamic_iterations, task_data->dynamic_chunksize);
|
||||
+ *begin = task_data->dynamic_first;
|
||||
+ *end = task_data->dynamic_first + (iterations - 1) * task_data->dynamic_step;
|
||||
+
|
||||
+ task_data->dynamic_iterations -= iterations;
|
||||
+ task_data->dynamic_first += iterations * task_data->dynamic_step;
|
||||
+ task_data->dynamic_chunksize = max((task_data->dynamic_chunksize * 3 + 2)/4,
|
||||
+ task_data->dynamic_min_chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ return (iterations != 0);
|
||||
+}
|
||||
+
|
||||
BOOL CDECL omp_in_parallel(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
@@ -560,6 +633,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_data.barrier_count = 0;
|
||||
|
||||
task_data.section = 0;
|
||||
+ task_data.dynamic = 0;
|
||||
|
||||
thread_data.team = &team_data;
|
||||
thread_data.task = &task_data;
|
||||
@@ -567,6 +641,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
thread_data.parallel = ifval || prev_thread_data->parallel;
|
||||
thread_data.fork_threads = 0;
|
||||
thread_data.section = 1;
|
||||
+ thread_data.dynamic = 1;
|
||||
list_init(&thread_data.entry);
|
||||
InitializeConditionVariable(&thread_data.cond);
|
||||
|
||||
@@ -585,6 +660,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->parallel = thread_data.parallel;
|
||||
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);
|
||||
@@ -606,6 +682,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
data->parallel = thread_data.parallel;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
+ data->dynamic = 1;
|
||||
InitializeConditionVariable(&data->cond);
|
||||
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 7083ce4..1b02a65 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
||||
+++ b/dlls/vcomp/vcomp.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long)
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr)
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end()
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
|
||||
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
|
||||
index 56c7ae3..ab93ec2 100644
|
||||
--- a/dlls/vcomp100/vcomp100.spec
|
||||
+++ b/dlls/vcomp100/vcomp100.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
|
||||
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
|
||||
index 56c7ae3..ab93ec2 100644
|
||||
--- a/dlls/vcomp90/vcomp90.spec
|
||||
+++ b/dlls/vcomp90/vcomp90.spec
|
||||
@@ -55,9 +55,9 @@
|
||||
@ stub _vcomp_copyprivate_receive
|
||||
@ stub _vcomp_enter_critsect
|
||||
@ stub _vcomp_flush
|
||||
-@ stub _vcomp_for_dynamic_init
|
||||
+@ cdecl _vcomp_for_dynamic_init(long long long long long) vcomp._vcomp_for_dynamic_init
|
||||
@ stub _vcomp_for_dynamic_init_i8
|
||||
-@ stub _vcomp_for_dynamic_next
|
||||
+@ cdecl _vcomp_for_dynamic_next(ptr ptr) vcomp._vcomp_for_dynamic_next
|
||||
@ stub _vcomp_for_dynamic_next_i8
|
||||
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end
|
||||
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,112 @@
|
||||
From 23a2077048d54113d81a05a475d63c2df37c2d63 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 19 Jul 2015 01:05:02 +0200
|
||||
Subject: vcomp/tests: Add tests for _vcomp_for_dynamic_init.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 68 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 205899d..c7a0e60 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (CDECL *p_vcomp_for_dynamic_init)(unsigned int flags, unsigned int first, unsigned int last,
|
||||
+ int step, unsigned int chunksize);
|
||||
+static BOOL (CDECL *p_vcomp_for_dynamic_next)(unsigned int *begin, unsigned 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);
|
||||
@@ -176,6 +179,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_dynamic_init);
|
||||
+ VCOMP_GET_PROC(_vcomp_for_dynamic_next);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
@@ -874,6 +879,68 @@ static void test_vcomp_for_static_init(void)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+static void CDECL for_dynamic_cb(LONG *a, LONG *b, LONG *c)
|
||||
+{
|
||||
+ unsigned int begin, end;
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0x40, 1, 100000, 1, 30);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ InterlockedExchangeAdd(a, end - begin + 1);
|
||||
+ Sleep(1);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0, 1337, 1, 1, 50);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ InterlockedExchangeAdd(b, begin - end + 1);
|
||||
+ Sleep(1);
|
||||
+ }
|
||||
+
|
||||
+ p_vcomp_for_dynamic_init(0x40, 1, 100000, 7, 30);
|
||||
+ while (p_vcomp_for_dynamic_next(&begin, &end))
|
||||
+ {
|
||||
+ while (begin <= end)
|
||||
+ {
|
||||
+ InterlockedIncrement(c);
|
||||
+ begin += 7;
|
||||
+ }
|
||||
+ Sleep(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void test_vcomp_for_dynamic_init(void)
|
||||
+{
|
||||
+ int max_threads = pomp_get_max_threads();
|
||||
+ LONG a, b, c;
|
||||
+ int i;
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ for_dynamic_cb(&a, &b, &c);
|
||||
+ ok(a == 100000, "expected a = 100000, got %d\n", a);
|
||||
+ ok(b == 1337, "expected b = 1337, got %d\n", b);
|
||||
+ ok(c == 14286, "expected c = 14286, got %d\n", c);
|
||||
+
|
||||
+ for (i = 1; i <= 4; i++)
|
||||
+ {
|
||||
+ pomp_set_num_threads(i);
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ p_vcomp_fork(TRUE, 3, for_dynamic_cb, &a, &b, &c);
|
||||
+ ok(a == 100000, "expected a = 100000, got %d\n", a);
|
||||
+ ok(b == 1337, "expected b = 1337, got %d\n", b);
|
||||
+ ok(c == 14286, "expected c = 14286, got %d\n", c);
|
||||
+
|
||||
+ a = b = c = 0;
|
||||
+ p_vcomp_fork(FALSE, 3, for_dynamic_cb, &a, &b, &c);
|
||||
+ ok(a == 100000, "expected a = 100000, got %d\n", a);
|
||||
+ ok(b == 1337, "expected b = 1337, got %d\n", b);
|
||||
+ ok(c == 14286, "expected c = 14286, got %d\n", c);
|
||||
+ }
|
||||
+
|
||||
+ pomp_set_num_threads(max_threads);
|
||||
+}
|
||||
+
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -885,6 +952,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_sections_init();
|
||||
test_vcomp_for_static_simple_init();
|
||||
test_vcomp_for_static_init();
|
||||
+ test_vcomp_for_dynamic_init();
|
||||
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
||||
|
Loading…
x
Reference in New Issue
Block a user