Skip to content

Commit de398b4

Browse files
committed
fix race in mutex tc & add recurse lock tc
1 parent 9a84c13 commit de398b4

File tree

1 file changed

+128
-14
lines changed

1 file changed

+128
-14
lines changed

examples/utest/testcases/kernel/mutex_tc.c

+128-14
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ static struct rt_mutex static_mutex;
2626
static rt_mutex_t dynamic_mutex;
2727
#endif /* RT_USING_HEAP */
2828

29+
static volatile int _sync_flag;
30+
2931
/* init test */
3032
static void test_static_mutex_init(void)
3133
{
@@ -72,11 +74,15 @@ static void static_mutex_take_entry(void *param)
7274
{
7375
uassert_true(RT_FALSE);
7476
}
77+
_sync_flag++;
7578
}
79+
7680
static void test_static_mutex_take(void)
7781
{
7882
rt_err_t result;
7983

84+
_sync_flag = 0;
85+
8086
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
8187
if (RT_EOK != result)
8288
{
@@ -104,8 +110,10 @@ static void test_static_mutex_take(void)
104110
/* startup thread take second */
105111
rt_thread_startup(tid);
106112

107-
/* let system schedule */
108-
rt_thread_mdelay(5);
113+
while (_sync_flag != 1)
114+
{
115+
rt_thread_mdelay(10);
116+
}
109117

110118
result = rt_mutex_detach(&static_mutex);
111119
if (RT_EOK != result)
@@ -128,18 +136,24 @@ static void static_mutex_release_entry(void *param)
128136
{
129137
uassert_true(RT_FALSE);
130138
}
139+
_sync_flag++;
131140
}
132141
static void test_static_mutex_release(void)
133142
{
134143
rt_err_t result;
135144

145+
_sync_flag = 0;
146+
136147
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
137148
if (RT_EOK != result)
138149
{
139150
uassert_true(RT_FALSE);
140151
return;
141152
}
142153

154+
result = rt_mutex_release(&static_mutex);
155+
uassert_true(result < 0);
156+
143157
/* take mutex */
144158
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
145159
if (RT_EOK != result)
@@ -165,8 +179,10 @@ static void test_static_mutex_release(void)
165179
/* startup thread and take mutex second */
166180
rt_thread_startup(tid);
167181

168-
/* let system schedule */
169-
rt_thread_mdelay(5);
182+
while (_sync_flag != 1)
183+
{
184+
rt_thread_mdelay(10);
185+
}
170186

171187
result = rt_mutex_detach(&static_mutex);
172188
if (RT_EOK != result)
@@ -188,11 +204,14 @@ static void static_mutex_trytake_entry(void *param)
188204
{
189205
uassert_true(RT_FALSE);
190206
}
207+
_sync_flag++;
191208
}
192209
static void test_static_mutex_trytake(void)
193210
{
194211
rt_err_t result;
195212

213+
_sync_flag = 0;
214+
196215
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
197216
if (RT_EOK != result)
198217
{
@@ -220,8 +239,10 @@ static void test_static_mutex_trytake(void)
220239
/* startup thread and trytake mutex second */
221240
rt_thread_startup(tid);
222241

223-
/* let system schedule */
224-
rt_thread_mdelay(5);
242+
while (_sync_flag != 1)
243+
{
244+
rt_thread_mdelay(10);
245+
}
225246

226247
result = rt_mutex_detach(&static_mutex);
227248
if (RT_EOK != result)
@@ -250,6 +271,7 @@ static void static_thread1_entry(void *param)
250271
{
251272
uassert_true(RT_TRUE);
252273
}
274+
_sync_flag++;
253275
}
254276

255277
static void static_thread2_entry(void *param)
@@ -265,6 +287,7 @@ static void static_thread2_entry(void *param)
265287
{
266288
rt_mutex_release(mutex);
267289
}
290+
_sync_flag++;
268291
}
269292
static void static_thread3_entry(void *param)
270293
{
@@ -282,6 +305,7 @@ static void static_thread3_entry(void *param)
282305
while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
283306

284307
rt_mutex_release(mutex);
308+
_sync_flag++;
285309
}
286310

287311
static void test_static_pri_reverse(void)
@@ -291,6 +315,8 @@ static void test_static_pri_reverse(void)
291315
tid2 = RT_NULL;
292316
tid3 = RT_NULL;
293317

318+
_sync_flag = 0;
319+
294320
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
295321
if (RT_EOK != result)
296322
{
@@ -328,7 +354,10 @@ static void test_static_pri_reverse(void)
328354
if (tid3 != RT_NULL)
329355
rt_thread_startup(tid3);
330356

331-
rt_thread_mdelay(1000);
357+
while (_sync_flag != 3)
358+
{
359+
rt_thread_mdelay(10);
360+
}
332361

333362
result = rt_mutex_detach(&static_mutex);
334363
if (RT_EOK != result)
@@ -385,11 +414,15 @@ static void dynamic_mutex_take_entry(void *param)
385414
{
386415
uassert_true(RT_FALSE);
387416
}
417+
_sync_flag++;
388418
}
419+
389420
static void test_dynamic_mutex_take(void)
390421
{
391422
rt_err_t result;
392423

424+
_sync_flag = 0;
425+
393426
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
394427
if (RT_NULL == dynamic_mutex)
395428
{
@@ -417,8 +450,10 @@ static void test_dynamic_mutex_take(void)
417450
/* startup thread take second */
418451
rt_thread_startup(tid);
419452

420-
/* let system schedule */
421-
rt_thread_mdelay(5);
453+
while (_sync_flag != 1)
454+
{
455+
rt_thread_mdelay(10);
456+
}
422457

423458
result = rt_mutex_delete(dynamic_mutex);
424459
if (RT_EOK != result)
@@ -441,18 +476,23 @@ static void dynamic_mutex_release_entry(void *param)
441476
{
442477
uassert_true(RT_FALSE);
443478
}
479+
_sync_flag++;
444480
}
445481
static void test_dynamic_mutex_release(void)
446482
{
447483
rt_err_t result;
448484

485+
_sync_flag = 0;
449486
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
450487
if (RT_NULL == dynamic_mutex)
451488
{
452489
uassert_true(RT_FALSE);
453490
return;
454491
}
455492

493+
result = rt_mutex_release(dynamic_mutex);
494+
uassert_true(result < 0);
495+
456496
/* take mutex */
457497
result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
458498
if (RT_EOK != result)
@@ -478,8 +518,10 @@ static void test_dynamic_mutex_release(void)
478518
/* startup thread and take mutex second */
479519
rt_thread_startup(tid);
480520

481-
/* let system schedule */
482-
rt_thread_mdelay(5);
521+
while (_sync_flag != 1)
522+
{
523+
rt_thread_mdelay(10);
524+
}
483525

484526
result = rt_mutex_delete(dynamic_mutex);
485527
if (RT_EOK != result)
@@ -501,11 +543,13 @@ static void dynamic_mutex_trytake_entry(void *param)
501543
{
502544
uassert_true(RT_FALSE);
503545
}
546+
_sync_flag++;
504547
}
505548
static void test_dynamic_mutex_trytake(void)
506549
{
507550
rt_err_t result;
508551

552+
_sync_flag = 0;
509553
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
510554
if (RT_NULL == dynamic_mutex)
511555
{
@@ -533,8 +577,10 @@ static void test_dynamic_mutex_trytake(void)
533577
/* startup thread and trytake mutex second */
534578
rt_thread_startup(tid);
535579

536-
/* let system schedule */
537-
rt_thread_mdelay(5);
580+
while (_sync_flag != 1)
581+
{
582+
rt_thread_mdelay(10);
583+
}
538584

539585
result = rt_mutex_delete(dynamic_mutex);
540586
if (RT_EOK != result)
@@ -559,6 +605,7 @@ static void dynamic_thread1_entry(void *param)
559605
{
560606
uassert_true(RT_TRUE);
561607
}
608+
_sync_flag++;
562609
}
563610

564611
static void dynamic_thread2_entry(void *param)
@@ -574,6 +621,7 @@ static void dynamic_thread2_entry(void *param)
574621
{
575622
rt_mutex_release(mutex);
576623
}
624+
_sync_flag++;
577625
}
578626
static void dynamic_thread3_entry(void *param)
579627
{
@@ -591,6 +639,7 @@ static void dynamic_thread3_entry(void *param)
591639
while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
592640

593641
rt_mutex_release(mutex);
642+
_sync_flag++;
594643
}
595644

596645
static void test_dynamic_pri_reverse(void)
@@ -600,6 +649,7 @@ static void test_dynamic_pri_reverse(void)
600649
tid2 = RT_NULL;
601650
tid3 = RT_NULL;
602651

652+
_sync_flag = 0;
603653
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
604654
if (RT_NULL == dynamic_mutex)
605655
{
@@ -637,7 +687,10 @@ static void test_dynamic_pri_reverse(void)
637687
if (tid3 != RT_NULL)
638688
rt_thread_startup(tid3);
639689

640-
rt_thread_mdelay(1000);
690+
while (_sync_flag != 3)
691+
{
692+
rt_thread_mdelay(10);
693+
}
641694

642695
result = rt_mutex_delete(dynamic_mutex);
643696
if (RT_EOK != result)
@@ -646,6 +699,66 @@ static void test_dynamic_pri_reverse(void)
646699
uassert_true(RT_TRUE);
647700
}
648701

702+
static void recursive_lock_test_entry(void *param)
703+
{
704+
rt_err_t result;
705+
rt_mutex_t mutex = (rt_mutex_t)param;
706+
707+
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
708+
uassert_true(result == RT_EOK);
709+
uassert_true(_sync_flag == 0);
710+
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
711+
uassert_true(result == RT_EOK);
712+
_sync_flag++;
713+
}
714+
715+
static void test_recurse_lock(void)
716+
{
717+
rt_err_t result;
718+
719+
_sync_flag = 0;
720+
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
721+
uassert_true(result == RT_EOK);
722+
723+
/* take mutex and not release */
724+
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
725+
uassert_true(result == RT_EOK);
726+
727+
/* take mutex twice */
728+
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
729+
uassert_true(result == RT_EOK);
730+
731+
rt_thread_t tid = rt_thread_create("mutex_th",
732+
recursive_lock_test_entry,
733+
&static_mutex,
734+
THREAD_STACKSIZE,
735+
10,
736+
10);
737+
_sync_flag = -1;
738+
739+
if (tid != RT_NULL)
740+
rt_thread_startup(tid);
741+
742+
result = rt_mutex_release(&static_mutex);
743+
uassert_true(result == RT_EOK);
744+
745+
_sync_flag = 0;
746+
747+
result = rt_mutex_release(&static_mutex);
748+
uassert_true(result == RT_EOK);
749+
750+
while (_sync_flag != 1)
751+
{
752+
rt_thread_mdelay(10);
753+
}
754+
755+
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
756+
uassert_true(result == RT_EOK);
757+
758+
result = rt_mutex_detach(&static_mutex);
759+
uassert_true(result == RT_EOK);
760+
}
761+
649762
static rt_err_t utest_tc_init(void)
650763
{
651764
#ifdef RT_USING_HEAP
@@ -678,6 +791,7 @@ static void testcase(void)
678791
UTEST_UNIT_RUN(test_dynamic_mutex_trytake);
679792
UTEST_UNIT_RUN(test_dynamic_pri_reverse);
680793
#endif
794+
UTEST_UNIT_RUN(test_recurse_lock);
681795
}
682796
UTEST_TC_EXPORT(testcase, "testcases.kernel.mutex_tc", utest_tc_init, utest_tc_cleanup, 1000);
683797

0 commit comments

Comments
 (0)