From a5510604e9adb511297bf9cb20a5fbdbaabe3e26 Mon Sep 17 00:00:00 2001 From: Jeremie Deray <jeremie.deray@pal-robotics.com> Date: Mon, 10 Oct 2016 18:40:28 +0200 Subject: [PATCH] add a bunch of utils for multi_threading --- src/multi_threading_utils.h | 171 ++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/multi_threading_utils.h diff --git a/src/multi_threading_utils.h b/src/multi_threading_utils.h new file mode 100644 index 000000000..eaadf6d4b --- /dev/null +++ b/src/multi_threading_utils.h @@ -0,0 +1,171 @@ +#ifndef WOLF_MULTI_THREADING_UTILS_H_ +#define WOLF_MULTI_THREADING_UTILS_H_ + +#include <iostream> +#include <mutex> +#include <chrono> + +#include <sys/syscall.h> + +namespace wolf +{ + +namespace core +{ +inline long get_thread_id() { return syscall(__NR_gettid); } +} + +namespace details +{ +using std::chrono::hours; +using std::chrono::minutes; +using std::chrono::seconds; +using std::chrono::milliseconds; +using std::chrono::microseconds; +using std::chrono::nanoseconds; + +using wolf_time_unit = nanoseconds; +using wolf_clock_t = std::chrono::_V2::high_resolution_clock; +using wolf_time_point_t = std::chrono::time_point<wolf_clock_t, wolf_time_unit>; +using wolf_duration_t = std::chrono::duration<wolf_clock_t, std::nano>; + +const wolf_time_unit zero = wolf_time_unit(0); +const wolf_time_unit min = std::numeric_limits<wolf_time_unit>::lowest(); +const wolf_time_unit max = std::numeric_limits<wolf_time_unit>::max(); +} + +/** + * \brief Return current time in 'unit'. + * Default nanoseconds. + * \return long, current time. + */ +template <typename unit = details::wolf_time_unit> +long int getTime() +{ + auto duration_since_epoch_to_now_unit = + std::chrono::duration_cast<unit>( + std::chrono::time_point_cast<unit>( + std::chrono::system_clock::now() + ).time_since_epoch() + ); + + return static_cast<long int>(duration_since_epoch_to_now_unit.count()); +} + +namespace io +{ + +enum class CoutColor +{ + BLACK, + RED, + GREEN, + YELLOW, + BLUE, + MAGENTA, + CYAN, + WHITE, + ENDCOLOR +}; + +inline std::ostream& operator<<(std::ostream& os, CoutColor c) +{ + switch(c) + { + // AINSI color codes. Prints bold color. + case CoutColor::BLACK : os << "\033[1;30m"; break; + case CoutColor::RED : os << "\033[1;31m"; break; + case CoutColor::GREEN : os << "\033[1;32m"; break; + case CoutColor::YELLOW : os << "\033[1;33m"; break; + case CoutColor::BLUE : os << "\033[1;34m"; break; + case CoutColor::MAGENTA : os << "\033[1;35m"; break; + case CoutColor::CYAN : os << "\033[1;36m"; break; + case CoutColor::WHITE : os << "\033[1;37m"; break; + case CoutColor::ENDCOLOR : os << "\033[0m"; break; + default : os << "\033[0m"; + } + return os; +} + +namespace details +{ + +static std::mutex the_infamous_cout_mutex; + +/** + * \brief Return current time in nanoseconds. + * \return Current time formated as string. + */ +inline std::string printTime() +{ + std::string now = std::to_string(getTime()).insert(10, "."); + return ("[" + now + "]"); +} + +inline void cout_impl() +{ + std::cout << CoutColor::ENDCOLOR << std::endl; +} + +template <typename T> +inline void cout_impl(const T& message) +{ + std::cout << message; + cout_impl(); +} + +template <typename T, typename... Args> +inline void cout_impl(const T& message, const Args&... rest) +{ + std::cout << message; + cout_impl(rest...); +} +} // namespace details + +template <typename T, typename... Args> +inline void locked_cout(const T& message, const Args&... rest) +{ + std::lock_guard<std::mutex> lock_cout{details::the_infamous_cout_mutex}; + std::cout << details::printTime() << " " << message; + + details::cout_impl(rest...); +} + +template <typename... Args> +inline void locked_cout(const CoutColor& color, const Args&... rest) +{ + std::lock_guard<std::mutex> lock_cout{details::the_infamous_cout_mutex}; + std::cout << color << details::printTime() << " "; + + details::cout_impl(rest...); +} + +} // namespace io + +#define WOLF_PRINT_COLOR(...) \ + locked_cout(__VA_ARGS__) + +#define WOLF_INFO(...) \ + locked_cout(wolf::io::CoutColor::ENDCOLOR, __VA_ARGS__) + +#define WOLF_WARN(...) \ + locked_cout(wolf::io::CoutColor::MAGENTA, __VA_ARGS__) + +#define WOLF_ERROR(...) \ + locked_cout(wolf::io::CoutColor::RED, __VA_ARGS__) + +#define WOLF_PRINT_COLOR_COND(cond, ...) \ + if (cond) locked_cout(__VA_ARGS__) + +#define WOLF_INFO_COND(cond, ...) \ + if (cond) locked_cout(cond, wolf::io::CoutColor::ENDCOLOR, __VA_ARGS__) + +#define WOLF_WARN_COND(...) \ + if (cond) locked_cout(cond, wolf::io::CoutColor::MAGENTA, __VA_ARGS__) + +#define WOLF_ERROR_COND(...) \ + if (cond) locked_cout(cond, wolf::io::CoutColor::RED, __VA_ARGS__) + +} // namespace wolf + +#endif /* WOLF_MULTI_THREADING_UTILS_H_ */ -- GitLab