vcomp: Allow calls to _vcomp_sections_init outside of parallel environment.
This commit is contained in:
parent
457c5f1977
commit
889eba36e9
|
@ -52,6 +52,7 @@ static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
struct vcomp_thread_data
|
struct vcomp_thread_data
|
||||||
{
|
{
|
||||||
struct vcomp_team_data *team;
|
struct vcomp_team_data *team;
|
||||||
|
struct vcomp_task_data *task;
|
||||||
int thread_num;
|
int thread_num;
|
||||||
int fork_threads;
|
int fork_threads;
|
||||||
|
|
||||||
|
@ -77,7 +78,10 @@ struct vcomp_team_data
|
||||||
/* barrier */
|
/* barrier */
|
||||||
unsigned int barrier;
|
unsigned int barrier;
|
||||||
int barrier_count;
|
int barrier_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vcomp_task_data
|
||||||
|
{
|
||||||
/* section */
|
/* section */
|
||||||
unsigned int section;
|
unsigned int section;
|
||||||
int num_sections;
|
int num_sections;
|
||||||
|
@ -180,17 +184,27 @@ static inline void vcomp_set_thread_data(struct vcomp_thread_data *thread_data)
|
||||||
static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
static struct vcomp_thread_data *vcomp_init_thread_data(void)
|
||||||
{
|
{
|
||||||
struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||||
if (thread_data) return thread_data;
|
struct
|
||||||
|
{
|
||||||
|
struct vcomp_thread_data thread;
|
||||||
|
struct vcomp_task_data task;
|
||||||
|
} *data;
|
||||||
|
|
||||||
if (!(thread_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*thread_data))))
|
if (thread_data) return thread_data;
|
||||||
|
if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data))))
|
||||||
{
|
{
|
||||||
ERR("could not create thread data\n");
|
ERR("could not create thread data\n");
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->task.section = 0;
|
||||||
|
|
||||||
|
thread_data = &data->thread;
|
||||||
thread_data->team = NULL;
|
thread_data->team = NULL;
|
||||||
|
thread_data->task = &data->task;
|
||||||
thread_data->thread_num = 0;
|
thread_data->thread_num = 0;
|
||||||
thread_data->fork_threads = 0;
|
thread_data->fork_threads = 0;
|
||||||
|
thread_data->section = 1;
|
||||||
|
|
||||||
vcomp_set_thread_data(thread_data);
|
vcomp_set_thread_data(thread_data);
|
||||||
return thread_data;
|
return thread_data;
|
||||||
|
@ -311,35 +325,35 @@ void CDECL _vcomp_single_end(void)
|
||||||
|
|
||||||
void CDECL _vcomp_sections_init(int n)
|
void CDECL _vcomp_sections_init(int n)
|
||||||
{
|
{
|
||||||
struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
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;
|
||||||
|
|
||||||
TRACE("(%d)\n", n);
|
TRACE("(%d)\n", n);
|
||||||
|
|
||||||
EnterCriticalSection(&vcomp_section);
|
EnterCriticalSection(&vcomp_section);
|
||||||
thread_data->section++;
|
thread_data->section++;
|
||||||
if ((int)(thread_data->section - team_data->section) > 0)
|
if ((int)(thread_data->section - task_data->section) > 0)
|
||||||
{
|
{
|
||||||
team_data->section = thread_data->section;
|
task_data->section = thread_data->section;
|
||||||
team_data->num_sections = n;
|
task_data->num_sections = n;
|
||||||
team_data->section_index = 0;
|
task_data->section_index = 0;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&vcomp_section);
|
LeaveCriticalSection(&vcomp_section);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CDECL _vcomp_sections_next(void)
|
int CDECL _vcomp_sections_next(void)
|
||||||
{
|
{
|
||||||
struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
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 i = -1;
|
int i = -1;
|
||||||
|
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
|
|
||||||
EnterCriticalSection(&vcomp_section);
|
EnterCriticalSection(&vcomp_section);
|
||||||
if (thread_data->section == team_data->section &&
|
if (thread_data->section == task_data->section &&
|
||||||
team_data->section_index != team_data->num_sections)
|
task_data->section_index != task_data->num_sections)
|
||||||
{
|
{
|
||||||
i = team_data->section_index++;
|
i = task_data->section_index++;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&vcomp_section);
|
LeaveCriticalSection(&vcomp_section);
|
||||||
return i;
|
return i;
|
||||||
|
@ -391,6 +405,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||||
struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data();
|
struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data();
|
||||||
struct vcomp_thread_data thread_data;
|
struct vcomp_thread_data thread_data;
|
||||||
struct vcomp_team_data team_data;
|
struct vcomp_team_data team_data;
|
||||||
|
struct vcomp_task_data task_data;
|
||||||
int num_threads;
|
int num_threads;
|
||||||
|
|
||||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||||
|
@ -412,9 +427,11 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||||
__ms_va_start(team_data.valist, wrapper);
|
__ms_va_start(team_data.valist, wrapper);
|
||||||
team_data.barrier = 0;
|
team_data.barrier = 0;
|
||||||
team_data.barrier_count = 0;
|
team_data.barrier_count = 0;
|
||||||
team_data.section = 0;
|
|
||||||
|
task_data.section = 0;
|
||||||
|
|
||||||
thread_data.team = &team_data;
|
thread_data.team = &team_data;
|
||||||
|
thread_data.task = &task_data;
|
||||||
thread_data.thread_num = 0;
|
thread_data.thread_num = 0;
|
||||||
thread_data.fork_threads = 0;
|
thread_data.fork_threads = 0;
|
||||||
thread_data.section = 1;
|
thread_data.section = 1;
|
||||||
|
@ -431,6 +448,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||||
{
|
{
|
||||||
struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry);
|
struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry);
|
||||||
data->team = &team_data;
|
data->team = &team_data;
|
||||||
|
data->task = &task_data;
|
||||||
data->thread_num = team_data.num_threads++;
|
data->thread_num = team_data.num_threads++;
|
||||||
data->fork_threads = 0;
|
data->fork_threads = 0;
|
||||||
data->section = 1;
|
data->section = 1;
|
||||||
|
@ -450,6 +468,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||||
if (!data) break;
|
if (!data) break;
|
||||||
|
|
||||||
data->team = &team_data;
|
data->team = &team_data;
|
||||||
|
data->task = &task_data;
|
||||||
data->thread_num = team_data.num_threads;
|
data->thread_num = team_data.num_threads;
|
||||||
data->fork_threads = 0;
|
data->fork_threads = 0;
|
||||||
data->section = 1;
|
data->section = 1;
|
||||||
|
|
|
@ -378,15 +378,35 @@ static void test_vcomp_sections_init(void)
|
||||||
int max_threads = pomp_get_max_threads();
|
int max_threads = pomp_get_max_threads();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
/* calling _vcomp_sections_next without prior _vcomp_sections_init
|
||||||
|
* returns uninitialized memory on Windows. */
|
||||||
|
i = p_vcomp_sections_next();
|
||||||
|
ok(i == -1, "expected -1, got %d\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
a = b = c = 0;
|
||||||
|
section_cb(&a, &b, &c);
|
||||||
|
ok(a == 20, "expected a == 20, got %d\n", a);
|
||||||
|
ok(b == 30, "expected b == 30, got %d\n", b);
|
||||||
|
ok(c == 40, "expected c == 40, got %d\n", c);
|
||||||
|
|
||||||
for (i = 1; i <= 4; i++)
|
for (i = 1; i <= 4; i++)
|
||||||
{
|
{
|
||||||
pomp_set_num_threads(i);
|
pomp_set_num_threads(i);
|
||||||
|
|
||||||
a = b = c = 0;
|
a = b = c = 0;
|
||||||
p_vcomp_fork(TRUE, 3, section_cb, &a, &b, &c);
|
p_vcomp_fork(TRUE, 3, section_cb, &a, &b, &c);
|
||||||
ok(a == 20, "expected a = 20, got %d\n", a);
|
ok(a == 20, "expected a == 20, got %d\n", a);
|
||||||
ok(b == 30, "expected b = 30, got %d\n", b);
|
ok(b == 30, "expected b == 30, got %d\n", b);
|
||||||
ok(c == 40, "expected c = 40, got %d\n", c);
|
ok(c == 40, "expected c == 40, got %d\n", c);
|
||||||
|
|
||||||
|
a = b = c = 0;
|
||||||
|
p_vcomp_fork(FALSE, 3, section_cb, &a, &b, &c);
|
||||||
|
ok(a == 20, "expected a == 20, got %d\n", a);
|
||||||
|
ok(b == 30, "expected b == 30, got %d\n", b);
|
||||||
|
ok(c == 40, "expected c == 40, got %d\n", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
pomp_set_num_threads(max_threads);
|
pomp_set_num_threads(max_threads);
|
||||||
|
|
Loading…
Reference in New Issue