[1/2] vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.
Sebastian Lackner
sebastian at fds-team.de
Thu Aug 6 02:30:57 CDT 2015
---
dlls/vcomp/main.c | 141 ++++++++++++++++++++++++++++++++++++++++++++
dlls/vcomp/vcomp.spec | 4 -
dlls/vcomp100/vcomp100.spec | 4 -
dlls/vcomp110/vcomp110.spec | 4 -
dlls/vcomp90/vcomp90.spec | 4 -
5 files changed, 149 insertions(+), 8 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 301370c..748899d 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -50,6 +50,11 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
};
static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+#define VCOMP_DYNAMIC_FLAGS_STATIC 0x01
+#define VCOMP_DYNAMIC_FLAGS_CHUNKED 0x02
+#define VCOMP_DYNAMIC_FLAGS_GUIDED 0x03
+#define VCOMP_DYNAMIC_FLAGS_INCREMENT 0x40
+
struct vcomp_thread_data
{
struct vcomp_team_data *team;
@@ -64,6 +69,12 @@ struct vcomp_thread_data
/* section */
unsigned int section;
+
+ /* dynamic */
+ unsigned int dynamic;
+ unsigned int dynamic_type;
+ unsigned int dynamic_begin;
+ unsigned int dynamic_end;
};
struct vcomp_team_data
@@ -88,6 +99,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_last;
+ unsigned int dynamic_iterations;
+ int dynamic_step;
+ unsigned int dynamic_chunksize;
};
#if defined(__i386__)
@@ -200,6 +219,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
}
data->task.section = 0;
+ data->task.dynamic = 0;
thread_data = &data->thread;
thread_data->team = NULL;
@@ -208,6 +228,8 @@ 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;
+ thread_data->dynamic_type = 0;
vcomp_set_thread_data(thread_data);
return thread_data;
@@ -634,6 +656,121 @@ 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)
+{
+ 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;
+ struct vcomp_task_data *task_data = thread_data->task;
+ int num_threads = team_data ? team_data->num_threads : 1;
+ int thread_num = thread_data->thread_num;
+ unsigned int type = flags & ~VCOMP_DYNAMIC_FLAGS_INCREMENT;
+
+ TRACE("(%u, %u, %u, %d, %u)\n", flags, first, last, step, chunksize);
+
+ if (step <= 0)
+ {
+ thread_data->dynamic_type = 0;
+ return;
+ }
+
+ if (flags & VCOMP_DYNAMIC_FLAGS_INCREMENT)
+ iterations = 1 + (last - first) / step;
+ else
+ {
+ iterations = 1 + (first - last) / step;
+ step *= -1;
+ }
+
+ if (type == VCOMP_DYNAMIC_FLAGS_STATIC)
+ {
+ 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
+ {
+ thread_data->dynamic_type = 0;
+ return;
+ }
+
+ thread_data->dynamic_type = VCOMP_DYNAMIC_FLAGS_STATIC;
+ thread_data->dynamic_begin = first + per_thread * thread_num * step;
+ thread_data->dynamic_end = thread_data->dynamic_begin + (per_thread - 1) * step;
+ }
+ else
+ {
+ if (type != VCOMP_DYNAMIC_FLAGS_CHUNKED &&
+ type != VCOMP_DYNAMIC_FLAGS_GUIDED)
+ {
+ FIXME("unsupported flags %u\n", flags);
+ type = VCOMP_DYNAMIC_FLAGS_GUIDED;
+ }
+
+ EnterCriticalSection(&vcomp_section);
+ thread_data->dynamic++;
+ thread_data->dynamic_type = type;
+ if ((int)(thread_data->dynamic - task_data->dynamic) > 0)
+ {
+ task_data->dynamic = thread_data->dynamic;
+ task_data->dynamic_first = first;
+ task_data->dynamic_last = last;
+ task_data->dynamic_iterations = iterations;
+ task_data->dynamic_step = step;
+ task_data->dynamic_chunksize = chunksize;
+ }
+ LeaveCriticalSection(&vcomp_section);
+ }
+}
+
+int 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;
+ struct vcomp_team_data *team_data = thread_data->team;
+ int num_threads = team_data ? team_data->num_threads : 1;
+
+ TRACE("(%p, %p)\n", begin, end);
+
+ if (thread_data->dynamic_type == VCOMP_DYNAMIC_FLAGS_STATIC)
+ {
+ *begin = thread_data->dynamic_begin;
+ *end = thread_data->dynamic_end;
+ thread_data->dynamic_type = 0;
+ return 1;
+ }
+ else if (thread_data->dynamic_type == VCOMP_DYNAMIC_FLAGS_CHUNKED ||
+ thread_data->dynamic_type == VCOMP_DYNAMIC_FLAGS_GUIDED)
+ {
+ unsigned int iterations = 0;
+ 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);
+ if (thread_data->dynamic_type == VCOMP_DYNAMIC_FLAGS_GUIDED &&
+ task_data->dynamic_iterations > num_threads * task_data->dynamic_chunksize)
+ {
+ iterations = (task_data->dynamic_iterations + num_threads - 1) / num_threads;
+ }
+ *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;
+ if (!task_data->dynamic_iterations)
+ *end = task_data->dynamic_last;
+ }
+ LeaveCriticalSection(&vcomp_section);
+ return iterations != 0;
+ }
+
+ return 0;
+}
+
int CDECL omp_in_parallel(void)
{
TRACE("()\n");
@@ -711,6 +848,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;
@@ -718,6 +856,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);
@@ -736,6 +875,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);
@@ -757,6 +897,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 3a709df..6e2fcec 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 eb6e568..a9a07e1 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/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec
index b288e52..5373420 100644
--- a/dlls/vcomp110/vcomp110.spec
+++ b/dlls/vcomp110/vcomp110.spec
@@ -56,9 +56,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 eb6e568..a9a07e1 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.5.0
More information about the wine-patches
mailing list