vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.
This commit is contained in:
parent
fa4dfa4325
commit
69ec890455
|
@ -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
|
||||||
|
|
||||||
/* 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
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
/* 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, ...)
|
||||||
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, ...)
|
||||||
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, ...)
|
||||||
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, ...)
|
||||||
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 @@
|
||||||
@ 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 @@
|
||||||
@ 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 @@
|
||||||
@ 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 @@
|
||||||
@ 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
|
||||||
|
|
Loading…
Reference in New Issue