From: Zebediah Figura Subject: [PATCH v2 1/2] kernelbase/tests: Relax tests for WaitOnAddress(). Message-Id: <20181205161153.32196-1-z.figura12@gmail.com> Date: Wed, 5 Dec 2018 10:11:52 -0600 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 --- 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