You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.3 KiB

1 year ago
  1. #include "zthread.hpp"
  2. #include <map>
  3. #include "zoslogger.hpp"
  4. using namespace iflytop;
  5. using namespace std;
  6. static bool s_map_inited = false;
  7. static zmutex s_zthread_map_lock;
  8. static map<osThreadId, ZThread *> s_zthread_map;
  9. static ZThread g_default_thread;
  10. static void zosthread_default_task(void const *argument) {
  11. ZThread *thread = (ZThread *)argument;
  12. ZASSERT(thread);
  13. thread->threadcb();
  14. };
  15. void ZThread::zthread_module_init() {
  16. if (s_map_inited) return;
  17. s_map_inited = true;
  18. s_zthread_map_lock.init();
  19. }
  20. ZThread *ZThread::getThread() {
  21. ZThread *thread = nullptr;
  22. {
  23. zlock_guard guard(s_zthread_map_lock);
  24. thread = s_zthread_map[osThreadGetId()];
  25. }
  26. return thread;
  27. }
  28. void ZThread::threadcb() {
  29. m_status = kidle;
  30. {
  31. zlock_guard guard(s_zthread_map_lock);
  32. s_zthread_map[osThreadGetId()] = this;
  33. }
  34. while (true) {
  35. if (m_threadisworkingFlagCallSide) {
  36. m_status = kworking;
  37. if (m_taskfunction) m_taskfunction();
  38. if (m_taskfunction_exitcb) m_taskfunction_exitcb();
  39. m_status = kdead;
  40. while (m_threadisworkingFlagCallSide) {
  41. vTaskDelay(10);
  42. }
  43. m_status = kidle;
  44. }
  45. vTaskDelay(10);
  46. }
  47. }
  48. void ZThread::init(const char *threadname, int stack_size, osPriority priority) {
  49. // int r_task_create = 0;
  50. ZASSERT(threadname);
  51. m_lock = xSemaphoreCreateMutex();
  52. ZASSERT(m_lock);
  53. m_stacksize = stack_size;
  54. m_uxPriority = osPriorityNormal;
  55. m_taskfunction = nullptr;
  56. m_zthreadstartworkevent = xEventGroupCreate();
  57. m_name = threadname;
  58. osThreadDef(zosthread_default_task, zosthread_default_task, m_uxPriority, 0, m_stacksize);
  59. m_defaultTaskHandle = osThreadCreate(osThread(zosthread_default_task), this);
  60. ZASSERT(m_defaultTaskHandle != NULL);
  61. }
  62. void ZThread::start(zosthread_cb_t cb) { start(cb, nullptr); }
  63. void ZThread::start(zosthread_cb_t cb, zosthread_cb_t exitcb) {
  64. stop();
  65. m_taskfunction = cb;
  66. m_taskfunction_exitcb = exitcb;
  67. ZASSERT(m_taskfunction);
  68. xSemaphoreTake(m_lock, portMAX_DELAY);
  69. m_threadisworkingFlagCallSide = true;
  70. // xEventGroupSetBits(m_zthreadstartworkevent, 0x01);
  71. while (m_status == kidle) {
  72. xTaskNotifyGive(m_defaultTaskHandle);
  73. vTaskDelay(1);
  74. }
  75. xSemaphoreGive(m_lock);
  76. }
  77. void ZThread::stop() {
  78. xSemaphoreTake(m_lock, portMAX_DELAY);
  79. m_threadisworkingFlagCallSide = false;
  80. // xEventGroupSetBits(m_zthreadstartworkevent, 0x01);
  81. while (m_status != kidle) {
  82. xTaskNotifyGive(m_defaultTaskHandle);
  83. vTaskDelay(1);
  84. }
  85. xSemaphoreGive(m_lock);
  86. }
  87. void ZThread::sleep(uint32_t ms) { ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(ms)); }
  88. void ZThread::wake() {
  89. BaseType_t state;
  90. if (xPortIsInsideInterrupt()) {
  91. vTaskNotifyGiveFromISR(m_defaultTaskHandle, &state);
  92. } else {
  93. xTaskNotifyGive(m_defaultTaskHandle);
  94. }
  95. }
  96. ThisThread::ThisThread() {
  97. ZThread *thread = ZThread::getThread();
  98. this->thread = thread;
  99. }
  100. bool ThisThread::getExitFlag() {
  101. if (thread) return thread->getExitFlag();
  102. return false;
  103. }
  104. bool ThisThread::isworking() {
  105. if (thread) return thread->isworking();
  106. return true;
  107. }
  108. void ThisThread::sleep(uint32_t ms) {
  109. if (thread) {
  110. thread->sleep(ms);
  111. } else {
  112. vTaskDelay(pdMS_TO_TICKS(ms));
  113. }
  114. }