[PATCH 5/6] vcomp: better stubs for _vcomp_for_dynamic_init, _vcomp_for_dynamic_next

Dan Kegel dank at kegel.com
Tue Oct 2 23:58:05 CDT 2012


---
 dlls/vcomp/tests/work.c    |   63 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/vcomp/vcomp.spec      |    4 +--
 dlls/vcomp/vcomp_private.h |   11 ++++++++
 dlls/vcomp/work.c          |   42 +++++++++++++++++++++++++++++
 4 files changed, 118 insertions(+), 2 deletions(-)

diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c
index d88f597..859edc8 100644
--- a/dlls/vcomp/tests/work.c
+++ b/dlls/vcomp/tests/work.c
@@ -21,12 +21,17 @@
 #include "wine/test.h"
 
 static void WINAPIV (*p_vcomp_fork)(DWORD parallel, int nargs, void *helper, ...);
+static void CDECL (*p_vcomp_for_dynamic_init)(int flags, int first, int last, int mystep, int chunksize);
+static int CDECL (*p_vcomp_for_dynamic_next)(int *pcounter, int *pchunklimit);
 static void CDECL (*p_vcomp_for_static_end)(void);
 static void CDECL (*p_vcomp_for_static_init)(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart);
 static void CDECL (*p_vcomp_for_static_simple_init)(int first, int last, int mystep, int step, int *pfirst, int *plast);
 
 #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0)
 
+/* Matches definition in ../vcomp_private.h */
+#define VCOMP_DYNAMIC_FOR_FLAGS_UP 0x40
+
 static BOOL init(void)
 {
     HMODULE vcomp = LoadLibraryA("vcomp.dll");
@@ -36,6 +41,8 @@ static BOOL init(void)
     }
 
     GETFUNC(_vcomp_fork);
+    GETFUNC(_vcomp_for_dynamic_init);
+    GETFUNC(_vcomp_for_dynamic_next);
     GETFUNC(_vcomp_for_static_end);
     GETFUNC(_vcomp_for_static_init);
     GETFUNC(_vcomp_for_static_simple_init);
@@ -46,6 +53,61 @@ static BOOL init(void)
 static LONG volatile ncalls;
 static LONG volatile nsum;
 
+static void CDECL _test_vcomp_for_dynamic_worker_up(void)
+{
+    int i, limit;
+
+    InterlockedIncrement(&ncalls);
+
+    /* pragma omp schedule(dynamic,16) */
+    /* for (i=0; i<=17; i++) */
+    p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FOR_FLAGS_UP, 0, 17, 1, 16);
+    while (p_vcomp_for_dynamic_next(&i, &limit)) {
+        for (; i<=limit; i++) {
+            int j;
+            for (j=0; j<i; j++) {
+                InterlockedIncrement(&nsum);
+            }
+        }
+    }
+}
+
+static void CDECL _test_vcomp_for_dynamic_worker_down(void)
+{
+    int i, limit;
+
+    InterlockedIncrement(&ncalls);
+
+    /* pragma omp schedule(dynamic,16) */
+    /* for (i=17; i>=0; i--) */
+    p_vcomp_for_dynamic_init(0, 17, 0, 1, 16);
+    while (p_vcomp_for_dynamic_next(&i, &limit)) {
+        for (; i>=limit; i--) {
+            int j;
+            for (j=0; j<i; j++) {
+                InterlockedIncrement(&nsum);
+            }
+        }
+    }
+}
+
+static void test_vcomp_for_dynamic(void)
+{
+    /* for (i=0; i<=17; i++) nsum += i; */
+    ncalls = 0;
+    nsum = 0;
+    p_vcomp_fork(1, 0, _test_vcomp_for_dynamic_worker_up);
+    ok(ncalls >= 1, "expected >= 1 call, got %d\n", ncalls);
+    ok(nsum == 9*17, "expected sum 9*17, got %d\n", nsum);
+
+    /* for (i=17; i>=0; i--) nsum += i; */
+    ncalls = 0;
+    nsum = 0;
+    p_vcomp_fork(1, 0, _test_vcomp_for_dynamic_worker_down);
+    ok(ncalls >= 1, "expected >= 1 call, got %d\n", ncalls);
+    ok(nsum == 9*17, "expected sum 9*17, got %d\n", nsum);
+}
+
 static void CDECL _test_vcomp_for_static_init_worker(void)
 {
     const int my_start = 0;
@@ -118,6 +180,7 @@ START_TEST(work)
     if (!init())
         return;
 
+    test_vcomp_for_dynamic();
     test_vcomp_for_static_init();
     test_vcomp_for_static_simple_init();
 }
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 31e5b51..c87abed 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)
 @ 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/vcomp/vcomp_private.h b/dlls/vcomp/vcomp_private.h
index f71b55e..999089f 100644
--- a/dlls/vcomp/vcomp_private.h
+++ b/dlls/vcomp/vcomp_private.h
@@ -23,6 +23,15 @@
 
 struct vcomp_team {
     struct vcomp_team *parent;
+    union {
+        struct {
+            int counter;
+            int step;
+            int iterations_remaining;
+            int chunksize;
+            int flags;
+        } dyn_for;
+    } work;
 };
 
 extern DWORD vcomp_context_tls_idx;
@@ -31,4 +40,6 @@ static inline struct vcomp_team *vcomp_get_team(void)
     return (struct vcomp_team *)TlsGetValue(vcomp_context_tls_idx);
 }
 
+#define VCOMP_DYNAMIC_FOR_FLAGS_UP 0x40
+
 #endif
diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c
index 6fad901..2aaf1c5 100644
--- a/dlls/vcomp/work.c
+++ b/dlls/vcomp/work.c
@@ -26,8 +26,50 @@
 #include "winbase.h"
 #include "wine/debug.h"
 
+#include "vcomp_private.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
 
+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int mystep, int chunksize)
+{
+    struct vcomp_team *pt = vcomp_get_team();
+
+    TRACE("(%d, %d, %d, %d, %d): stub\n", flags, first, last, mystep, chunksize);
+    pt->work.dyn_for.counter = first;
+    pt->work.dyn_for.chunksize = chunksize;
+    pt->work.dyn_for.flags = flags;
+    pt->work.dyn_for.step = mystep;
+    if (flags & VCOMP_DYNAMIC_FOR_FLAGS_UP) {
+        pt->work.dyn_for.iterations_remaining = 1 + (last - first) / mystep;
+    } else {
+        pt->work.dyn_for.iterations_remaining = 1 + (first - last) / mystep;
+    }
+}
+
+int CDECL _vcomp_for_dynamic_next(int *pcounter, int *pchunklimit)
+{
+    int n;
+    struct vcomp_team *pt = vcomp_get_team();
+
+    TRACE("(%p, %p): stub.\n", pcounter, pchunklimit);
+    n = pt->work.dyn_for.chunksize;
+    if (n > pt->work.dyn_for.iterations_remaining)
+        n = pt->work.dyn_for.iterations_remaining;
+    *pcounter = pt->work.dyn_for.counter;
+    if (pt->work.dyn_for.flags & VCOMP_DYNAMIC_FOR_FLAGS_UP) {
+        pt->work.dyn_for.counter += pt->work.dyn_for.step * n;
+        *pchunklimit = pt->work.dyn_for.counter - 1;
+    } else {
+        pt->work.dyn_for.counter -= pt->work.dyn_for.step * n;
+        *pchunklimit = pt->work.dyn_for.counter + 1;
+    }
+    pt->work.dyn_for.iterations_remaining -= n;
+
+    TRACE("counter %d, iterations_remaining %d, n %d, returning %d\n",
+       pt->work.dyn_for.counter, pt->work.dyn_for.iterations_remaining, n, (n > 0));
+    return (n > 0);
+}
+
 void CDECL _vcomp_for_static_init(int first, int last, int mystep, int chunksize, int *pnloops, int *pfirst, int *plast, int *pchunksize, int *pfinalchunkstart)
 {
     TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p): stub\n",
-- 
1.7.9.5




More information about the wine-patches mailing list