From 6c448aeca163dc103f15c7a9499df7baef9cf6d3 Mon Sep 17 00:00:00 2001
From: Dan Kegel <dank@kegel.com>
Date: Mon, 1 Oct 2012 21:39:21 -0700
Subject: [PATCH 12/14] vcomp: better stubs for _vcomp_sections_init,
 _vcomp_sections_next, and _vcomp_barrier

---
 dlls/vcomp/fork.c          |    5 +++++
 dlls/vcomp/tests/work.c    |   33 +++++++++++++++++++++++++++++++++
 dlls/vcomp/vcomp.spec      |    6 +++---
 dlls/vcomp/vcomp_private.h |    4 ++++
 dlls/vcomp/work.c          |   17 +++++++++++++++++
 5 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/dlls/vcomp/fork.c b/dlls/vcomp/fork.c
index ca80c98..e2384bc 100644
--- a/dlls/vcomp/fork.c
+++ b/dlls/vcomp/fork.c
@@ -29,10 +29,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
 
+void CDECL _vcomp_barrier(void);
 void WINAPIV _vcomp_fork(DWORD parallel, int nargs, void *helper, ...);
 void CDECL _vcomp_fork_body(DWORD parallel, int nargs, void *helper, DWORD *args);
 void CDECL _vcomp_fork_call_helper(void *helper, int nargs, DWORD *args);
 
+void CDECL _vcomp_barrier(void)
+{
+    TRACE("stub\n");
+}
 
 /* Marshal helper's arguments into array, then call _vcomp_fork_body.
  * The helper's arguments are always pointers, never floating point numbers.
diff --git a/dlls/vcomp/tests/work.c b/dlls/vcomp/tests/work.c
index 859edc8..654ef9f 100644
--- a/dlls/vcomp/tests/work.c
+++ b/dlls/vcomp/tests/work.c
@@ -20,12 +20,15 @@
 
 #include "wine/test.h"
 
+static void WINAPIV (*p_vcomp_barrier)(void);
 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);
+static void CDECL (*p_vcomp_sections_init)(int n);
+static int CDECL (*p_vcomp_sections_next)(void);
 
 #define GETFUNC(x) do { p##x = (void*)GetProcAddress(vcomp, #x); ok(p##x != NULL, "Export '%s' not found\n", #x); } while(0)
 
@@ -40,12 +43,15 @@ static BOOL init(void)
         return FALSE;
     }
 
+    GETFUNC(_vcomp_barrier);
     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);
+    GETFUNC(_vcomp_sections_init);
+    GETFUNC(_vcomp_sections_next);
 
     return TRUE;
 }
@@ -175,6 +181,32 @@ static void test_vcomp_for_static_simple_init(void)
     ok(nsum == 6*13, "expected sum 6*13, got %d\n", nsum);
 }
 
+int section_calls[3];
+
+static void CDECL _test_vcomp_sections_worker(void)
+{
+    p_vcomp_sections_init(3);
+
+    while (1) {
+        int i = p_vcomp_sections_next();
+        if (i < 0 || i >= 3) break;
+        section_calls[i]++;
+    }
+
+    p_vcomp_barrier();
+}
+
+static void test_vcomp_sections(void)
+{
+    section_calls[0] = 0;
+    section_calls[1] = 0;
+    section_calls[2] = 0;
+    p_vcomp_fork(1, 0, _test_vcomp_sections_worker);
+    ok(section_calls[0] == 1, "section 0 not called once\n");
+    ok(section_calls[1] == 1, "section 1 not called once\n");
+    ok(section_calls[2] == 1, "section 2 not called once\n");
+}
+
 START_TEST(work)
 {
     if (!init())
@@ -183,4 +215,5 @@ START_TEST(work)
     test_vcomp_for_dynamic();
     test_vcomp_for_static_init();
     test_vcomp_for_static_simple_init();
+    test_vcomp_sections();
 }
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index c87abed..1149d76 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -50,7 +50,7 @@
 @ stub _vcomp_atomic_xor_i2
 @ stub _vcomp_atomic_xor_i4
 @ stub _vcomp_atomic_xor_i8
-@ stub _vcomp_barrier
+@ cdecl _vcomp_barrier()
 @ stub _vcomp_copyprivate_broadcast
 @ stub _vcomp_copyprivate_receive
 @ stub _vcomp_enter_critsect
@@ -83,8 +83,8 @@
 @ stub _vcomp_reduction_u2
 @ stub _vcomp_reduction_u4
 @ stub _vcomp_reduction_u8
-@ stub _vcomp_sections_init
-@ stub _vcomp_sections_next
+@ cdecl _vcomp_sections_init(long)
+@ cdecl _vcomp_sections_next()
 @ cdecl _vcomp_set_num_threads(long)
 @ stub _vcomp_single_begin
 @ stub _vcomp_single_end
diff --git a/dlls/vcomp/vcomp_private.h b/dlls/vcomp/vcomp_private.h
index 999089f..b6cd6ee 100644
--- a/dlls/vcomp/vcomp_private.h
+++ b/dlls/vcomp/vcomp_private.h
@@ -31,6 +31,10 @@ struct vcomp_team {
             int chunksize;
             int flags;
         } dyn_for;
+        struct {
+            int counter;
+            int nsect;
+        } sections;
     } work;
 };
 
diff --git a/dlls/vcomp/work.c b/dlls/vcomp/work.c
index 3376783..199b9f2 100644
--- a/dlls/vcomp/work.c
+++ b/dlls/vcomp/work.c
@@ -93,3 +93,20 @@ void CDECL _vcomp_for_static_end(void)
     TRACE("stub\n");
 }
 
+void CDECL _vcomp_sections_init(int n)
+{
+    struct vcomp_team *pt = vcomp_get_team();
+    TRACE("(%d): stub\n", n);
+    pt->work.sections.counter = 0;
+    pt->work.sections.nsect = n;
+}
+
+int CDECL _vcomp_sections_next(void)
+{
+    struct vcomp_team *pt = vcomp_get_team();
+    int i = pt->work.sections.counter++;
+    if (i >= pt->work.sections.nsect)
+        i = -1;
+    TRACE("stub; returning %d\n", i);
+    return i;
+}
-- 
1.7.9.5

