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 =
};
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);
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
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