From 69ec8904557f2ecb9708dd38034a13993be9a646 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 6 Aug 2015 09:30:57 +0200 Subject: [PATCH] vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next. --- 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 301370c1bb6..748899ddbe9 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 3a709df17e9..6e2fcec1aff 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 eb6e568b6a2..a9a07e10d79 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 b288e5231de..5373420196f 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 eb6e568b6a2..a9a07e10d79 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.11.4.GIT