mutex_tc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09.01 luckyzjq the first version
  9. * 2023-09-15 xqyjlj change stack size in cpu64
  10. */
  11. /**
  12. * Test Case Name: RT-Thread Mutex Functional and Scheduling Validation
  13. * Test Objectives:
  14. * - Verify correctness of static and dynamic mutex operations
  15. * - Validate priority inheritance, recursive locking, timeout handling, and error cases
  16. * - Test core mutex APIs: rt_mutex_init/detach, rt_mutex_create/delete,
  17. * rt_mutex_take/trytake/release, and related thread scheduling functions
  18. * Test Scenarios:
  19. * - Mutex acquisition under contention with multi-thread scheduling
  20. * - Try-take on locked mutex, timeout-based take, recursive take sequence
  21. * - Priority inheritance when high-priority threads are blocked by lower-priority holders
  22. * - Behavior differences between static and dynamic mutexes
  23. * - Mutex release error handling, invalid release, and cleanup
  24. * Verification Metrics:
  25. * - Correct return codes for all mutex operations (RT_EOK, timeouts, error states)
  26. * - Proper priority inheritance and restoration during contention
  27. * - Expected thread wake-up and state transition behavior
  28. * - Successful thread synchronization via _sync_flag
  29. * Dependencies:
  30. * - RT-Thread kernel with IPC and mutex support enabled
  31. * - Heap availability when testing dynamic mutex creation
  32. * - Scheduler operating normally with multi-thread preemption
  33. * - Accurate system tick for timeout and delay validation
  34. * Expected Results:
  35. * - All mutex APIs behave according to RT-Thread specifications
  36. * - Static and dynamic mutex tests complete successfully
  37. * - Priority inversion resolved via priority inheritance
  38. * - Console/log output indicates all UTEST cases pass
  39. */
  40. #define __RT_IPC_SOURCE__
  41. #include <rtthread.h>
  42. #include <stdlib.h>
  43. #include "utest.h"
  44. #ifdef ARCH_CPU_64BIT
  45. #define THREAD_STACKSIZE 8192
  46. #else
  47. #define THREAD_STACKSIZE 4096
  48. #endif
  49. static struct rt_mutex static_mutex;
  50. #ifdef RT_USING_HEAP
  51. static rt_mutex_t dynamic_mutex;
  52. #endif /* RT_USING_HEAP */
  53. static volatile int _sync_flag;
  54. /* init test */
  55. static void test_static_mutex_init(void)
  56. {
  57. rt_err_t result = -RT_ERROR;
  58. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  59. if (RT_EOK != result)
  60. {
  61. uassert_true(RT_FALSE);
  62. }
  63. result = rt_mutex_detach(&static_mutex);
  64. if (RT_EOK != result)
  65. {
  66. uassert_true(RT_FALSE);
  67. }
  68. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  69. if (RT_EOK != result)
  70. {
  71. uassert_true(RT_FALSE);
  72. }
  73. result = rt_mutex_detach(&static_mutex);
  74. if (RT_EOK != result)
  75. {
  76. uassert_true(RT_FALSE);
  77. }
  78. uassert_true(RT_TRUE);
  79. }
  80. /* static take test */
  81. static void static_mutex_take_entry(void *param)
  82. {
  83. rt_err_t result;
  84. rt_mutex_t mutex;
  85. int rand_num = rand() % 0x1000;
  86. mutex = (rt_mutex_t)param;
  87. result = rt_mutex_take(mutex, rand_num);
  88. if (RT_EOK == result)
  89. {
  90. uassert_true(RT_FALSE);
  91. }
  92. _sync_flag++;
  93. }
  94. static void test_static_mutex_take(void)
  95. {
  96. rt_err_t result;
  97. _sync_flag = 0;
  98. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  99. if (RT_EOK != result)
  100. {
  101. uassert_true(RT_FALSE);
  102. return;
  103. }
  104. /* take mutex and not release */
  105. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  106. if (RT_EOK != result)
  107. uassert_true(RT_FALSE);
  108. rt_thread_t tid = rt_thread_create("mutex_th",
  109. static_mutex_take_entry,
  110. &static_mutex,
  111. THREAD_STACKSIZE,
  112. 10,
  113. 10);
  114. if (RT_NULL == tid)
  115. {
  116. uassert_true(RT_FALSE);
  117. return;
  118. }
  119. /* startup thread take second */
  120. rt_thread_startup(tid);
  121. while (_sync_flag != 1)
  122. {
  123. rt_thread_mdelay(10);
  124. }
  125. result = rt_mutex_detach(&static_mutex);
  126. if (RT_EOK != result)
  127. uassert_true(RT_FALSE);
  128. uassert_true(RT_TRUE);
  129. }
  130. /* static release test */
  131. static void static_mutex_release_entry(void *param)
  132. {
  133. rt_err_t result;
  134. rt_mutex_t mutex;
  135. int rand_num = rand() % 0x1000;
  136. mutex = (rt_mutex_t)param;
  137. result = rt_mutex_take(mutex, rand_num);
  138. if (RT_EOK != result)
  139. {
  140. uassert_true(RT_FALSE);
  141. }
  142. _sync_flag++;
  143. }
  144. static void test_static_mutex_release(void)
  145. {
  146. rt_err_t result;
  147. _sync_flag = 0;
  148. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  149. if (RT_EOK != result)
  150. {
  151. uassert_true(RT_FALSE);
  152. return;
  153. }
  154. result = rt_mutex_release(&static_mutex);
  155. uassert_true(result < 0);
  156. /* take mutex */
  157. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  158. if (RT_EOK != result)
  159. uassert_true(RT_FALSE);
  160. /* release mutex */
  161. result = rt_mutex_release(&static_mutex);
  162. if (RT_EOK != result)
  163. uassert_true(RT_FALSE);
  164. rt_thread_t tid = rt_thread_create("mutex_th",
  165. static_mutex_release_entry,
  166. &static_mutex,
  167. THREAD_STACKSIZE,
  168. 10,
  169. 10);
  170. if (RT_NULL == tid)
  171. {
  172. uassert_true(RT_FALSE);
  173. return;
  174. }
  175. /* startup thread and take mutex second */
  176. rt_thread_startup(tid);
  177. while (_sync_flag != 1)
  178. {
  179. rt_thread_mdelay(10);
  180. }
  181. result = rt_mutex_detach(&static_mutex);
  182. if (RT_EOK != result)
  183. uassert_true(RT_FALSE);
  184. uassert_true(RT_TRUE);
  185. }
  186. /* static trytake test */
  187. static void static_mutex_trytake_entry(void *param)
  188. {
  189. rt_err_t result;
  190. rt_mutex_t mutex;
  191. mutex = (rt_mutex_t)param;
  192. result = rt_mutex_trytake(mutex);
  193. if (RT_EOK == result)
  194. {
  195. uassert_true(RT_FALSE);
  196. }
  197. _sync_flag++;
  198. }
  199. static void test_static_mutex_trytake(void)
  200. {
  201. rt_err_t result;
  202. _sync_flag = 0;
  203. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  204. if (RT_EOK != result)
  205. {
  206. uassert_true(RT_FALSE);
  207. return;
  208. }
  209. /* take mutex and not release */
  210. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  211. if (RT_EOK != result)
  212. uassert_true(RT_FALSE);
  213. rt_thread_t tid = rt_thread_create("mutex_th",
  214. static_mutex_trytake_entry,
  215. &static_mutex,
  216. THREAD_STACKSIZE,
  217. 10,
  218. 10);
  219. if (RT_NULL == tid)
  220. {
  221. uassert_true(RT_FALSE);
  222. return;
  223. }
  224. /* startup thread and trytake mutex second */
  225. rt_thread_startup(tid);
  226. while (_sync_flag != 1)
  227. {
  228. rt_thread_mdelay(10);
  229. }
  230. result = rt_mutex_detach(&static_mutex);
  231. if (RT_EOK != result)
  232. uassert_true(RT_FALSE);
  233. uassert_true(RT_TRUE);
  234. }
  235. static rt_thread_t tid1 = RT_NULL;
  236. static rt_thread_t tid2 = RT_NULL;
  237. static rt_thread_t tid3 = RT_NULL;
  238. /* static mutex priority reverse test */
  239. static void static_thread1_entry(void *param)
  240. {
  241. /* let system schedule */
  242. rt_thread_mdelay(100);
  243. /* thread3 hode mutex thread2 take mutex */
  244. /* check thread2 and thread3 priority */
  245. if (RT_SCHED_PRIV(tid2).current_priority != RT_SCHED_PRIV(tid3).current_priority)
  246. {
  247. uassert_true(RT_FALSE);
  248. }
  249. else
  250. {
  251. uassert_true(RT_TRUE);
  252. }
  253. _sync_flag++;
  254. }
  255. static void static_thread2_entry(void *param)
  256. {
  257. rt_err_t result;
  258. rt_mutex_t mutex = (rt_mutex_t)param;
  259. /* let system schedule */
  260. rt_thread_mdelay(50);
  261. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  262. if (result == RT_EOK)
  263. {
  264. rt_mutex_release(mutex);
  265. }
  266. _sync_flag++;
  267. }
  268. static void static_thread3_entry(void *param)
  269. {
  270. rt_tick_t tick;
  271. rt_err_t result;
  272. rt_mutex_t mutex = (rt_mutex_t)param;
  273. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  274. if (result != RT_EOK)
  275. {
  276. uassert_true(RT_FALSE);
  277. }
  278. tick = rt_tick_get();
  279. while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
  280. rt_mutex_release(mutex);
  281. _sync_flag++;
  282. }
  283. static void test_static_pri_reverse(void)
  284. {
  285. rt_err_t result;
  286. tid1 = RT_NULL;
  287. tid2 = RT_NULL;
  288. tid3 = RT_NULL;
  289. _sync_flag = 0;
  290. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  291. if (RT_EOK != result)
  292. {
  293. uassert_true(RT_FALSE);
  294. return;
  295. }
  296. /* thread1 */
  297. tid1 = rt_thread_create("thread1",
  298. static_thread1_entry,
  299. &static_mutex,
  300. UTEST_THR_STACK_SIZE,
  301. 10 - 1,
  302. 10);
  303. if (tid1 != RT_NULL)
  304. rt_thread_startup(tid1);
  305. /* thread2 */
  306. tid2 = rt_thread_create("thread2",
  307. static_thread2_entry,
  308. &static_mutex,
  309. UTEST_THR_STACK_SIZE,
  310. 10,
  311. 10);
  312. if (tid2 != RT_NULL)
  313. rt_thread_startup(tid2);
  314. /* thread3 */
  315. tid3 = rt_thread_create("thread3",
  316. static_thread3_entry,
  317. &static_mutex,
  318. UTEST_THR_STACK_SIZE,
  319. 10 + 1,
  320. 10);
  321. if (tid3 != RT_NULL)
  322. rt_thread_startup(tid3);
  323. while (_sync_flag != 3)
  324. {
  325. rt_thread_mdelay(10);
  326. }
  327. result = rt_mutex_detach(&static_mutex);
  328. if (RT_EOK != result)
  329. uassert_true(RT_FALSE);
  330. uassert_true(RT_TRUE);
  331. }
  332. /* create test */
  333. static void test_dynamic_mutex_create(void)
  334. {
  335. rt_err_t result = -RT_ERROR;
  336. /* PRIO mode */
  337. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  338. if (RT_NULL == dynamic_mutex)
  339. {
  340. uassert_true(RT_FALSE);
  341. }
  342. result = rt_mutex_delete(dynamic_mutex);
  343. if (RT_EOK != result)
  344. {
  345. uassert_true(RT_FALSE);
  346. }
  347. /* FIFO mode */
  348. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  349. if (RT_NULL == dynamic_mutex)
  350. {
  351. uassert_true(RT_FALSE);
  352. }
  353. result = rt_mutex_delete(dynamic_mutex);
  354. if (RT_EOK != result)
  355. {
  356. uassert_true(RT_FALSE);
  357. }
  358. uassert_true(RT_TRUE);
  359. }
  360. /* dynamic take test */
  361. static void dynamic_mutex_take_entry(void *param)
  362. {
  363. rt_err_t result;
  364. rt_mutex_t mutex;
  365. int rand_num = rand() % 0x1000;
  366. mutex = (rt_mutex_t)param;
  367. result = rt_mutex_take(mutex, rand_num);
  368. if (RT_EOK == result)
  369. {
  370. uassert_true(RT_FALSE);
  371. }
  372. _sync_flag++;
  373. }
  374. static void test_dynamic_mutex_take(void)
  375. {
  376. rt_err_t result;
  377. _sync_flag = 0;
  378. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  379. if (RT_NULL == dynamic_mutex)
  380. {
  381. uassert_true(RT_FALSE);
  382. return;
  383. }
  384. /* take mutex and not release */
  385. result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
  386. if (RT_EOK != result)
  387. uassert_true(RT_FALSE);
  388. rt_thread_t tid = rt_thread_create("mutex_th",
  389. dynamic_mutex_take_entry,
  390. dynamic_mutex,
  391. THREAD_STACKSIZE,
  392. 10,
  393. 10);
  394. if (RT_NULL == tid)
  395. {
  396. uassert_true(RT_FALSE);
  397. return;
  398. }
  399. /* startup thread take second */
  400. rt_thread_startup(tid);
  401. while (_sync_flag != 1)
  402. {
  403. rt_thread_mdelay(10);
  404. }
  405. result = rt_mutex_delete(dynamic_mutex);
  406. if (RT_EOK != result)
  407. uassert_true(RT_FALSE);
  408. uassert_true(RT_TRUE);
  409. }
  410. /* dynamic release test */
  411. static void dynamic_mutex_release_entry(void *param)
  412. {
  413. rt_err_t result;
  414. rt_mutex_t mutex;
  415. int rand_num = rand() % 0x1000;
  416. mutex = (rt_mutex_t)param;
  417. result = rt_mutex_take(mutex, rand_num);
  418. if (RT_EOK != result)
  419. {
  420. uassert_true(RT_FALSE);
  421. }
  422. _sync_flag++;
  423. }
  424. static void test_dynamic_mutex_release(void)
  425. {
  426. rt_err_t result;
  427. _sync_flag = 0;
  428. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  429. if (RT_NULL == dynamic_mutex)
  430. {
  431. uassert_true(RT_FALSE);
  432. return;
  433. }
  434. result = rt_mutex_release(dynamic_mutex);
  435. uassert_true(result < 0);
  436. /* take mutex */
  437. result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
  438. if (RT_EOK != result)
  439. uassert_true(RT_FALSE);
  440. /* release mutex */
  441. result = rt_mutex_release(dynamic_mutex);
  442. if (RT_EOK != result)
  443. uassert_true(RT_FALSE);
  444. rt_thread_t tid = rt_thread_create("mutex_th",
  445. dynamic_mutex_release_entry,
  446. dynamic_mutex,
  447. THREAD_STACKSIZE,
  448. 10,
  449. 10);
  450. if (RT_NULL == tid)
  451. {
  452. uassert_true(RT_FALSE);
  453. return;
  454. }
  455. /* startup thread and take mutex second */
  456. rt_thread_startup(tid);
  457. while (_sync_flag != 1)
  458. {
  459. rt_thread_mdelay(10);
  460. }
  461. result = rt_mutex_delete(dynamic_mutex);
  462. if (RT_EOK != result)
  463. uassert_true(RT_FALSE);
  464. uassert_true(RT_TRUE);
  465. }
  466. /* dynamic trytake test */
  467. static void dynamic_mutex_trytake_entry(void *param)
  468. {
  469. rt_err_t result;
  470. rt_mutex_t mutex;
  471. mutex = (rt_mutex_t)param;
  472. result = rt_mutex_trytake(mutex);
  473. if (RT_EOK == result)
  474. {
  475. uassert_true(RT_FALSE);
  476. }
  477. _sync_flag++;
  478. }
  479. static void test_dynamic_mutex_trytake(void)
  480. {
  481. rt_err_t result;
  482. _sync_flag = 0;
  483. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  484. if (RT_NULL == dynamic_mutex)
  485. {
  486. uassert_true(RT_FALSE);
  487. return;
  488. }
  489. /* take mutex and not release */
  490. result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
  491. if (RT_EOK != result)
  492. uassert_true(RT_FALSE);
  493. rt_thread_t tid = rt_thread_create("mutex_th",
  494. dynamic_mutex_trytake_entry,
  495. dynamic_mutex,
  496. THREAD_STACKSIZE,
  497. 10,
  498. 10);
  499. if (RT_NULL == tid)
  500. {
  501. uassert_true(RT_FALSE);
  502. return;
  503. }
  504. /* startup thread and trytake mutex second */
  505. rt_thread_startup(tid);
  506. while (_sync_flag != 1)
  507. {
  508. rt_thread_mdelay(10);
  509. }
  510. result = rt_mutex_delete(dynamic_mutex);
  511. if (RT_EOK != result)
  512. uassert_true(RT_FALSE);
  513. uassert_true(RT_TRUE);
  514. }
  515. /* dynamic mutex priority reverse test */
  516. static void dynamic_thread1_entry(void *param)
  517. {
  518. /* let system schedule */
  519. rt_thread_mdelay(100);
  520. /* thread3 hode mutex thread2 take mutex */
  521. /* check thread2 and thread3 priority */
  522. if (RT_SCHED_PRIV(tid2).current_priority != RT_SCHED_PRIV(tid3).current_priority)
  523. {
  524. uassert_true(RT_FALSE);
  525. }
  526. else
  527. {
  528. uassert_true(RT_TRUE);
  529. }
  530. _sync_flag++;
  531. }
  532. static void dynamic_thread2_entry(void *param)
  533. {
  534. rt_err_t result;
  535. rt_mutex_t mutex = (rt_mutex_t)param;
  536. /* let system schedule */
  537. rt_thread_mdelay(50);
  538. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  539. if (result == RT_EOK)
  540. {
  541. rt_mutex_release(mutex);
  542. }
  543. _sync_flag++;
  544. }
  545. static void dynamic_thread3_entry(void *param)
  546. {
  547. rt_tick_t tick;
  548. rt_err_t result;
  549. rt_mutex_t mutex = (rt_mutex_t)param;
  550. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  551. if (result != RT_EOK)
  552. {
  553. uassert_true(RT_FALSE);
  554. }
  555. tick = rt_tick_get();
  556. while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
  557. rt_mutex_release(mutex);
  558. _sync_flag++;
  559. }
  560. static void test_dynamic_pri_reverse(void)
  561. {
  562. rt_err_t result;
  563. tid1 = RT_NULL;
  564. tid2 = RT_NULL;
  565. tid3 = RT_NULL;
  566. _sync_flag = 0;
  567. dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
  568. if (RT_NULL == dynamic_mutex)
  569. {
  570. uassert_true(RT_FALSE);
  571. return;
  572. }
  573. /* thread1 */
  574. tid1 = rt_thread_create("thread1",
  575. dynamic_thread1_entry,
  576. dynamic_mutex,
  577. UTEST_THR_STACK_SIZE,
  578. 10 - 1,
  579. 10);
  580. if (tid1 != RT_NULL)
  581. rt_thread_startup(tid1);
  582. /* thread2 */
  583. tid2 = rt_thread_create("thread2",
  584. dynamic_thread2_entry,
  585. dynamic_mutex,
  586. UTEST_THR_STACK_SIZE,
  587. 10,
  588. 10);
  589. if (tid2 != RT_NULL)
  590. rt_thread_startup(tid2);
  591. /* thread3 */
  592. tid3 = rt_thread_create("thread3",
  593. dynamic_thread3_entry,
  594. dynamic_mutex,
  595. UTEST_THR_STACK_SIZE,
  596. 10 + 1,
  597. 10);
  598. if (tid3 != RT_NULL)
  599. rt_thread_startup(tid3);
  600. while (_sync_flag != 3)
  601. {
  602. rt_thread_mdelay(10);
  603. }
  604. result = rt_mutex_delete(dynamic_mutex);
  605. if (RT_EOK != result)
  606. uassert_true(RT_FALSE);
  607. uassert_true(RT_TRUE);
  608. }
  609. static void recursive_lock_test_entry(void *param)
  610. {
  611. rt_err_t result;
  612. rt_mutex_t mutex = (rt_mutex_t)param;
  613. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  614. uassert_true(result == RT_EOK);
  615. uassert_true(_sync_flag == 0);
  616. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  617. uassert_true(result == RT_EOK);
  618. _sync_flag++;
  619. }
  620. static void test_recurse_lock(void)
  621. {
  622. rt_err_t result;
  623. _sync_flag = 0;
  624. result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
  625. uassert_true(result == RT_EOK);
  626. /* take mutex and not release */
  627. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  628. uassert_true(result == RT_EOK);
  629. /* take mutex twice */
  630. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  631. uassert_true(result == RT_EOK);
  632. rt_thread_t tid = rt_thread_create("mutex_th",
  633. recursive_lock_test_entry,
  634. &static_mutex,
  635. THREAD_STACKSIZE,
  636. 10,
  637. 10);
  638. _sync_flag = -1;
  639. if (tid != RT_NULL)
  640. rt_thread_startup(tid);
  641. result = rt_mutex_release(&static_mutex);
  642. uassert_true(result == RT_EOK);
  643. _sync_flag = 0;
  644. result = rt_mutex_release(&static_mutex);
  645. uassert_true(result == RT_EOK);
  646. while (_sync_flag != 1)
  647. {
  648. rt_thread_mdelay(10);
  649. }
  650. result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
  651. uassert_true(result == RT_EOK);
  652. result = rt_mutex_detach(&static_mutex);
  653. uassert_true(result == RT_EOK);
  654. }
  655. static rt_err_t utest_tc_init(void)
  656. {
  657. #ifdef RT_USING_HEAP
  658. dynamic_mutex = RT_NULL;
  659. #endif /* RT_USING_HEAP */
  660. return RT_EOK;
  661. }
  662. static rt_err_t utest_tc_cleanup(void)
  663. {
  664. #ifdef RT_USING_HEAP
  665. dynamic_mutex = RT_NULL;
  666. #endif /* RT_USING_HEAP */
  667. return RT_EOK;
  668. }
  669. static void testcase(void)
  670. {
  671. UTEST_UNIT_RUN(test_static_mutex_init);
  672. UTEST_UNIT_RUN(test_static_mutex_take);
  673. UTEST_UNIT_RUN(test_static_mutex_release);
  674. UTEST_UNIT_RUN(test_static_mutex_trytake);
  675. UTEST_UNIT_RUN(test_static_pri_reverse);
  676. #ifdef RT_USING_HEAP
  677. UTEST_UNIT_RUN(test_dynamic_mutex_create);
  678. UTEST_UNIT_RUN(test_dynamic_mutex_take);
  679. UTEST_UNIT_RUN(test_dynamic_mutex_release);
  680. UTEST_UNIT_RUN(test_dynamic_mutex_trytake);
  681. UTEST_UNIT_RUN(test_dynamic_pri_reverse);
  682. #endif
  683. UTEST_UNIT_RUN(test_recurse_lock);
  684. }
  685. UTEST_TC_EXPORT(testcase, "core.mutex", utest_tc_init, utest_tc_cleanup, 1000);
  686. /********************* end of file ************************/