mutex_priority.c 12 KB

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