[PATCH v3 1/2] kernelbase/tests: Relax tests for WaitOnAddress().

Zebediah Figura z.figura12 at gmail.com
Tue Feb 5 20:21:06 CST 2019


Application should be expected to handle spurious wakeups, which the
following implementation will give in WakeByAddressSingle(). Avoid testing
that WakeByAddressSingle() only wakes one thread.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/kernelbase/tests/sync.c | 50 +++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/dlls/kernelbase/tests/sync.c b/dlls/kernelbase/tests/sync.c
index 99cbbc43bc..eb1a20f11e 100644
--- a/dlls/kernelbase/tests/sync.c
+++ b/dlls/kernelbase/tests/sync.c
@@ -30,20 +30,24 @@ static BOOL (WINAPI *pWaitOnAddress)(volatile void *, void *, SIZE_T, DWORD);
 static void (WINAPI *pWakeByAddressAll)(void *);
 static void (WINAPI *pWakeByAddressSingle)(void *);
 
-static LONG64 address;
-static LONG64 compare;
+static LONG address;
 static DWORD WINAPI test_WaitOnAddress_func(void *arg)
 {
     BOOL ret = FALSE;
-    DWORD gle;
-    while (address == compare)
+    LONG compare;
+
+    do
     {
-        SetLastError(0xdeadbeef);
-        ret = pWaitOnAddress(&address, &compare, sizeof(compare), INFINITE);
-        gle = GetLastError();
-        ok(gle == 0xdeadbeef || broken(gle == ERROR_SUCCESS) /* Win 8 */, "got %d\n", gle);
-    }
-    ok(ret, "got %d\n", ret);
+        while (!(compare = address))
+        {
+            SetLastError(0xdeadbeef);
+            ret = pWaitOnAddress(&address, &compare, sizeof(compare), INFINITE);
+            ok(ret, "wait failed\n");
+            ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_SUCCESS) /* Win 8 */,
+                    "got error %d\n", GetLastError());
+        }
+    } while (InterlockedCompareExchange(&address, compare - 1, compare) != compare);
+
     return 0;
 }
 
@@ -51,6 +55,7 @@ static void test_WaitOnAddress(void)
 {
     DWORD gle, val, nthreads;
     HANDLE threads[8];
+    LONG compare;
     BOOL ret;
     int i;
 
@@ -64,8 +69,8 @@ static void test_WaitOnAddress(void)
     compare = 0;
     if (0) /* crash on Windows */
     {
-        ret = pWaitOnAddress(&address, NULL, 8, 0);
-        ret = pWaitOnAddress(NULL, &compare, 8, 0);
+        ret = pWaitOnAddress(&address, NULL, 4, 0);
+        ret = pWaitOnAddress(NULL, &compare, 4, 0);
     }
 
     /* invalid arguments */
@@ -111,15 +116,15 @@ static void test_WaitOnAddress(void)
 
     /* different address size */
     address = 0;
-    compare = 0xffff0000;
+    compare = 0xff00;
     SetLastError(0xdeadbeef);
-    ret = pWaitOnAddress(&address, &compare, 4, 0);
+    ret = pWaitOnAddress(&address, &compare, 2, 0);
     gle = GetLastError();
     ok(gle == 0xdeadbeef || broken(gle == ERROR_SUCCESS) /* Win 8 */, "got %d\n", gle);
     ok(ret, "got %d\n", ret);
 
     SetLastError(0xdeadbeef);
-    ret = pWaitOnAddress(&address, &compare, 2, 0);
+    ret = pWaitOnAddress(&address, &compare, 1, 0);
     gle = GetLastError();
     ok(gle == ERROR_TIMEOUT, "got %d\n", gle);
     ok(!ret, "got %d\n", ret);
@@ -128,38 +133,35 @@ static void test_WaitOnAddress(void)
     address = 0;
     compare = 1;
     SetLastError(0xdeadbeef);
-    ret = pWaitOnAddress(&address, &compare, 8, 0);
+    ret = pWaitOnAddress(&address, &compare, 4, 0);
     gle = GetLastError();
     ok(gle == 0xdeadbeef || broken(gle == ERROR_SUCCESS) /* Win 8 */, "got %d\n", gle);
     ok(ret, "got %d\n", ret);
 
     /* WakeByAddressAll */
     address = 0;
-    compare = 0;
     for (i = 0; i < ARRAY_SIZE(threads); i++)
         threads[i] = CreateThread(NULL, 0, test_WaitOnAddress_func, NULL, 0, NULL);
 
     Sleep(100);
-    address = ~0;
+    address = ARRAY_SIZE(threads);
     pWakeByAddressAll(&address);
     val = WaitForMultipleObjects(ARRAY_SIZE(threads), threads, TRUE, 5000);
     ok(val == WAIT_OBJECT_0, "got %d\n", val);
     for (i = 0; i < ARRAY_SIZE(threads); i++)
         CloseHandle(threads[i]);
+    ok(!address, "got unexpected value %s\n", wine_dbgstr_longlong(address));
 
     /* WakeByAddressSingle */
     address = 0;
     for (i = 0; i < ARRAY_SIZE(threads); i++)
-        threads[i] = CreateThread(NULL, 0, test_WaitOnAddress_func, NULL, 0, NULL);
+            threads[i] = CreateThread(NULL, 0, test_WaitOnAddress_func, NULL, 0, NULL);
 
     Sleep(100);
-    address = 1;
     nthreads = ARRAY_SIZE(threads);
+    address = ARRAY_SIZE(threads);
     while (nthreads)
     {
-        val = WaitForMultipleObjects(nthreads, threads, FALSE, 0);
-        ok(val == STATUS_TIMEOUT, "got %u\n", val);
-
         pWakeByAddressSingle(&address);
         val = WaitForMultipleObjects(nthreads, threads, FALSE, 2000);
         ok(val < WAIT_OBJECT_0 + nthreads, "got %u\n", val);
@@ -167,7 +169,7 @@ static void test_WaitOnAddress(void)
         memmove(&threads[val], &threads[val+1], (nthreads - val - 1) * sizeof(threads[0]));
         nthreads--;
     }
-
+    ok(!address, "got unexpected value %s\n", wine_dbgstr_longlong(address));
 }
 
 START_TEST(sync)
-- 
2.20.1




More information about the wine-devel mailing list