util.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. #define ALIGNED_SIZE(x, align) (((x) + (align)-1) & ~((align)-1))
  35. namespace util {
  36. void set_thread_name(const char* name);
  37. int set_realtime_priority(int level);
  38. int set_core_affinity(std::vector<int> cores);
  39. int set_file_descriptor_limit(uint64_t limit);
  40. // ***** math helpers *****
  41. // map x from [a1, a2] to [b1, b2]
  42. template <typename T>
  43. T map_val(T x, T a1, T a2, T b1, T b2) {
  44. x = std::clamp(x, a1, a2);
  45. T ra = a2 - a1;
  46. T rb = b2 - b1;
  47. return (x - a1) * rb / ra + b1;
  48. }
  49. // ***** string helpers *****
  50. template <typename... Args>
  51. std::string string_format(const std::string& format, Args... args) {
  52. size_t size = snprintf(nullptr, 0, format.c_str(), args...) + 1;
  53. std::unique_ptr<char[]> buf(new char[size]);
  54. snprintf(buf.get(), size, format.c_str(), args...);
  55. return std::string(buf.get(), buf.get() + size - 1);
  56. }
  57. std::string getenv(const char* key, std::string default_val = "");
  58. int getenv(const char* key, int default_val);
  59. float getenv(const char* key, float default_val);
  60. std::string hexdump(const uint8_t* in, const size_t size);
  61. bool starts_with(const std::string &s1, const std::string &s2);
  62. bool ends_with(const std::string &s, const std::string &suffix);
  63. // ***** random helpers *****
  64. int random_int(int min, int max);
  65. std::string random_string(std::string::size_type length);
  66. // **** file helpers *****
  67. std::string read_file(const std::string& fn);
  68. std::map<std::string, std::string> read_files_in_dir(const std::string& path);
  69. int write_file(const char* path, const void* data, size_t size, int flags = O_WRONLY, mode_t mode = 0664);
  70. FILE* safe_fopen(const char* filename, const char* mode);
  71. size_t safe_fwrite(const void * ptr, size_t size, size_t count, FILE * stream);
  72. int safe_fflush(FILE *stream);
  73. int safe_ioctl(int fd, unsigned long request, void *argp);
  74. std::string readlink(const std::string& path);
  75. bool file_exists(const std::string& fn);
  76. bool create_directories(const std::string &dir, mode_t mode);
  77. std::string check_output(const std::string& command);
  78. inline void sleep_for(const int milliseconds) {
  79. if (milliseconds > 0) {
  80. std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
  81. }
  82. }
  83. } // namespace util
  84. class ExitHandler {
  85. public:
  86. ExitHandler() {
  87. std::signal(SIGINT, (sighandler_t)set_do_exit);
  88. std::signal(SIGTERM, (sighandler_t)set_do_exit);
  89. #ifndef __APPLE__
  90. std::signal(SIGPWR, (sighandler_t)set_do_exit);
  91. #endif
  92. }
  93. inline static std::atomic<bool> power_failure = false;
  94. inline static std::atomic<int> signal = 0;
  95. inline operator bool() { return do_exit; }
  96. inline ExitHandler& operator=(bool v) {
  97. signal = 0;
  98. do_exit = v;
  99. return *this;
  100. }
  101. private:
  102. static void set_do_exit(int sig) {
  103. #ifndef __APPLE__
  104. power_failure = (sig == SIGPWR);
  105. #endif
  106. signal = sig;
  107. do_exit = true;
  108. }
  109. inline static std::atomic<bool> do_exit = false;
  110. };
  111. struct unique_fd {
  112. unique_fd(int fd = -1) : fd_(fd) {}
  113. unique_fd& operator=(unique_fd&& uf) {
  114. fd_ = uf.fd_;
  115. uf.fd_ = -1;
  116. return *this;
  117. }
  118. ~unique_fd() {
  119. if (fd_ != -1) close(fd_);
  120. }
  121. operator int() const { return fd_; }
  122. int fd_;
  123. };
  124. class FirstOrderFilter {
  125. public:
  126. FirstOrderFilter(float x0, float ts, float dt, bool initialized = true) {
  127. k_ = (dt / ts) / (1.0 + dt / ts);
  128. x_ = x0;
  129. initialized_ = initialized;
  130. }
  131. inline float update(float x) {
  132. if (initialized_) {
  133. x_ = (1. - k_) * x_ + k_ * x;
  134. } else {
  135. initialized_ = true;
  136. x_ = x;
  137. }
  138. return x_;
  139. }
  140. inline void reset(float x) { x_ = x; }
  141. inline float x(){ return x_; }
  142. private:
  143. float x_, k_;
  144. bool initialized_;
  145. };
  146. template<typename T>
  147. void update_max_atomic(std::atomic<T>& max, T const& value) {
  148. T prev = max;
  149. while (prev < value && !max.compare_exchange_weak(prev, value)) {}
  150. }
  151. typedef struct Rect {
  152. int x;
  153. int y;
  154. int w;
  155. int h;
  156. } Rect;