Module: wine Branch: master Commit: 889eba36e93918e7957cb3fda142d87abc2b9c84 URL: http://source.winehq.org/git/wine.git/?a=commit;h=889eba36e93918e7957cb3fda1...
Author: Sebastian Lackner sebastian@fds-team.de Date: Mon Jul 20 05:15:27 2015 +0200
vcomp: Allow calls to _vcomp_sections_init outside of parallel environment.
---
dlls/vcomp/main.c | 47 +++++++++++++++++++++++++++++++++-------------- dlls/vcomp/tests/vcomp.c | 26 +++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c index 0f8a272..6e99d21 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -52,6 +52,7 @@ static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 }; struct vcomp_thread_data { struct vcomp_team_data *team; + struct vcomp_task_data *task; int thread_num; int fork_threads;
@@ -77,7 +78,10 @@ struct vcomp_team_data /* barrier */ unsigned int barrier; int barrier_count; +};
+struct vcomp_task_data +{ /* section */ unsigned int section; 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) { 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"); ExitProcess(1); }
+ data->task.section = 0; + + thread_data = &data->thread; thread_data->team = NULL; + thread_data->task = &data->task; thread_data->thread_num = 0; thread_data->fork_threads = 0; + thread_data->section = 1;
vcomp_set_thread_data(thread_data); return thread_data; @@ -311,35 +325,35 @@ void CDECL _vcomp_single_end(void)
void CDECL _vcomp_sections_init(int n) { - struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); - struct vcomp_team_data *team_data = thread_data->team; + struct vcomp_thread_data *thread_data = vcomp_init_thread_data(); + struct vcomp_task_data *task_data = thread_data->task;
TRACE("(%d)\n", n);
EnterCriticalSection(&vcomp_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; - team_data->num_sections = n; - team_data->section_index = 0; + task_data->section = thread_data->section; + task_data->num_sections = n; + task_data->section_index = 0; } LeaveCriticalSection(&vcomp_section); }
int CDECL _vcomp_sections_next(void) { - struct vcomp_thread_data *thread_data = vcomp_get_thread_data(); - struct vcomp_team_data *team_data = thread_data->team; + struct vcomp_thread_data *thread_data = vcomp_init_thread_data(); + struct vcomp_task_data *task_data = thread_data->task; int i = -1;
TRACE("()\n");
EnterCriticalSection(&vcomp_section); - if (thread_data->section == team_data->section && - team_data->section_index != team_data->num_sections) + if (thread_data->section == task_data->section && + task_data->section_index != task_data->num_sections) { - i = team_data->section_index++; + i = task_data->section_index++; } LeaveCriticalSection(&vcomp_section); 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 thread_data; struct vcomp_team_data team_data; + struct vcomp_task_data task_data; int num_threads;
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); team_data.barrier = 0; team_data.barrier_count = 0; - team_data.section = 0; + + task_data.section = 0;
thread_data.team = &team_data; + thread_data.task = &task_data; thread_data.thread_num = 0; thread_data.fork_threads = 0; 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); data->team = &team_data; + data->task = &task_data; data->thread_num = team_data.num_threads++; data->fork_threads = 0; data->section = 1; @@ -450,6 +468,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...) if (!data) break;
data->team = &team_data; + data->task = &task_data; data->thread_num = team_data.num_threads; data->fork_threads = 0; data->section = 1; diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c index c433991..a96f957 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c @@ -378,15 +378,35 @@ static void test_vcomp_sections_init(void) int max_threads = pomp_get_max_threads(); 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++) { pomp_set_num_threads(i);
a = b = c = 0; p_vcomp_fork(TRUE, 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); + 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); + + 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);