[PATCH] msvcp120: implement _Cnd_* functions (try 3)
Piotr Caban
piotr.caban at gmail.com
Thu Nov 12 08:29:58 CST 2015
Hi,
The implementation looks good for me. The tests are over complicated.
I'm attaching a patch generated on top of yours that simplifies them. If
you agree with this changes please just squash both commits and resend.
Thanks,
Piotr
-------------- next part --------------
>From 55ea6332d2df9088bb185d0c9023d1fbf88027a6 Mon Sep 17 00:00:00 2001
From: Piotr Caban <piotr at codeweavers.com>
Date: Thu, 12 Nov 2015 15:23:14 +0100
Subject: [PATCH] _Cnd_* tests cleanup
To: wine-patches <wine-patches at winehq.org>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
---
dlls/msvcp120/tests/msvcp120.c | 152 +++++++++++++----------------------------
1 file changed, 47 insertions(+), 105 deletions(-)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index b05fba4..e69405f 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -1303,66 +1303,38 @@ static void test_thrd(void)
#define NUM_THREADS 10
struct cndmtx
{
+ HANDLE initialized;
+ int started;
+ int thread_no;
+
_Cnd_t cnd;
_Mtx_t mtx;
- int go;
- int started;
+ BOOL timed_wait;
};
-static int __cdecl cnd_broadcast_thread(void *arg)
+static int __cdecl cnd_wait_thread(void *arg)
{
struct cndmtx *cm = arg;
- int done;
int r;
- done = 0;
p__Mtx_lock(&cm->mtx);
- while(!cm->go) {
- if(!done) {
- if(++cm->started == NUM_THREADS) {
- r = p__Cnd_broadcast(&cm->cnd);
- ok(!r, "failed to broadcast\n");
- }
- done = 1;
- }
- r = p__Cnd_wait(&cm->cnd, &cm->mtx);
- ok(!r, "failed to wait\n");
- }
- p__Mtx_unlock(&cm->mtx);
- return 0;
-}
-static int __cdecl cnd_signal_thread(void *arg)
-{
- struct cndmtx *cm = arg;
- int r;
+ if(InterlockedIncrement(&cm->started) == cm->thread_no)
+ SetEvent(cm->initialized);
- p__Mtx_lock(&cm->mtx);
- while(!cm->go) {
- if(!cm->started) {
- cm->started = 1;
- r = p__Cnd_signal(&cm->cnd);
- ok(!r, "failed to signal\n");
- }
+ if(cm->timed_wait) {
+ xtime xt;
+
+ p_xtime_get(&xt, 1);
+ xt.sec += 2;
+ r = p__Cnd_timedwait(&cm->cnd, &cm->mtx, &xt);
+ ok(!r, "timed wait failed\n");
+ } else {
r = p__Cnd_wait(&cm->cnd, &cm->mtx);
- ok(!r, "failed to wait\n");
+ ok(!r, "wait failed\n");
}
- p__Mtx_unlock(&cm->mtx);
- return 0;
-}
-
-static int __cdecl cnd_timedwait_thread(void *arg)
-{
- struct cndmtx *cm = arg;
- int r;
- p__Mtx_lock(&cm->mtx);
- cm->started = 1;
p__Mtx_unlock(&cm->mtx);
- r = p__Cnd_signal(&cm->cnd);
- ok(!r, "failed signal\n");
-
- /* exit without setting go */
return 0;
}
@@ -1392,111 +1364,81 @@ static void test_cnd(void)
}
p__Cnd_destroy(NULL);
- /* test signal */
+ /* test _Cnd_signal/_Cnd_wait */
+ cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
+ cm.started = 0;
+ cm.thread_no = 1;
cm.cnd = cnd;
cm.mtx = mtx;
- cm.go = 0;
- cm.started = 0;
- p__Thrd_create(&threads[0], cnd_signal_thread, (void*)&cm);
+ cm.timed_wait = FALSE;
+ p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
+ WaitForSingleObject(cm.initialized, INFINITE);
p__Mtx_lock(&mtx);
- while(cm.started != 1) {
- r = p__Cnd_wait(&cm.cnd, &cm.mtx);
- ok(!r, "failed to wait\n");
- }
p__Mtx_unlock(&mtx);
- p__Mtx_lock(&cm.mtx);
- cm.go = 1;
- p__Mtx_unlock(&cm.mtx);
r = p__Cnd_signal(&cm.cnd);
ok(!r, "failed to signal\n");
-
p__Thrd_join(threads[0], NULL);
- /* test time out on purpose */
- p_xtime_get(&xt, 1);
- xt.sec += 2;
-
+ /* test _Cnd_timedwait time out */
p__Mtx_lock(&mtx);
p_xtime_get(&before, 1);
+ xt = before;
+ xt.sec += 1;
r = p__Cnd_timedwait(&cnd, &mtx, &xt);
p_xtime_get(&after, 1);
p__Mtx_unlock(&mtx);
diff = p__Xtime_diff_to_millis2(&after, &before);
ok(r == 2, "should have timed out\n");
- ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
+ ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
- /* test timed wait */
- cm.go = 0;
+ /* test _Cnd_timedwait */
cm.started = 0;
- p__Thrd_create(&threads[0], cnd_timedwait_thread, (void*)&cm);
+ cm.timed_wait = TRUE;
+ p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
- /* wait up to 5 seconds for thread to start (should pass) */
- p_xtime_get(&xt, 1);
- xt.sec += 5;
+ WaitForSingleObject(cm.initialized, INFINITE);
p__Mtx_lock(&mtx);
- while(!cm.started) {
- r = p__Cnd_timedwait(&cnd, &mtx, &xt);
- ok(!r, "failed timed wait\n");
- }
p__Mtx_unlock(&mtx);
- /* wait for thread to set go (which it won't, so should time out) */
- p_xtime_get(&xt, 1);
- xt.sec += 1;
- r = 0;
- p__Mtx_lock(&mtx);
- while(!r && !cm.go) {
- r = p__Cnd_timedwait(&cnd, &mtx, &xt);
- ok(r == 2, "timed wait did not timeout: %d\n", r);
- }
- p__Mtx_unlock(&mtx);
+ r = p__Cnd_signal(&cm.cnd);
+ ok(!r, "failed to signal\n");
p__Thrd_join(threads[0], NULL);
- /* test broadcast with _Cnd_broadcast */
- cm.go = 0;
+ /* test _Cnd_broadcast */
cm.started = 0;
- for(i = 0; i < NUM_THREADS; i++)
- p__Thrd_create(&threads[i], cnd_broadcast_thread, (void*)&cm);
+ cm.thread_no = NUM_THREADS;
+ cm.timed_wait = FALSE;
- p__Mtx_lock(&mtx);
- while(cm.started != NUM_THREADS) {
- r = p__Cnd_wait(&cm.cnd, &cm.mtx);
- ok(!r, "failed to wait\n");
- }
- p__Mtx_unlock(&mtx);
+ for(i = 0; i < cm.thread_no; i++)
+ p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
+ WaitForSingleObject(cm.initialized, INFINITE);
p__Mtx_lock(&mtx);
- cm.go = 1;
p__Mtx_unlock(&mtx);
+
r = p__Cnd_broadcast(&cnd);
ok(!r, "failed to broadcast\n");
- for(i = 0; i < NUM_THREADS; i++)
+ for(i = 0; i < cm.thread_no; i++)
p__Thrd_join(threads[i], NULL);
/* test broadcast with _Cnd_destroy */
- cm.go = 0;
cm.started = 0;
- for(i = 0; i < NUM_THREADS; i++)
- p__Thrd_create(&threads[i], cnd_broadcast_thread, (void*)&cm);
+ for(i = 0; i < cm.thread_no; i++)
+ p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
+ WaitForSingleObject(cm.initialized, INFINITE);
p__Mtx_lock(&mtx);
- while(cm.started != NUM_THREADS) {
- r = p__Cnd_wait(&cm.cnd, &cm.mtx);
- ok(!r, "failed to wait\n");
- }
p__Mtx_unlock(&mtx);
- p__Mtx_lock(&mtx);
- cm.go = 1;
- p__Mtx_unlock(&mtx);
p__Cnd_destroy(&cnd);
- for(i = 0; i < NUM_THREADS; i++)
+ for(i = 0; i < cm.thread_no; i++)
p__Thrd_join(threads[i], NULL);
p__Mtx_destroy(&mtx);
+ CloseHandle(cm.initialized);
}
START_TEST(msvcp120)
--
2.4.10
More information about the wine-devel
mailing list