hthread.h 3.0 KB

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