hthread.h 3.0 KB

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