[PATCH 9/9] ntdll/tests: Change bad test & add random test order
Daniel Santos
daniel.santos at pobox.com
Sun Sep 13 17:16:06 CDT 2015
The test on line 244 can fail if scheduling happens to preempt the
main thread at just the right time, especially if a page fault is hit
and I/O is needed or the semaphore implementation is faster than it was
when this test was originally written.
---
dlls/ntdll/tests/threadpool.c | 62 +++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c
index 7be3f0d..5397419 100644
--- a/dlls/ntdll/tests/threadpool.c
+++ b/dlls/ntdll/tests/threadpool.c
@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <stdio.h>
+#include <sys/time.h>
+
#include "ntdll_test.h"
static HMODULE hntdll = 0;
@@ -238,7 +241,7 @@ static void test_tp_simple(void)
ok(!status, "TpSimpleTryPost failed with status %x\n", status);
}
pTpReleaseCleanupGroupMembers(group, TRUE, NULL);
- ok(userdata < 100, "expected userdata < 100, got %u\n", userdata);
+ ok(userdata <= 100, "expected userdata <= 100, got %u\n", userdata);
/* cleanup */
pTpReleaseCleanupGroup(group);
@@ -1235,11 +1238,15 @@ static void CALLBACK multi_wait_cb(TP_CALLBACK_INSTANCE *instance, void *userdat
ReleaseSemaphore(multi_wait_info.semaphore, 1, NULL);
}
+#define TP_TEST_SIZE 512
static void test_tp_multi_wait(void)
{
TP_CALLBACK_ENVIRON environment;
- HANDLE semaphores[512];
- TP_WAIT *waits[512];
+ HANDLE semaphores[TP_TEST_SIZE];
+ TP_WAIT *waits[TP_TEST_SIZE];
+ int rand_order[TP_TEST_SIZE];
+ struct timeval now;
+ unsigned int seed;
LARGE_INTEGER when;
HANDLE semaphore;
NTSTATUS status;
@@ -1247,7 +1254,7 @@ static void test_tp_multi_wait(void)
DWORD result;
int i;
- semaphore = CreateSemaphoreW(NULL, 0, 512, NULL);
+ semaphore = CreateSemaphoreW(NULL, 0, TP_TEST_SIZE, NULL);
ok(semaphore != NULL, "failed to create semaphore\n");
multi_wait_info.semaphore = semaphore;
@@ -1261,8 +1268,27 @@ static void test_tp_multi_wait(void)
environment.Version = 1;
environment.Pool = pool;
+ /* init a randomized index */
+ if (gettimeofday (&now, NULL))
+ perror("gettimeofday");
+ seed = now.tv_sec ^ now.tv_usec;
+
+ memset(&rand_order, 0, TP_TEST_SIZE * sizeof(rand_order[0]));
+ for (i = 1; i < TP_TEST_SIZE; i++)
+ {
+ int j;
+ for (j = rand_r(&seed) % TP_TEST_SIZE; ; j = (j + 1) % TP_TEST_SIZE)
+ {
+ if (!rand_order[j])
+ {
+ rand_order[j] = i;
+ break;
+ }
+ }
+ }
+
/* create semaphores and corresponding wait objects */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
semaphores[i] = CreateSemaphoreW(NULL, 0, 1, NULL);
ok(semaphores[i] != NULL, "failed to create semaphore %i\n", i);
@@ -1276,7 +1302,7 @@ static void test_tp_multi_wait(void)
}
/* release all semaphores and wait for callback */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
multi_wait_info.result = 0;
ReleaseSemaphore(semaphores[i], 1, NULL);
@@ -1289,7 +1315,7 @@ static void test_tp_multi_wait(void)
}
/* repeat the same test in reverse order */
- for (i = sizeof(semaphores)/sizeof(semaphores[0]) - 1; i >= 0; i--)
+ for (i = TP_TEST_SIZE - 1; i >= 0; i--)
{
multi_wait_info.result = 0;
ReleaseSemaphore(semaphores[i], 1, NULL);
@@ -1301,15 +1327,29 @@ static void test_tp_multi_wait(void)
pTpSetWait(waits[i], semaphores[i], NULL);
}
+ /* repeat again in random order */
+ for (i = 0; i < TP_TEST_SIZE; i++)
+ {
+ int j = rand_order[i];
+ multi_wait_info.result = 0;
+ ReleaseSemaphore(semaphores[j], 1, NULL);
+
+ result = WaitForSingleObject(semaphore, 100);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ ok(multi_wait_info.result == j, "expected result %d, got %u\n", j, multi_wait_info.result);
+
+ pTpSetWait(waits[j], semaphores[j], NULL);
+ }
+
/* test timeout of wait objects */
multi_wait_info.result = 0;
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
when.QuadPart = (ULONGLONG)50 * -10000;
pTpSetWait(waits[i], semaphores[i], &when);
}
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
result = WaitForSingleObject(semaphore, 150);
ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
@@ -1318,14 +1358,14 @@ static void test_tp_multi_wait(void)
ok(multi_wait_info.result >> 16, "expected multi_wait_info.result >> 16 != 0\n");
/* destroy the wait objects and semaphores while waiting */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
pTpSetWait(waits[i], semaphores[i], NULL);
}
Sleep(50);
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < TP_TEST_SIZE; i++)
{
pTpReleaseWait(waits[i]);
NtClose(semaphores[i]);
--
2.4.6
More information about the wine-devel
mailing list