mutex_priority.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. *
  8. */
  9. /*
  10. * 创建7个进程,tid20、tid21、tid22、tid23、tid24、tid25、tid26、tid27、tid28、tid29
  11. * 各任务优先级分别为20、21、22、23、24、25、26、27、28、29,
  12. * 其中tid26最先获得锁,tid22不需要使用到互斥锁,其他所有进程均需要使用互斥锁,
  13. * 通过各个进程的打印信息,观察各个进程获取到互斥锁后,优先级变化情况
  14. */
  15. #include <rtthread.h>
  16. #include "tc_comm.h"
  17. static rt_thread_t tid20 = RT_NULL;
  18. static rt_thread_t tid21 = RT_NULL;
  19. static rt_thread_t tid22 = RT_NULL;
  20. static rt_thread_t tid23 = RT_NULL;
  21. static rt_thread_t tid24 = RT_NULL;
  22. static rt_thread_t tid25 = RT_NULL;
  23. static rt_thread_t tid26 = RT_NULL;
  24. static rt_thread_t tid27 = RT_NULL;
  25. static rt_thread_t tid28 = RT_NULL;
  26. static rt_thread_t tid29 = RT_NULL;
  27. static rt_mutex_t mutex = RT_NULL;
  28. static void thread20_entry(void* parameter)
  29. {
  30. rt_err_t result;
  31. rt_tick_t tick;
  32. rt_kprintf("[%d] thread20 run!\n", rt_tick_get());
  33. rt_thread_delay(30);
  34. rt_kprintf("[%d] thread20 wake!\n", rt_tick_get());
  35. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  36. if (result != RT_EOK)
  37. {
  38. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  39. }
  40. rt_kprintf("[%d] thread20 take!\n", rt_tick_get());
  41. tick = rt_tick_get();
  42. while (rt_tick_get() - tick < 5)
  43. {
  44. rt_kprintf("[%d] thread20, init_priority=%d, current_priority=%d\n",
  45. rt_tick_get(), tid20->init_priority, tid20->current_priority);
  46. }
  47. rt_mutex_release(mutex);
  48. rt_kprintf("[%d] thread20 exit!\n", rt_tick_get());
  49. }
  50. static void thread21_entry(void* parameter)
  51. {
  52. rt_err_t result;
  53. rt_tick_t tick;
  54. rt_kprintf("[%d] thread21 run!\n", rt_tick_get());
  55. rt_thread_delay(25);
  56. rt_kprintf("[%d] thread21 wake!\n", rt_tick_get());
  57. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  58. if (result != RT_EOK)
  59. {
  60. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  61. }
  62. rt_kprintf("[%d] thread21 take!\n", rt_tick_get());
  63. tick = rt_tick_get();
  64. while (rt_tick_get() - tick < 5)
  65. {
  66. rt_kprintf("[%d] thread21, init_priority=%d, current_priority=%d\n",
  67. rt_tick_get(), tid21->init_priority, tid21->current_priority);
  68. }
  69. rt_mutex_release(mutex);
  70. rt_kprintf("[%d] thread21 exit!\n", rt_tick_get());
  71. }
  72. static void thread22_entry(void* parameter)
  73. {
  74. rt_tick_t tick;
  75. rt_kprintf("[%d] thread22 run!\n", rt_tick_get());
  76. rt_thread_delay(20);
  77. rt_kprintf("[%d] thread22 wake!\n", rt_tick_get());
  78. tick = rt_tick_get();
  79. while (rt_tick_get() - tick < 100)
  80. {
  81. rt_kprintf("[%d] thread22 running..., init_priority=%d, current_priority=%d\n",
  82. rt_tick_get(), tid22->init_priority, tid22->current_priority);
  83. rt_thread_delay(2);
  84. }
  85. rt_kprintf("[%d] thread22 exit!\n", rt_tick_get());
  86. }
  87. static void thread23_entry(void* parameter)
  88. {
  89. rt_err_t result;
  90. rt_tick_t tick;
  91. rt_kprintf("[%d] thread23 run!\n", rt_tick_get());
  92. rt_thread_delay(15);
  93. rt_kprintf("[%d] thread23 wake!\n", rt_tick_get());
  94. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  95. if (result != RT_EOK)
  96. {
  97. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  98. }
  99. rt_kprintf("[%d] thread23 take!\n", rt_tick_get());
  100. tick = rt_tick_get();
  101. while (rt_tick_get() - tick < 5)
  102. {
  103. rt_kprintf("[%d] thread23, init_priority=%d, current_priority=%d\n",
  104. rt_tick_get(), tid23->init_priority, tid23->current_priority);
  105. }
  106. rt_mutex_release(mutex);
  107. rt_kprintf("[%d] thread23 exit!\n", rt_tick_get());
  108. }
  109. static void thread24_entry(void* parameter)
  110. {
  111. rt_err_t result;
  112. rt_tick_t tick;
  113. rt_kprintf("[%d] thread24 run!\n", rt_tick_get());
  114. rt_thread_delay(10);
  115. rt_kprintf("[%d] thread24 wake!\n", rt_tick_get());
  116. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  117. if (result != RT_EOK)
  118. {
  119. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  120. }
  121. rt_kprintf("[%d] thread24 take!\n", rt_tick_get());
  122. tick = rt_tick_get();
  123. while (rt_tick_get() - tick < 5)
  124. {
  125. rt_kprintf("[%d] thread24, init_priority=%d, current_priority=%d\n",
  126. rt_tick_get(), tid24->init_priority, tid24->current_priority);
  127. }
  128. rt_mutex_release(mutex);
  129. rt_kprintf("[%d] thread24 exit!\n", rt_tick_get());
  130. }
  131. static void thread25_entry(void* parameter)
  132. {
  133. rt_err_t result;
  134. rt_tick_t tick;
  135. rt_kprintf("[%d] thread25 run!\n", rt_tick_get());
  136. rt_thread_delay(5);
  137. rt_kprintf("[%d] thread25 wake!\n", rt_tick_get());
  138. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  139. if (result != RT_EOK)
  140. {
  141. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  142. }
  143. rt_kprintf("[%d] thread25 take!\n", rt_tick_get());
  144. tick = rt_tick_get();
  145. while (rt_tick_get() - tick < 5)
  146. {
  147. rt_kprintf("[%d] thread25, init_priority=%d, current_priority=%d\n",
  148. rt_tick_get(), tid25->init_priority, tid25->current_priority);
  149. }
  150. rt_mutex_release(mutex);
  151. rt_kprintf("[%d] thread25 exit!\n", rt_tick_get());
  152. }
  153. static void thread26_entry(void* parameter)
  154. {
  155. rt_tick_t tick;
  156. rt_err_t result;
  157. rt_kprintf("[%d] thread26 run!\n", rt_tick_get());
  158. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  159. if (result != RT_EOK)
  160. {
  161. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  162. }
  163. rt_kprintf("[%d] thread26 take!\n", rt_tick_get());
  164. tick = rt_tick_get();
  165. while (rt_tick_get() - tick < 50)
  166. {
  167. rt_kprintf("[%d] thread26, init_priority=%d, current_priority=%d\n",
  168. rt_tick_get(), tid26->init_priority, tid26->current_priority);
  169. rt_thread_delay(1);
  170. }
  171. rt_mutex_release(mutex);
  172. rt_kprintf("[%d] thread26 exit!\n", rt_tick_get());
  173. }
  174. static void thread27_entry(void* parameter)
  175. {
  176. rt_tick_t tick;
  177. rt_err_t result;
  178. rt_kprintf("[%d] thread27 run!\n", rt_tick_get());
  179. rt_thread_delay(35);
  180. rt_kprintf("[%d] thread27 wake!\n", rt_tick_get());
  181. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  182. if (result != RT_EOK)
  183. {
  184. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  185. }
  186. rt_kprintf("[%d] thread27 take!\n", rt_tick_get());
  187. tick = rt_tick_get();
  188. while (rt_tick_get() - tick < 5)
  189. {
  190. rt_kprintf("[%d] thread27, init_priority=%d, current_priority=%d\n",
  191. rt_tick_get(), tid27->init_priority, tid27->current_priority);
  192. }
  193. rt_mutex_release(mutex);
  194. rt_kprintf("[%d] thread27 exit!\n", rt_tick_get());
  195. }
  196. static void thread28_entry(void* parameter)
  197. {
  198. rt_tick_t tick;
  199. rt_err_t result;
  200. rt_kprintf("[%d] thread28 run!\n", rt_tick_get());
  201. rt_thread_delay(40);
  202. rt_kprintf("[%d] thread28 wake!\n", rt_tick_get());
  203. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  204. if (result != RT_EOK)
  205. {
  206. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  207. }
  208. rt_kprintf("[%d] thread28 take!\n", rt_tick_get());
  209. tick = rt_tick_get();
  210. while (rt_tick_get() - tick < 5)
  211. {
  212. rt_kprintf("[%d] thread28, init_priority=%d, current_priority=%d\n",
  213. rt_tick_get(), tid28->init_priority, tid28->current_priority);
  214. }
  215. rt_mutex_release(mutex);
  216. rt_kprintf("[%d] thread28 exit!\n", rt_tick_get());
  217. }
  218. static void thread29_entry(void* parameter)
  219. {
  220. rt_tick_t tick;
  221. rt_err_t result;
  222. rt_kprintf("[%d] thread29 run!\n", rt_tick_get());
  223. rt_thread_delay(45);
  224. rt_kprintf("[%d] thread29 wake!\n", rt_tick_get());
  225. result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
  226. if (result != RT_EOK)
  227. {
  228. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  229. }
  230. rt_kprintf("[%d] thread29 take!\n", rt_tick_get());
  231. tick = rt_tick_get();
  232. while (rt_tick_get() - tick < 5)
  233. {
  234. rt_kprintf("[%d] thread29, init_priority=%d, current_priority=%d\n",
  235. rt_tick_get(), tid29->init_priority, tid29->current_priority);
  236. }
  237. rt_mutex_release(mutex);
  238. rt_kprintf("[%d] thread29 exit!\n", rt_tick_get());
  239. }
  240. static int mutex_simple_init()
  241. {
  242. /* 创建互斥锁 */
  243. mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
  244. if (mutex == RT_NULL)
  245. {
  246. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  247. return 0;
  248. }
  249. tid29 = rt_thread_create("t29",
  250. thread29_entry, RT_NULL,
  251. THREAD_STACK_SIZE, 29, THREAD_TIMESLICE);
  252. if (tid29 != RT_NULL)
  253. rt_thread_startup(tid29);
  254. else
  255. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  256. tid28 = rt_thread_create("t28",
  257. thread28_entry, RT_NULL,
  258. THREAD_STACK_SIZE, 28, THREAD_TIMESLICE);
  259. if (tid28 != RT_NULL)
  260. rt_thread_startup(tid28);
  261. else
  262. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  263. tid27 = rt_thread_create("t27",
  264. thread27_entry, RT_NULL,
  265. THREAD_STACK_SIZE, 27, THREAD_TIMESLICE);
  266. if (tid27 != RT_NULL)
  267. rt_thread_startup(tid27);
  268. else
  269. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  270. tid26 = rt_thread_create("t26",
  271. thread26_entry, RT_NULL,
  272. THREAD_STACK_SIZE, 26, THREAD_TIMESLICE);
  273. if (tid26 != RT_NULL)
  274. rt_thread_startup(tid26);
  275. else
  276. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  277. tid25 = rt_thread_create("t25",
  278. thread25_entry, RT_NULL,
  279. THREAD_STACK_SIZE, 25, THREAD_TIMESLICE);
  280. if (tid25 != RT_NULL)
  281. rt_thread_startup(tid25);
  282. else
  283. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  284. tid24 = rt_thread_create("t24",
  285. thread24_entry, RT_NULL,
  286. THREAD_STACK_SIZE, 24, THREAD_TIMESLICE);
  287. if (tid24 != RT_NULL)
  288. rt_thread_startup(tid24);
  289. else
  290. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  291. tid23 = rt_thread_create("t23",
  292. thread23_entry, RT_NULL,
  293. THREAD_STACK_SIZE, 23, THREAD_TIMESLICE);
  294. if (tid23 != RT_NULL)
  295. rt_thread_startup(tid23);
  296. else
  297. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  298. tid22 = rt_thread_create("t22",
  299. thread22_entry, RT_NULL,
  300. THREAD_STACK_SIZE, 22, THREAD_TIMESLICE);
  301. if (tid22 != RT_NULL)
  302. rt_thread_startup(tid22);
  303. else
  304. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  305. tid21 = rt_thread_create("t21",
  306. thread21_entry, RT_NULL,
  307. THREAD_STACK_SIZE, 21, THREAD_TIMESLICE);
  308. if (tid21 != RT_NULL)
  309. rt_thread_startup(tid21);
  310. else
  311. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  312. tid20 = rt_thread_create("t20",
  313. thread20_entry, RT_NULL,
  314. THREAD_STACK_SIZE, 20, THREAD_TIMESLICE);
  315. if (tid20 != RT_NULL)
  316. rt_thread_startup(tid20);
  317. else
  318. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  319. return 0;
  320. }
  321. #ifdef RT_USING_TC
  322. static void _tc_cleanup()
  323. {
  324. /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
  325. rt_enter_critical();
  326. /* 删除线程 */
  327. if (tid20 != RT_NULL && tid20->stat != RT_THREAD_CLOSE)
  328. rt_thread_delete(tid20);
  329. if (tid21 != RT_NULL && tid21->stat != RT_THREAD_CLOSE)
  330. rt_thread_delete(tid21);
  331. if (tid22 != RT_NULL && tid22->stat != RT_THREAD_CLOSE)
  332. rt_thread_delete(tid22);
  333. if (tid23 != RT_NULL && tid23->stat != RT_THREAD_CLOSE)
  334. rt_thread_delete(tid23);
  335. if (tid24 != RT_NULL && tid24->stat != RT_THREAD_CLOSE)
  336. rt_thread_delete(tid24);
  337. if (tid25 != RT_NULL && tid25->stat != RT_THREAD_CLOSE)
  338. rt_thread_delete(tid25);
  339. if (tid26 != RT_NULL && tid26->stat != RT_THREAD_CLOSE)
  340. rt_thread_delete(tid26);
  341. if (tid27 != RT_NULL && tid27->stat != RT_THREAD_CLOSE)
  342. rt_thread_delete(tid27);
  343. if (tid28 != RT_NULL && tid28->stat != RT_THREAD_CLOSE)
  344. rt_thread_delete(tid28);
  345. if (tid29 != RT_NULL && tid29->stat != RT_THREAD_CLOSE)
  346. rt_thread_delete(tid29);
  347. if (mutex != RT_NULL)
  348. {
  349. rt_mutex_delete(mutex);
  350. }
  351. rt_kprintf("test_done!\n");
  352. /* 调度器解锁 */
  353. rt_exit_critical();
  354. /* 设置TestCase状态 */
  355. tc_done(TC_STAT_PASSED);
  356. }
  357. int _tc_mutex_priority()
  358. {
  359. /* 设置TestCase清理回调函数 */
  360. tc_cleanup(_tc_cleanup);
  361. mutex_simple_init();
  362. /* 返回TestCase运行的最长时间 */
  363. return 100;
  364. }
  365. /* 输出函数命令到finsh shell中 */
  366. FINSH_FUNCTION_EXPORT(_tc_mutex_priority, a priority rollover example of mutex);
  367. #else
  368. /* 用户应用入口 */
  369. int rt_application_init()
  370. {
  371. mutex_simple_init();
  372. return 0;
  373. }
  374. #endif