Commit 69ec8904 authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.

parent fa4dfa43
...@@ -50,6 +50,11 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = ...@@ -50,6 +50,11 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
}; };
static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 }; 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_thread_data
{ {
struct vcomp_team_data *team; struct vcomp_team_data *team;
...@@ -64,6 +69,12 @@ struct vcomp_thread_data ...@@ -64,6 +69,12 @@ struct vcomp_thread_data
/* section */ /* section */
unsigned int section; unsigned int section;
/* dynamic */
unsigned int dynamic;
unsigned int dynamic_type;
unsigned int dynamic_begin;
unsigned int dynamic_end;
}; };
struct vcomp_team_data struct vcomp_team_data
...@@ -88,6 +99,14 @@ struct vcomp_task_data ...@@ -88,6 +99,14 @@ struct vcomp_task_data
unsigned int section; unsigned int section;
int num_sections; int num_sections;
int section_index; 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__) #if defined(__i386__)
...@@ -200,6 +219,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void) ...@@ -200,6 +219,7 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
} }
data->task.section = 0; data->task.section = 0;
data->task.dynamic = 0;
thread_data = &data->thread; thread_data = &data->thread;
thread_data->team = NULL; thread_data->team = NULL;
...@@ -208,6 +228,8 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void) ...@@ -208,6 +228,8 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
thread_data->parallel = FALSE; thread_data->parallel = FALSE;
thread_data->fork_threads = 0; thread_data->fork_threads = 0;
thread_data->section = 1; thread_data->section = 1;
thread_data->dynamic = 1;
thread_data->dynamic_type = 0;
vcomp_set_thread_data(thread_data); vcomp_set_thread_data(thread_data);
return thread_data; return thread_data;
...@@ -634,6 +656,121 @@ void CDECL _vcomp_for_static_end(void) ...@@ -634,6 +656,121 @@ void CDECL _vcomp_for_static_end(void)
/* nothing to do here */ /* 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) int CDECL omp_in_parallel(void)
{ {
TRACE("()\n"); TRACE("()\n");
...@@ -711,6 +848,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) ...@@ -711,6 +848,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
team_data.barrier_count = 0; team_data.barrier_count = 0;
task_data.section = 0; task_data.section = 0;
task_data.dynamic = 0;
thread_data.team = &team_data; thread_data.team = &team_data;
thread_data.task = &task_data; thread_data.task = &task_data;
...@@ -718,6 +856,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) ...@@ -718,6 +856,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
thread_data.parallel = ifval || prev_thread_data->parallel; thread_data.parallel = ifval || prev_thread_data->parallel;
thread_data.fork_threads = 0; thread_data.fork_threads = 0;
thread_data.section = 1; thread_data.section = 1;
thread_data.dynamic = 1;
list_init(&thread_data.entry); list_init(&thread_data.entry);
InitializeConditionVariable(&thread_data.cond); InitializeConditionVariable(&thread_data.cond);
...@@ -736,6 +875,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) ...@@ -736,6 +875,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->parallel = thread_data.parallel; data->parallel = thread_data.parallel;
data->fork_threads = 0; data->fork_threads = 0;
data->section = 1; data->section = 1;
data->dynamic = 1;
list_remove(&data->entry); list_remove(&data->entry);
list_add_tail(&thread_data.entry, &data->entry); list_add_tail(&thread_data.entry, &data->entry);
WakeAllConditionVariable(&data->cond); WakeAllConditionVariable(&data->cond);
...@@ -757,6 +897,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) ...@@ -757,6 +897,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->parallel = thread_data.parallel; data->parallel = thread_data.parallel;
data->fork_threads = 0; data->fork_threads = 0;
data->section = 1; data->section = 1;
data->dynamic = 1;
InitializeConditionVariable(&data->cond); InitializeConditionVariable(&data->cond);
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL); thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
......
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
@ stub _vcomp_copyprivate_receive @ stub _vcomp_copyprivate_receive
@ stub _vcomp_enter_critsect @ stub _vcomp_enter_critsect
@ stub _vcomp_flush @ 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_init_i8
@ stub _vcomp_for_dynamic_next @ cdecl _vcomp_for_dynamic_next(ptr ptr)
@ stub _vcomp_for_dynamic_next_i8 @ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end() @ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
......
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
@ stub _vcomp_copyprivate_receive @ stub _vcomp_copyprivate_receive
@ stub _vcomp_enter_critsect @ stub _vcomp_enter_critsect
@ stub _vcomp_flush @ 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_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 @ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end @ 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 @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
......
...@@ -56,9 +56,9 @@ ...@@ -56,9 +56,9 @@
@ stub _vcomp_copyprivate_receive @ stub _vcomp_copyprivate_receive
@ stub _vcomp_enter_critsect @ stub _vcomp_enter_critsect
@ stub _vcomp_flush @ 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_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 @ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end @ 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 @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
......
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
@ stub _vcomp_copyprivate_receive @ stub _vcomp_copyprivate_receive
@ stub _vcomp_enter_critsect @ stub _vcomp_enter_critsect
@ stub _vcomp_flush @ 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_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 @ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end @ 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 @ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment