hthread.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #ifndef HW_THREAD_H_
  2. #define HW_THREAD_H_
  3. #include <thread>
  4. #include <atomic>
  5. #include <chrono>
  6. #include "hplatform.h"
  7. #include "hdef.h"
  8. #ifdef OS_WIN
  9. #define gettid GetCurrentThreadId
  10. #elif defined(OS_ANDROID)
  11. #define gettid gettid
  12. #elif defined(OS_LINUX)
  13. #include <sys/syscall.h>
  14. static inline int gettid() {
  15. return syscall(SYS_gettid);
  16. }
  17. #else
  18. #define gettid pthread_self
  19. #endif
  20. /************************************************
  21. * HThread
  22. * Status: STOP,RUNNING,PAUSE
  23. * Control: start,stop,pause,resume
  24. * first-level virtual: doTask
  25. * second-level virtual: run
  26. ************************************************/
  27. class HThread {
  28. public:
  29. HThread() {
  30. status = STOP;
  31. status_switch = false;
  32. sleep_policy = YIELD;
  33. sleep_ms = 0;
  34. }
  35. virtual ~HThread() {}
  36. virtual int start() {
  37. if (status == STOP) {
  38. switchStatus(RUNNING);
  39. dotask_cnt = 0;
  40. thread = std::thread([this]{
  41. doPrepare();
  42. run();
  43. doFinish();
  44. });
  45. }
  46. return 0;
  47. }
  48. virtual int stop() {
  49. if (status != STOP) {
  50. switchStatus(STOP);
  51. thread.join(); // wait thread exit
  52. }
  53. return 0;
  54. }
  55. virtual int pause() {
  56. if (status == RUNNING) {
  57. switchStatus(PAUSE);
  58. }
  59. return 0;
  60. }
  61. virtual int resume() {
  62. if (status == PAUSE) {
  63. switchStatus(RUNNING);
  64. }
  65. return 0;
  66. }
  67. virtual void run() {
  68. while (status != STOP) {
  69. while (status == PAUSE) {
  70. std::this_thread::yield();
  71. }
  72. doTask();
  73. dotask_cnt++;
  74. sleep();
  75. }
  76. }
  77. virtual void doPrepare() {}
  78. virtual void doTask() {}
  79. virtual void doFinish() {}
  80. std::thread thread;
  81. enum Status {
  82. STOP,
  83. RUNNING,
  84. PAUSE,
  85. };
  86. std::atomic<Status> status;
  87. uint32_t dotask_cnt;
  88. enum SleepPolicy {
  89. YIELD,
  90. SLEEP_FOR,
  91. SLEEP_UNTIL,
  92. NO_SLEEP,
  93. };
  94. void setSleepPolicy(SleepPolicy policy, uint32_t ms = 0) {
  95. status_switch = true;
  96. sleep_policy = policy;
  97. sleep_ms = ms;
  98. }
  99. protected:
  100. void switchStatus(Status stat) {
  101. status_switch = true;
  102. status = stat;
  103. }
  104. void sleep() {
  105. switch (sleep_policy) {
  106. case YIELD:
  107. std::this_thread::yield();
  108. break;
  109. case SLEEP_FOR:
  110. std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
  111. break;
  112. case SLEEP_UNTIL: {
  113. if (status_switch) {
  114. status_switch = false;
  115. base_tp = std::chrono::system_clock::now();
  116. }
  117. base_tp += std::chrono::milliseconds(sleep_ms);
  118. std::this_thread::sleep_until(base_tp);
  119. }
  120. break;
  121. default: // donothing, go all out.
  122. break;
  123. }
  124. }
  125. std::atomic<bool> status_switch;
  126. SleepPolicy sleep_policy;
  127. std::chrono::system_clock::time_point base_tp; // for SLEEP_UNTIL
  128. uint32_t sleep_ms;
  129. };
  130. #endif // HW_THREAD_H_