[1/2] vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next.

Sebastian Lackner sebastian at fds-team.de
Thu Aug 6 02:30:57 CDT 2015


---
 dlls/vcomp/main.c           |  141 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/vcomp/vcomp.spec       |    4 -
 dlls/vcomp100/vcomp100.spec |    4 -
 dlls/vcomp110/vcomp110.spec |    4 -
 dlls/vcomp90/vcomp90.spec   |    4 -
 5 files changed, 149 insertions(+), 8 deletions(-)

diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 301370c..748899d 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -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);
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 3a709df..6e2fcec 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -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)
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index eb6e568..a9a07e1 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -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
diff --git a/dlls/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec
index b288e52..5373420 100644
--- a/dlls/vcomp110/vcomp110.spec
+++ b/dlls/vcomp110/vcomp110.spec
@@ -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
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index eb6e568..a9a07e1 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -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
-- 
2.5.0



More information about the wine-patches mailing list