luat_rtos_task_pc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "luat_base.h"
  2. #include "luat_rtos.h"
  3. #include "luat_malloc.h"
  4. #include "uv.h"
  5. #include "c_common.h"
  6. #define LUAT_LOG_TAG "rtos.task"
  7. #include "luat_log.h"
  8. #include "luat_queue_pc.h"
  9. typedef struct utask
  10. {
  11. uv_thread_t t;
  12. uv_queue_item_t q;
  13. uv_mutex_t m;
  14. luat_rtos_task_entry task_fun;
  15. void* user_data;
  16. uint16_t event_cout;
  17. }utask_t;
  18. LUAT_RET luat_send_event_to_task(void *task_handle, uint32_t id, uint32_t param1, uint32_t param2, uint32_t param3) {
  19. luat_rtos_event_send(task_handle, id, param1, param2, param3, 0);
  20. }
  21. LUAT_RET luat_wait_event_from_task(void *task_handle, uint32_t wait_event_id, luat_event_t *out_event, void *call_back, uint32_t ms) {
  22. luat_rtos_event_recv(task_handle, wait_event_id, out_event, call_back, ms);
  23. }
  24. // void *luat_get_current_task(void) {
  25. // LLOGE("调用了luat_get_current_task,但未实现");
  26. // return NULL;
  27. // }
  28. static void rtos_task(void* args) {
  29. utask_t* task = (utask_t*)args;
  30. task->task_fun(task->user_data);
  31. }
  32. int luat_rtos_task_create(luat_rtos_task_handle *task_handle, uint32_t stack_size, uint8_t priority, const char *task_name, luat_rtos_task_entry task_fun, void* user_data, uint16_t event_cout) {
  33. utask_t* task = luat_heap_malloc(sizeof(utask_t));
  34. if (task == NULL) {
  35. return -1;
  36. }
  37. memset(task, 0, sizeof(utask_t));
  38. task->event_cout = event_cout;
  39. task->user_data = user_data;
  40. task->task_fun = task_fun;
  41. uv_mutex_init(&task->m);
  42. int ret = uv_thread_create(&task->t, rtos_task, task);
  43. if (ret) {
  44. LLOGE("uv_thread_create %d", ret);
  45. luat_heap_free(task);
  46. return ret;
  47. }
  48. *task_handle = task;
  49. return 0;
  50. }
  51. int luat_rtos_task_delete(luat_rtos_task_handle task_handle) {
  52. utask_t* task = (utask_t*)task_handle;
  53. luat_heap_free(task); // TODO 详细清理呢
  54. return 0;
  55. }
  56. int luat_rtos_event_send(luat_rtos_task_handle task_handle, uint32_t id, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t timeout) {
  57. if (task_handle == NULL) {
  58. LLOGE("task_handle is NULL");
  59. return -1;
  60. }
  61. utask_t* task = (utask_t*)task_handle;
  62. luat_event_t e = {0};
  63. e.id = id;
  64. e.param1 = param1;
  65. e.param2 = param2;
  66. e.param3 = param3;
  67. uv_queue_item_t* item = luat_heap_malloc(sizeof(uv_queue_item_t) + sizeof(luat_event_t));
  68. memset(item, 0, sizeof(uv_queue_item_t));
  69. memcpy(item->msg, &e, sizeof(luat_event_t));
  70. item->size = sizeof(luat_event_t);
  71. uv_mutex_lock(&task->m);
  72. int ret = luat_queue_push(&task->q, item);
  73. uv_mutex_unlock(&task->m);
  74. return ret;
  75. }
  76. int luat_rtos_event_recv(luat_rtos_task_handle task_handle, uint32_t wait_event_id, luat_event_t *out_event, luat_rtos_event_wait_callback_t *callback_fun, uint32_t timeout) {
  77. if (task_handle == NULL) {
  78. LLOGE("task_handle is NULL");
  79. return -1;
  80. }
  81. // LLOGD("callback_fun %p", callback_fun);
  82. utask_t* task = (utask_t*)task_handle;
  83. uv_queue_item_t* item = luat_heap_malloc(sizeof(uv_queue_item_t) + sizeof(luat_event_t));
  84. int ret = 0;
  85. while (1)
  86. {
  87. uv_mutex_lock(&task->m);
  88. ret = luat_queue_pop(&task->q, item);
  89. uv_mutex_unlock(&task->m);
  90. if (ret == 0)
  91. {
  92. memcpy(out_event, item->msg, sizeof(luat_event_t));
  93. if ((wait_event_id == CORE_EVENT_ID_ANY) || (out_event->id == wait_event_id)) {
  94. luat_heap_free(item);
  95. return 0;
  96. }
  97. if (callback_fun) {
  98. LLOGE("暂不支持callback_fun %p", callback_fun);
  99. // callback_fun(out_event, task_handle);
  100. }
  101. }
  102. // 读不到, 只能返回错误了
  103. if (timeout == 0)
  104. {
  105. luat_heap_free(item);
  106. return 1;
  107. }
  108. if (timeout > 0 && timeout != (size_t)(-1))
  109. {
  110. timeout--;
  111. }
  112. uv_sleep(1);
  113. }
  114. luat_heap_free(item);
  115. return -1;
  116. }
  117. typedef struct luat_message_item
  118. {
  119. uint32_t id;
  120. void* msg;
  121. } luat_message_item_t;
  122. int luat_rtos_message_send(luat_rtos_task_handle task_handle, uint32_t message_id, void *p_message) {
  123. if (task_handle == NULL) {
  124. LLOGE("task_handle is NULL");
  125. return -1;
  126. }
  127. utask_t* task = (utask_t*)task_handle;
  128. luat_message_item_t payload = {0};
  129. payload.id = message_id;
  130. payload.msg = p_message;
  131. uv_queue_item_t* item = luat_heap_malloc(sizeof(uv_queue_item_t) + sizeof(luat_message_item_t));
  132. if (item == NULL) {
  133. LLOGE("out of memory when malloc message item");
  134. return -1;
  135. }
  136. memset(item, 0, sizeof(uv_queue_item_t));
  137. memcpy(item->msg, &payload, sizeof(luat_message_item_t));
  138. item->size = sizeof(luat_message_item_t);
  139. uv_mutex_lock(&task->m);
  140. int ret = luat_queue_push(&task->q, item);
  141. uv_mutex_unlock(&task->m);
  142. return ret;
  143. }
  144. int luat_rtos_message_recv(luat_rtos_task_handle task_handle, uint32_t *message_id, void **p_p_message, uint32_t timeout) {
  145. if (task_handle == NULL || message_id == NULL || p_p_message == NULL) {
  146. LLOGE("invalid args for message_recv");
  147. return -1;
  148. }
  149. utask_t* task = (utask_t*)task_handle;
  150. uv_queue_item_t* item = luat_heap_malloc(sizeof(uv_queue_item_t) + sizeof(luat_message_item_t));
  151. int ret = 0;
  152. while (1) {
  153. uv_mutex_lock(&task->m);
  154. ret = luat_queue_pop(&task->q, item);
  155. uv_mutex_unlock(&task->m);
  156. if (ret == 0) {
  157. luat_message_item_t payload = {0};
  158. memcpy(&payload, item->msg, sizeof(luat_message_item_t));
  159. *message_id = payload.id;
  160. *p_p_message = payload.msg;
  161. luat_heap_free(item);
  162. return 0;
  163. }
  164. if (timeout == 0) {
  165. luat_heap_free(item);
  166. return 1;
  167. }
  168. if (timeout > 0 && timeout != (size_t)(-1)) {
  169. timeout--;
  170. }
  171. uv_sleep(1);
  172. }
  173. luat_heap_free(item);
  174. return -1;
  175. }
  176. void luat_os_entry_cri(void) {
  177. }
  178. void luat_os_exit_cri(void) {
  179. }
  180. uint32_t luat_rtos_entry_critical(void) {
  181. return 0;
  182. }
  183. void luat_rtos_exit_critical(uint32_t critical) {
  184. // nop
  185. }