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

Zebediah Figura z.figura12 at gmail.com
Wed Dec 5 10:11:52 CST 2018


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 | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/dlls/kernelbase/tests/sync.c b/dlls/kernelbase/tests/sync.c
index 99cbbc43bc..7a335d1af8 100644
--- a/dlls/kernelbase/tests/sync.c
+++ b/dlls/kernelbase/tests/sync.c
@@ -31,19 +31,23 @@ static void (WINAPI *pWakeByAddressAll)(void *);
 static void (WINAPI *pWakeByAddressSingle)(void *);
 
 static LONG64 address;
-static LONG64 compare;
 static DWORD WINAPI test_WaitOnAddress_func(void *arg)
 {
     BOOL ret = FALSE;
-    DWORD gle;
-    while (address == compare)
+    LONG64 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 (InterlockedCompareExchange64(&address, compare - 1, compare) != compare);
+
     return 0;
 }
 
@@ -51,6 +55,7 @@ static void test_WaitOnAddress(void)
 {
     DWORD gle, val, nthreads;
     HANDLE threads[8];
+    LONG64 compare;
     BOOL ret;
     int i;
 
@@ -135,31 +140,28 @@ static void test_WaitOnAddress(void)
 
     /* 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.14.1




More information about the wine-devel mailing list