util.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #pragma once
  2. #include <fcntl.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <algorithm>
  6. #include <atomic>
  7. #include <chrono>
  8. #include <csignal>
  9. #include <map>
  10. #include <memory>
  11. #include <mutex>
  12. #include <string>
  13. #include <thread>
  14. #include <vector>
  15. // keep trying if x gets interrupted by a signal
  16. #define HANDLE_EINTR(x) \
  17. ({ \
  18. decltype(x) ret_; \
  19. int try_cnt = 0; \
  20. do { \
  21. ret_ = (x); \
  22. } while (ret_ == -1 && errno == EINTR && try_cnt++ < 100); \
  23. ret_; \
  24. })
  25. #ifndef sighandler_t
  26. typedef void (*sighandler_t)(int sig);
  27. #endif
  28. const double MILE_TO_KM = 1.609344;
  29. const double KM_TO_MILE = 1. / MILE_TO_KM;
  30. const double MS_TO_KPH = 3.6;
  31. const double MS_TO_MPH = MS_TO_KPH * KM_TO_MILE;
  32. const double METER_TO_MILE = KM_TO_MILE / 1000.0;
  33. const double METER_TO_FOOT = 3.28084;
  34. namespace util {
  35. void set_thread_name(const char* name);
  36. int set_realtime_priority(int level);
  37. int set_core_affinity(std::vector<int> cores);
  38. int set_file_descriptor_limit(uint64_t limit);
  39. // ***** math helpers *****
  40. // map x from [a1, a2] to [b1, b2]
  41. template <typename T>
  42. T map_val(T x, T a1, T a2, T b1, T b2) {
  43. x = std::clamp(x, a1, a2);
  44. T ra = a2 - a1;
  45. T rb = b2 - b1;
  46. return (x - a1) * rb / ra + b1;
  47. }
  48. // ***** string helpers *****
  49. template <typename... Args>
  50. std::string string_format(const std::string& format, Args... args) {
  51. size_t size = snprintf(nullptr, 0, format.c_str(), args...) + 1;
  52. std::unique_ptr<char[]> buf(new char[size]);
  53. snprintf(buf.get(), size, format.c_str(), args...);
  54. return std::string(buf.get(), buf.get() + size - 1);
  55. }
  56. std::string getenv(const char* key, std::string default_val = "");
  57. int getenv(const char* key, int default_val);
  58. float getenv(const char* key, float default_val);
  59. std::string hexdump(const uint8_t* in, const size_t size);
  60. bool starts_with(const std::string &s1, const std::string &s2);
  61. bool ends_with(const std::string &s, const std::string &suffix);
  62. // ***** random helpers *****
  63. int random_int(int min, int max);
  64. std::string random_string(std::string::size_type length);
  65. // **** file helpers *****
  66. std::string read_file(const std::string& fn);
  67. std::map<std::string, std::string> read_files_in_dir(const std::string& path);
  68. int write_file(const char* path, const void* data, size_t size, int flags = O_WRONLY, mode_t mode = 0664);
  69. FILE* safe_fopen(const char* filename, const char* mode);
  70. size_t safe_fwrite(const void * ptr, size_t size, size_t count, FILE * stream);
  71. int safe_fflush(FILE *stream);
  72. int safe_ioctl(int fd, unsigned long request, void *argp);
  73. std::string readlink(const std::string& path);
  74. bool file_exists(const std::string& fn);
  75. bool create_directories(const std::string &dir, mode_t mode);
  76. std::string check_output(const std::string& command);
  77. inline void sleep_for(const int milliseconds) {
  78. if (milliseconds > 0) {
  79. std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
  80. }
  81. }
  82. } // namespace util
  83. class ExitHandler {
  84. public:
  85. ExitHandler() {
  86. std::signal(SIGINT, (sighandler_t)set_do_exit);
  87. std::signal(SIGTERM, (sighandler_t)set_do_exit);
  88. #ifndef __APPLE__
  89. std::signal(SIGPWR, (sighandler_t)set_do_exit);
  90. #endif
  91. }
  92. inline static std::atomic<bool> power_failure = false;
  93. inline static std::atomic<int> signal = 0;
  94. inline operator bool() { return do_exit; }
  95. inline ExitHandler& operator=(bool v) {
  96. signal = 0;
  97. do_exit = v;
  98. return *this;
  99. }
  100. private:
  101. static void set_do_exit(int sig) {
  102. #ifndef __APPLE__
  103. power_failure = (sig == SIGPWR);
  104. #endif
  105. signal = sig;
  106. do_exit = true;
  107. }
  108. inline static std::atomic<bool> do_exit = false;
  109. };
  110. struct unique_fd {
  111. unique_fd(int fd = -1) : fd_(fd) {}
  112. unique_fd& operator=(unique_fd&& uf) {
  113. fd_ = uf.fd_;
  114. uf.fd_ = -1;
  115. return *this;
  116. }
  117. ~unique_fd() {
  118. if (fd_ != -1) close(fd_);
  119. }
  120. operator int() const { return fd_; }
  121. int fd_;
  122. };
  123. class FirstOrderFilter {
  124. public:
  125. FirstOrderFilter(float x0, float ts, float dt, bool initialized = true) {
  126. k_ = (dt / ts) / (1.0 + dt / ts);
  127. x_ = x0;
  128. initialized_ = initialized;
  129. }
  130. inline float update(float x) {
  131. if (initialized_) {
  132. x_ = (1. - k_) * x_ + k_ * x;
  133. } else {
  134. initialized_ = true;
  135. x_ = x;
  136. }
  137. return x_;
  138. }
  139. inline void reset(float x) { x_ = x; }
  140. inline float x(){ return x_; }
  141. private:
  142. float x_, k_;
  143. bool initialized_;
  144. };
  145. template<typename T>
  146. void update_max_atomic(std::atomic<T>& max, T const& value) {
  147. T prev = max;
  148. while (prev < value && !max.compare_exchange_weak(prev, value)) {}
  149. }
  150. typedef struct Rect {
  151. int x;
  152. int y;
  153. int w;
  154. int h;
  155. } Rect;