[PATCH v6 5/8] msvcr120: Add tests for _StructuredTaskCollection.

Torge Matthies tmatthies at codeweavers.com
Mon Apr 25 08:56:29 CDT 2022


Signed-off-by: Torge Matthies <tmatthies at codeweavers.com>
---
v5 -> v6:
  Fixed calling convention of _StructuredTaskCollection::_RunAndWait.

 dlls/msvcr120/tests/msvcr120.c | 131 +++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c
index a3161266db41..1fde3afed4a8 100644
--- a/dlls/msvcr120/tests/msvcr120.c
+++ b/dlls/msvcr120/tests/msvcr120.c
@@ -95,6 +95,31 @@ typedef struct cs_queue
     int unknown;
 } cs_queue;
 
+typedef struct UnrealizedChore
+{
+    void *unk1;
+    void (__cdecl *callback)(struct UnrealizedChore *_this, void *unk);
+    void *unk2;
+    void *unk3;
+    void *unk4;
+    void *unk5;
+    void *unk6;
+    void *unk7;
+    void *unk8;
+    void *unk9;
+} UnrealizedChore;
+
+typedef struct
+{
+    void *unk1;
+    unsigned int unk2;
+    void *unk3;
+    void *volatile unk_chores;
+    unsigned int count;
+    unsigned int unk5;
+    void *unk6;
+} StructuredTaskCollection;
+
 typedef struct
 {
     ULONG_PTR unk_thread_id;
@@ -204,6 +229,11 @@ static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t);
 #undef errno
 #define errno (*p_errno())
 
+static StructuredTaskCollection* (__thiscall *p__StructuredTaskCollection_ctor)(StructuredTaskCollection*, void*);
+static void (__thiscall *p__StructuredTaskCollection_dtor)(StructuredTaskCollection*);
+static void (__thiscall *p__StructuredTaskCollection__Schedule)(StructuredTaskCollection*, UnrealizedChore*);
+static int (__stdcall *p__StructuredTaskCollection__RunAndWait)(StructuredTaskCollection*, UnrealizedChore*);
+
 static critical_section* (__thiscall *p_critical_section_ctor)(critical_section*);
 static void (__thiscall *p_critical_section_dtor)(critical_section*);
 static void (__thiscall *p_critical_section_lock)(critical_section*);
@@ -279,6 +309,14 @@ static BOOL init(void)
     SET(p_towctrans, "towctrans");
     SET(p__Context__CurrentContext, "?_CurrentContext at _Context@details at Concurrency@@SA?AV123 at XZ");
     if(sizeof(void*) == 8) { /* 64-bit initialization */
+        SET(p__StructuredTaskCollection_ctor,
+                "??0_StructuredTaskCollection at details@Concurrency@@QEAA at PEAV_CancellationTokenState@12@@Z");
+        SET(p__StructuredTaskCollection_dtor,
+                "??1_StructuredTaskCollection at details@Concurrency@@QEAA at XZ");
+        SET(p__StructuredTaskCollection__Schedule,
+                "?_Schedule at _StructuredTaskCollection@details at Concurrency@@QEAAXPEAV_UnrealizedChore at 23@@Z");
+        SET(p__StructuredTaskCollection__RunAndWait,
+                "?_RunAndWait at _StructuredTaskCollection@details at Concurrency@@QEAA?AW4_TaskCollectionStatus at 23@PEAV_UnrealizedChore at 23@@Z");
         SET(p_critical_section_ctor,
                 "??0critical_section at Concurrency@@QEAA at XZ");
         SET(p_critical_section_dtor,
@@ -313,6 +351,12 @@ static BOOL init(void)
                 "?CurrentContext at Context@Concurrency@@SAPEAV12 at XZ");
     } else {
 #ifdef __arm__
+        SET(p__StructuredTaskCollection_ctor,
+                "??0_StructuredTaskCollection at details@Concurrency@@QAA at PAV_CancellationTokenState@12@@Z");
+        SET(p__StructuredTaskCollection__Schedule,
+                "?_Schedule at _StructuredTaskCollection@details at Concurrency@@QAAXPAV_UnrealizedChore at 23@@Z");
+        SET(p__StructuredTaskCollection__RunAndWait,
+                "?_RunAndWait at _StructuredTaskCollection@details at Concurrency@@QAA?AW4_TaskCollectionStatus at 23@PAV_UnrealizedChore at 23@@Z");
         SET(p_critical_section_ctor,
                 "??0critical_section at Concurrency@@QAA at XZ");
         SET(p_critical_section_dtor,
@@ -344,6 +388,14 @@ static BOOL init(void)
         SET(p__Condition_variable_notify_all,
                 "?notify_all at _Condition_variable@details at Concurrency@@QAAXXZ");
 #else
+        SET(p__StructuredTaskCollection_ctor,
+                "??0_StructuredTaskCollection at details@Concurrency@@QAE at PAV_CancellationTokenState@12@@Z");
+        SET(p__StructuredTaskCollection_dtor,
+                "??1_StructuredTaskCollection at details@Concurrency@@QAE at XZ");
+        SET(p__StructuredTaskCollection__Schedule,
+                "?_Schedule at _StructuredTaskCollection@details at Concurrency@@QAEXPAV_UnrealizedChore at 23@@Z");
+        SET(p__StructuredTaskCollection__RunAndWait,
+                "?_RunAndWait at _StructuredTaskCollection@details at Concurrency@@QAG?AW4_TaskCollectionStatus at 23@PAV_UnrealizedChore at 23@@Z");
         SET(p_critical_section_ctor,
                 "??0critical_section at Concurrency@@QAE at XZ");
         SET(p_critical_section_dtor,
@@ -738,6 +790,84 @@ static unsigned __stdcall test_critical_section_scoped_lock(void *arg)
     return 0;
 }
 
+static void setup_chore(UnrealizedChore *chore, void (__cdecl *callback)(struct UnrealizedChore *_this, void *unk))
+{
+    chore->unk1 = (void*)0xdeadbeef;
+    chore->callback = callback;
+    chore->unk2 = NULL;
+    chore->unk3 = (void*)0xdead0000;
+    chore->unk4 = (void*)0xdead1000;
+    chore->unk5 = (void*)0xdead2000;
+    chore->unk6 = (void*)0xdead3000;
+    chore->unk7 = (void*)0xdead4000;
+    chore->unk8 = (void*)0xdead5000;
+    chore->unk9 = (void*)0xdead6000;
+}
+
+static HANDLE chore_evt1;
+static HANDLE chore_evt2;
+static BOOL chore1_executed;
+static BOOL chore2_executed;
+static BOOL main_chore_executed;
+
+void __cdecl chore1_cb(struct UnrealizedChore *_this, void *unk)
+{
+    BOOL b;
+    DWORD ret;
+    b = SetEvent(chore_evt1);
+    ok(b, "SetEvent failed\n");
+    ret = WaitForSingleObject(chore_evt2, 5000);
+    ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", ret);
+    chore1_executed = TRUE;
+}
+
+void __cdecl chore2_cb(struct UnrealizedChore *_this, void *unk)
+{
+    BOOL b;
+    DWORD ret;
+    b = SetEvent(chore_evt2);
+    ok(b, "SetEvent failed\n");
+    ret = WaitForSingleObject(chore_evt1, 5000);
+    ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", ret);
+    chore2_executed = TRUE;
+}
+
+void __cdecl main_chore_cb(struct UnrealizedChore *_this, void *unk)
+{
+    main_chore_executed = TRUE;
+}
+
+static void test_StructuredTaskCollection(void)
+{
+    StructuredTaskCollection task_coll;
+    UnrealizedChore chore1, chore2, main_chore;
+    int status;
+
+    chore_evt1 = CreateEventW(NULL, FALSE, FALSE, NULL);
+    ok(chore_evt1 != NULL, "CreateEvent failed\n");
+    chore_evt2 = CreateEventW(NULL, FALSE, FALSE, NULL);
+    ok(chore_evt2 != NULL, "CreateEvent failed\n");
+
+    call_func2(p__StructuredTaskCollection_ctor, &task_coll, NULL);
+
+    /* test that all chores are run in parallel */
+    setup_chore(&chore1, chore1_cb);
+    setup_chore(&chore2, chore2_cb);
+    setup_chore(&main_chore, main_chore_cb);
+    call_func2(p__StructuredTaskCollection__Schedule, &task_coll, &chore1);
+    call_func2(p__StructuredTaskCollection__Schedule, &task_coll, &chore2);
+    status = p__StructuredTaskCollection__RunAndWait(&task_coll, &main_chore);
+    ok(status == 1, "_StructuredTaskCollection::_RunAndWait failed: %d\n", status);
+    todo_wine ok(chore1_executed, "_StructuredTaskCollection::_RunAndWait did not execute chore1\n");
+    todo_wine ok(chore2_executed, "_StructuredTaskCollection::_RunAndWait did not execute chore2\n");
+    todo_wine ok(main_chore_executed, "_StructuredTaskCollection::_RunAndWait did not execute the main chore\n");
+
+    call_func1(p__StructuredTaskCollection_dtor, &task_coll);
+
+    CloseHandle(chore_evt1);
+    CloseHandle(chore_evt2);
+}
+
 static void test_critical_section(void)
 {
     HANDLE thread;
@@ -1282,6 +1412,7 @@ START_TEST(msvcr120)
     test_gettnames(p__Gettnames);
     test__strtof();
     test_remainder();
+    test_StructuredTaskCollection();
     test_critical_section();
     test_feenv();
     test__wcreate_locale();
-- 
2.36.0




More information about the wine-devel mailing list