2020 */
2121
2222#include < lsp-plug.in/test-fw/utest.h>
23+ #include < lsp-plug.in/common/atomic.h>
2324#include < lsp-plug.in/ipc/Thread.h>
2425#include < lsp-plug.in/ipc/Mutex.h>
2526#include < lsp-plug.in/ipc/SharedMutex.h>
@@ -34,6 +35,8 @@ UTEST_BEGIN("runtime.ipc", shmutex)
3435 {
3536 ipc::Mutex lock;
3637 LSPString data;
38+ uatomic_t init_latch;
39+ uatomic_t start_latch;
3740
3841 void log (status_t code, const char *event, status_t expected)
3942 {
@@ -42,7 +45,10 @@ UTEST_BEGIN("runtime.ipc", shmutex)
4245
4346 data.append_ascii (event);
4447 data.append (' =' );
45- data.append_ascii ((code == expected) ? " true" : " false" );
48+ if (code == expected)
49+ data.append_ascii (" true" );
50+ else
51+ data.fmt_append_ascii (" false(code=%d)" , int (code));
4652 data.append (' ;' );
4753 }
4854 } context_t ;
@@ -53,11 +59,15 @@ UTEST_BEGIN("runtime.ipc", shmutex)
5359 ipc::SharedMutex mutex;
5460 context_t *ctx = static_cast <context_t *>(arg);
5561
56- ipc::Thread::sleep (500 );
5762 ctx->log (mutex.open (" test-lsp.lock" ), " open1" , STATUS_OK);
58- ctx->log (mutex.lock (), " SYNC1" , STATUS_OK);
63+ wait_latch (ctx->init_latch , 0 );
64+ atomic_add (&ctx->init_latch , 1 );
65+ wait_latch (ctx->start_latch , 1 );
66+
67+ ipc::Thread::sleep (500 );
68+ ctx->log (mutex.lock (), " SYNC1.lock" , STATUS_OK);
5969 ipc::Thread::sleep (800 );
60- ctx->log (mutex.unlock (), " SYNC2" , STATUS_OK);
70+ ctx->log (mutex.unlock (), " SYNC2.unlock " , STATUS_OK);
6171
6272 return STATUS_OK;
6373 }
@@ -68,23 +78,33 @@ UTEST_BEGIN("runtime.ipc", shmutex)
6878 context_t *ctx = static_cast <context_t *>(arg);
6979
7080 ctx->log (mutex.open (" test-lsp.lock" ), " open2" , STATUS_OK);
81+ wait_latch (ctx->init_latch , 1 );
82+ atomic_add (&ctx->init_latch , 1 );
83+ wait_latch (ctx->start_latch , 1 );
84+
7185 ctx->log (mutex.lock (), " lock2" , STATUS_OK);
7286
7387 ipc::Thread::sleep (500 );
7488
75- ctx->log (mutex.unlock (), " SYNC1" , STATUS_OK);
89+ ctx->log (mutex.unlock (), " SYNC1.unlock " , STATUS_OK);
7690
7791 ipc::Thread::sleep (100 );
7892
7993 ctx->log (mutex.try_lock (), " trylock2" , STATUS_RETRY);
8094 ctx->log (mutex.lock (500 ), " timedlock2" , STATUS_TIMED_OUT);
81- ctx->log (mutex.lock (500 ), " SYNC2" , STATUS_OK);
95+ ctx->log (mutex.lock (500 ), " SYNC2.lock " , STATUS_OK);
8296 ipc::Thread::sleep (200 );
83- ctx->log (mutex.unlock (), " SYNC3" , STATUS_OK);
97+ ctx->log (mutex.unlock (), " SYNC3.unlock " , STATUS_OK);
8498
8599 return STATUS_OK;
86100 }
87101
102+ static void wait_latch (uatomic_t & latch, uatomic_t value)
103+ {
104+ while (atomic_load (&latch) != value)
105+ ipc::Thread::yield ();
106+ }
107+
88108 void test_simple ()
89109 {
90110 ipc::SharedMutex mutex;
@@ -122,6 +142,8 @@ UTEST_BEGIN("runtime.ipc", shmutex)
122142 {
123143 ipc::SharedMutex mutex;
124144 context_t ctx;
145+ atomic_store (&ctx.init_latch , uatomic_t (0 ));
146+ atomic_store (&ctx.start_latch , uatomic_t (0 ));
125147
126148 printf (" Testing simple multi-threaded mutex locks\n " );
127149
@@ -134,6 +156,8 @@ UTEST_BEGIN("runtime.ipc", shmutex)
134156 ctx.log (STATUS_OK, " start" , STATUS_OK);
135157 t1.start ();
136158 t2.start ();
159+ wait_latch (ctx.init_latch , 2 );
160+ atomic_add (&ctx.start_latch , 1 );
137161
138162 ctx.log (STATUS_OK, " sleep" , STATUS_OK);
139163 ipc::Thread::sleep (200 );
@@ -142,16 +166,16 @@ UTEST_BEGIN("runtime.ipc", shmutex)
142166 UTEST_ASSERT (mutex.unlock () == STATUS_OK);
143167
144168 ipc::Thread::sleep (2000 );
145- ctx.log (mutex.lock (), " SYNC3" , STATUS_OK);
169+ ctx.log (mutex.lock (), " SYNC3.lock " , STATUS_OK);
146170 ctx.log (mutex.unlock (), " unlock" , STATUS_OK);
147171
148172 ctx.log (mutex.close (), " close" , STATUS_OK);
149173
150174 static const char *expected =
151- " open=true;lock=true;start=true;sleep =true;open2=true;unlock =true;lock2 =true;open1 =true;"
152- " SYNC1=true;SYNC1=true;trylock2=true;timedlock2=true;"
153- " SYNC2=true;SYNC2=true;"
154- " SYNC3=true;SYNC3=true;unlock=true;close=true;" ;
175+ " open=true;lock=true;start=true;open1 =true;open2=true;sleep =true;unlock =true;lock2 =true;"
176+ " SYNC1.unlock =true;SYNC1.lock =true;trylock2=true;timedlock2=true;"
177+ " SYNC2.unlock =true;SYNC2.lock =true;"
178+ " SYNC3.unlock =true;SYNC3.lock =true;unlock=true;close=true;" ;
155179
156180 printf (" Result content: %s\n " , ctx.data .get_ascii ());
157181 printf (" Expected content: %s\n " , expected);
0 commit comments