hthread.h 3.1 KB

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