diff --git a/common/include/villas/boxes.hpp b/common/include/villas/boxes.hpp index 7c1243f7a..17ce65ae4 100644 --- a/common/include/villas/boxes.hpp +++ b/common/include/villas/boxes.hpp @@ -17,35 +17,35 @@ // E.g. a cross can be constructed by combining all line fragments: // BOX_UDLR #if 0 // Alternate character set - #define BOX(chr) "\e(0" chr "\e(B" - #define BOX_LR BOX("\x71") // Boxdrawing: ─ - #define BOX_UD BOX("\x78") // Boxdrawing: │ - #define BOX_UDR BOX("\x74") // Boxdrawing: ├ - #define BOX_UDLR BOX("\x6E") // Boxdrawing: ┼ - #define BOX_UDL BOX("\x75") // Boxdrawing: ┤ - #define BOX_ULR BOX("\x76") // Boxdrawing: ┴ - #define BOX_UL BOX("\x6A") // Boxdrawing: ┘ - #define BOX_DLR BOX("\x77") // Boxdrawing: ┘ - #define BOX_DL BOX("\x6B") // Boxdrawing: ┘ -#elif 1 // UTF-8 - #define BOX_LR "─" // Boxdrawing: ─ - #define BOX_UD "│" // Boxdrawing: │ - #define BOX_UDR "├" // Boxdrawing: ├ - #define BOX_UDLR "┼" // Boxdrawing: ┼ - #define BOX_UDL "┤" // Boxdrawing: ┤ - #define BOX_ULR "┴" // Boxdrawing: ┴ - #define BOX_UL "┘" // Boxdrawing: ┘ - #define BOX_DLR "┬" // Boxdrawing: ┘ - #define BOX_DL "┐" // Boxdrawing: ┘ - #define BOX_UR "└" // Boxdrawing: └ -#else // ASCII - #define BOX_LR "-" // Boxdrawing: ─ - #define BOX_UD "|" // Boxdrawing: │ - #define BOX_UDR "+" // Boxdrawing: ├ - #define BOX_UDLR "+" // Boxdrawing: ┼ - #define BOX_UDL "+" // Boxdrawing: ┤ - #define BOX_ULR "+" // Boxdrawing: ┴ - #define BOX_UL "+" // Boxdrawing: ┘ - #define BOX_DLR "+" // Boxdrawing: ┘ - #define BOX_DL "+" // Boxdrawing: ┘ +#define BOX(chr) "\e(0" chr "\e(B" +#define BOX_LR BOX("\x71") // Boxdrawing: ─ +#define BOX_UD BOX("\x78") // Boxdrawing: │ +#define BOX_UDR BOX("\x74") // Boxdrawing: ├ +#define BOX_UDLR BOX("\x6E") // Boxdrawing: ┼ +#define BOX_UDL BOX("\x75") // Boxdrawing: ┤ +#define BOX_ULR BOX("\x76") // Boxdrawing: ┴ +#define BOX_UL BOX("\x6A") // Boxdrawing: ┘ +#define BOX_DLR BOX("\x77") // Boxdrawing: ┘ +#define BOX_DL BOX("\x6B") // Boxdrawing: ┘ +#elif 1 // UTF-8 +#define BOX_LR "─" // Boxdrawing: ─ +#define BOX_UD "│" // Boxdrawing: │ +#define BOX_UDR "├" // Boxdrawing: ├ +#define BOX_UDLR "┼" // Boxdrawing: ┼ +#define BOX_UDL "┤" // Boxdrawing: ┤ +#define BOX_ULR "┴" // Boxdrawing: ┴ +#define BOX_UL "┘" // Boxdrawing: ┘ +#define BOX_DLR "┬" // Boxdrawing: ┘ +#define BOX_DL "┐" // Boxdrawing: ┘ +#define BOX_UR "└" // Boxdrawing: └ +#else // ASCII +#define BOX_LR "-" // Boxdrawing: ─ +#define BOX_UD "|" // Boxdrawing: │ +#define BOX_UDR "+" // Boxdrawing: ├ +#define BOX_UDLR "+" // Boxdrawing: ┼ +#define BOX_UDL "+" // Boxdrawing: ┤ +#define BOX_ULR "+" // Boxdrawing: ┴ +#define BOX_UL "+" // Boxdrawing: ┘ +#define BOX_DLR "+" // Boxdrawing: ┘ +#define BOX_DL "+" // Boxdrawing: ┘ #endif diff --git a/common/include/villas/buffer.hpp b/common/include/villas/buffer.hpp index 015c5095c..949e9ca61 100644 --- a/common/include/villas/buffer.hpp +++ b/common/include/villas/buffer.hpp @@ -18,28 +18,20 @@ namespace villas { class Buffer : public std::vector { protected: - static - int callback(const char *data, size_t len, void *ctx); + static int callback(const char *data, size_t len, void *ctx); public: - Buffer(const char *buf, size_type len) : - std::vector(buf, buf+len) - { } + Buffer(const char *buf, size_type len) : std::vector(buf, buf + len) {} - Buffer(size_type count = 0) : - std::vector(count, 0) - { } + Buffer(size_type count = 0) : std::vector(count, 0) {} - // Encode JSON document /p j and append it to the buffer - int encode(json_t *j, int flags = 0); + // Encode JSON document /p j and append it to the buffer + int encode(json_t *j, int flags = 0); - // Decode JSON document from the beginning of the buffer - json_t * decode(); + // Decode JSON document from the beginning of the buffer + json_t *decode(); - void append(const char *data, size_t len) - { - insert(end(), data, data + len); - } + void append(const char *data, size_t len) { insert(end(), data, data + len); } }; } // namespace villas diff --git a/common/include/villas/colors.hpp b/common/include/villas/colors.hpp index e98f58d42..d960e5c45 100644 --- a/common/include/villas/colors.hpp +++ b/common/include/villas/colors.hpp @@ -10,22 +10,22 @@ #include // CPP stringification -#define XSTR(x) STR(x) -#define STR(x) #x +#define XSTR(x) STR(x) +#define STR(x) #x // Some color escape codes for pretty log messages #ifdef LOG_COLOR_DISABLE - #define CLR(clr, str) str +#define CLR(clr, str) str #else - #define CLR(clr, str) "\e[" XSTR(clr) "m" str "\e[0m" +#define CLR(clr, str) "\e[" XSTR(clr) "m" str "\e[0m" #endif -#define CLR_GRY(str) CLR(30, str) // Print str in gray -#define CLR_RED(str) CLR(31, str) // Print str in red -#define CLR_GRN(str) CLR(32, str) // Print str in green -#define CLR_YEL(str) CLR(33, str) // Print str in yellow -#define CLR_BLU(str) CLR(34, str) // Print str in blue -#define CLR_MAG(str) CLR(35, str) // Print str in magenta -#define CLR_CYN(str) CLR(36, str) // Print str in cyan -#define CLR_WHT(str) CLR(37, str) // Print str in white -#define CLR_BLD(str) CLR( 1, str) // Print str in bold +#define CLR_GRY(str) CLR(30, str) // Print str in gray +#define CLR_RED(str) CLR(31, str) // Print str in red +#define CLR_GRN(str) CLR(32, str) // Print str in green +#define CLR_YEL(str) CLR(33, str) // Print str in yellow +#define CLR_BLU(str) CLR(34, str) // Print str in blue +#define CLR_MAG(str) CLR(35, str) // Print str in magenta +#define CLR_CYN(str) CLR(36, str) // Print str in cyan +#define CLR_WHT(str) CLR(37, str) // Print str in white +#define CLR_BLD(str) CLR(1, str) // Print str in bold diff --git a/common/include/villas/common.hpp b/common/include/villas/common.hpp index 0ed06b273..b0eb92429 100644 --- a/common/include/villas/common.hpp +++ b/common/include/villas/common.hpp @@ -11,20 +11,20 @@ // Common states for most objects in VILLAScommon (paths, nodes, hooks, plugins) enum class State { - DESTROYED = 0, - INITIALIZED = 1, - PARSED = 2, - CHECKED = 3, - STARTED = 4, - STOPPED = 5, - PENDING_CONNECT = 6, - CONNECTED = 7, - PAUSED = 8, - STARTING = 9, - STOPPING = 10, - PAUSING = 11, - RESUMING = 12, - PREPARED = 13 + DESTROYED = 0, + INITIALIZED = 1, + PARSED = 2, + CHECKED = 3, + STARTED = 4, + STOPPED = 5, + PENDING_CONNECT = 6, + CONNECTED = 7, + PAUSED = 8, + STARTING = 9, + STOPPING = 10, + PAUSING = 11, + RESUMING = 12, + PREPARED = 13 }; // Callback to destroy list elements. diff --git a/common/include/villas/compat.hpp b/common/include/villas/compat.hpp index ea65fe85a..757e46ae8 100644 --- a/common/include/villas/compat.hpp +++ b/common/include/villas/compat.hpp @@ -18,26 +18,27 @@ int json_dumpfd(const json_t *json, int output, size_t flags); json_t *json_loadfd(int input, size_t flags, json_error_t *error); #endif -#if defined(WITH_CONFIG) && (LIBCONFIG_VER_MAJOR <= 1) && (LIBCONFIG_VER_MINOR < 5) - #include +#if defined(WITH_CONFIG) && (LIBCONFIG_VER_MAJOR <= 1) && \ + (LIBCONFIG_VER_MINOR < 5) +#include - #define config_setting_lookup config_lookup_from +#define config_setting_lookup config_lookup_from #endif #ifdef __MACH__ - #include +#include - #define le16toh(x) OSSwapLittleToHostInt16(x) - #define le32toh(x) OSSwapLittleToHostInt32(x) - #define le64toh(x) OSSwapLittleToHostInt64(x) - #define be16toh(x) OSSwapBigToHostInt16(x) - #define be32toh(x) OSSwapBigToHostInt32(x) - #define be64toh(x) OSSwapBigToHostInt64(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define be16toh(x) OSSwapBigToHostInt16(x) +#define be32toh(x) OSSwapBigToHostInt32(x) +#define be64toh(x) OSSwapBigToHostInt64(x) - #define htole16(x) OSSwapHostToLittleInt16(x) - #define htole32(x) OSSwapHostToLittleInt32(x) - #define htole64(x) OSSwapHostToLittleInt64(x) - #define htobe16(x) OSSwapHostToBigInt16(x) - #define htobe32(x) OSSwapHostToBigInt32(x) - #define htobe64(x) OSSwapHostToBigInt64(x) +#define htole16(x) OSSwapHostToLittleInt16(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define htole64(x) OSSwapHostToLittleInt64(x) +#define htobe16(x) OSSwapHostToBigInt16(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htobe64(x) OSSwapHostToBigInt64(x) #endif // __MACH__ diff --git a/common/include/villas/cpuset.hpp b/common/include/villas/cpuset.hpp index f68884327..11547daed 100644 --- a/common/include/villas/cpuset.hpp +++ b/common/include/villas/cpuset.hpp @@ -9,8 +9,8 @@ #ifdef __linux__ -#include #include +#include #include @@ -20,153 +20,104 @@ namespace utils { class CpuSet { protected: - cpu_set_t *setp; + cpu_set_t *setp; - unsigned num_cpus; - size_t sz; + unsigned num_cpus; + size_t sz; public: + CpuSet() : num_cpus(sizeof(uintmax_t) * 8), sz(CPU_ALLOC_SIZE(num_cpus)) { - CpuSet() : - num_cpus(sizeof(uintmax_t) * 8), - sz(CPU_ALLOC_SIZE(num_cpus)) - { + setp = CPU_ALLOC(num_cpus); + if (!setp) + throw MemoryAllocationError(); - setp = CPU_ALLOC(num_cpus); - if (!setp) - throw MemoryAllocationError(); + zero(); + } - zero(); - } + // Parses string with list of CPU ranges. + // + // @param str Human readable representation of the set. + CpuSet(const std::string &str); - // Parses string with list of CPU ranges. - // - // @param str Human readable representation of the set. - CpuSet(const std::string &str); + CpuSet(const char *str); - CpuSet(const char *str); + // Convert integer to cpu_set_t. + // + // @param set An integer number which is used as the mask + CpuSet(uintmax_t set); - // Convert integer to cpu_set_t. - // - // @param set An integer number which is used as the mask - CpuSet(uintmax_t set); + // Convert cpu_set_t to an integer. */ + operator uintmax_t(); - // Convert cpu_set_t to an integer. */ - operator uintmax_t(); + operator const cpu_set_t *() { return setp; } - operator const cpu_set_t*() - { - return setp; - } + // Returns human readable representation of the cpuset. + // + // The output format is a list of CPUs with ranges (for example, "0,1,3-9"). + operator std::string(); - // Returns human readable representation of the cpuset. - // - // The output format is a list of CPUs with ranges (for example, "0,1,3-9"). - operator std::string(); + ~CpuSet() { CPU_FREE(setp); } - ~CpuSet() - { - CPU_FREE(setp); - } + CpuSet(const CpuSet &src) : CpuSet(src.num_cpus) { + memcpy(setp, src.setp, sz); + } - CpuSet(const CpuSet &src) : - CpuSet(src.num_cpus) - { - memcpy(setp, src.setp, sz); - } + bool empty() const { return count() == 0; } - bool empty() const - { - return count() == 0; - } + bool full() const { return count() == num_cpus; } - bool full() const - { - return count() == num_cpus; - } + unsigned count() const { return CPU_COUNT_S(sz, setp); } - unsigned count() const - { - return CPU_COUNT_S(sz, setp); - } + void zero() { CPU_ZERO_S(sz, setp); } - void zero() - { - CPU_ZERO_S(sz, setp); - } + size_t size() const { return sz; } - size_t size() const - { - return sz; - } + CpuSet operator~() { + CpuSet full = UINTMAX_MAX; - CpuSet operator~() - { - CpuSet full = UINTMAX_MAX; + return full ^ *this; + } - return full ^ *this; - } + bool operator==(const CpuSet &rhs) { return CPU_EQUAL_S(sz, setp, rhs.setp); } - bool operator==(const CpuSet &rhs) - { - return CPU_EQUAL_S(sz, setp, rhs.setp); - } + CpuSet &operator&=(const CpuSet &rhs) { + CPU_AND_S(sz, setp, setp, rhs.setp); + return *this; + } - CpuSet & operator&=(const CpuSet &rhs) - { - CPU_AND_S(sz, setp, setp, rhs.setp); - return *this; - } + CpuSet &operator|=(const CpuSet &rhs) { + CPU_OR_S(sz, setp, setp, rhs.setp); + return *this; + } - CpuSet & operator|=(const CpuSet &rhs) - { - CPU_OR_S(sz, setp, setp, rhs.setp); - return *this; - } + CpuSet &operator^=(const CpuSet &rhs) { + CPU_XOR_S(sz, setp, setp, rhs.setp); + return *this; + } - CpuSet & operator^=(const CpuSet &rhs) - { - CPU_XOR_S(sz, setp, setp, rhs.setp); - return *this; - } + friend CpuSet operator&(CpuSet lhs, const CpuSet &rhs) { + lhs &= rhs; + return lhs; + } - friend CpuSet operator&(CpuSet lhs, const CpuSet &rhs) - { - lhs &= rhs; - return lhs; - } + friend CpuSet operator|(CpuSet lhs, const CpuSet &rhs) { + lhs |= rhs; + return lhs; + } - friend CpuSet operator|(CpuSet lhs, const CpuSet &rhs) - { - lhs |= rhs; - return lhs; - } + friend CpuSet operator^(CpuSet lhs, const CpuSet &rhs) { + lhs ^= rhs; + return lhs; + } - friend CpuSet operator^(CpuSet lhs, const CpuSet &rhs) - { - lhs ^= rhs; - return lhs; - } + bool operator[](size_t cpu) const { return isSet(cpu); } - bool operator[](size_t cpu) const - { - return isSet(cpu); - } + bool isSet(size_t cpu) const { return CPU_ISSET_S(cpu, sz, setp); } - bool isSet(size_t cpu) const - { - return CPU_ISSET_S(cpu, sz, setp); - } + void clear(size_t cpu) { CPU_CLR_S(cpu, sz, setp); } - void clear(size_t cpu) - { - CPU_CLR_S(cpu, sz, setp); - } - - void set(size_t cpu) - { - CPU_SET_S(cpu, sz, setp); - } + void set(size_t cpu) { CPU_SET_S(cpu, sz, setp); } }; } // namespace utils diff --git a/common/include/villas/dsp/exponential_window.hpp b/common/include/villas/dsp/exponential_window.hpp index f6a1d8928..a5e89d727 100644 --- a/common/include/villas/dsp/exponential_window.hpp +++ b/common/include/villas/dsp/exponential_window.hpp @@ -12,25 +12,20 @@ namespace villas { namespace dsp { -template -class ExponentialWindow { +template class ExponentialWindow { protected: - T a; - T last; + T a; + T last; public: - ExponentialWindow(T _a, T i = 0) : - a(a), - last(i) - { } + ExponentialWindow(T _a, T i = 0) : a(a), last(i) {} - T update(T in) - { - last = a * in + (1 - a) * last; + T update(T in) { + last = a * in + (1 - a) * last; - return last; - } + return last; + } }; } // namespace dsp diff --git a/common/include/villas/dsp/moving_average_window.hpp b/common/include/villas/dsp/moving_average_window.hpp index 449c0880a..d91b9127b 100644 --- a/common/include/villas/dsp/moving_average_window.hpp +++ b/common/include/villas/dsp/moving_average_window.hpp @@ -13,27 +13,22 @@ namespace villas { namespace dsp { -template -class MovingAverageWindow : public Window { +template class MovingAverageWindow : public Window { protected: - T state; + T state; public: - MovingAverageWindow(size_t len, T i = 0) : - Window(len, i), - state(i) - { } + MovingAverageWindow(size_t len, T i = 0) : Window(len, i), state(i) {} - T update(T in) - { - T out = Window::update(in); + T update(T in) { + T out = Window::update(in); - state += in; - state -= out; + state += in; + state -= out; - return state / (double) Window::getLength(); - } + return state / (double)Window::getLength(); + } }; } // namespace dsp diff --git a/common/include/villas/dsp/pid.hpp b/common/include/villas/dsp/pid.hpp index 3c452af80..74d82d1bc 100644 --- a/common/include/villas/dsp/pid.hpp +++ b/common/include/villas/dsp/pid.hpp @@ -13,26 +13,26 @@ namespace dsp { class PID { protected: - double dt; - double max; - double min; - double Kp; - double Kd; - double Ki; - double pre_error; - double integral; + double dt; + double max; + double min; + double Kp; + double Kd; + double Ki; + double pre_error; + double integral; public: - // Kp - proportional gain - // Ki - Integral gain - // Kd - derivative gain - // dt - loop interval time - // max - maximum value of manipulated variable - // min - minimum value of manipulated variable - PID(double _dt, double _max, double _min, double _Kp, double _Kd, double _Ki); + // Kp - proportional gain + // Ki - Integral gain + // Kd - derivative gain + // dt - loop interval time + // max - maximum value of manipulated variable + // min - minimum value of manipulated variable + PID(double _dt, double _max, double _min, double _Kp, double _Kd, double _Ki); - // Returns the manipulated variable given a setpoint and current process value - double calculate(double setpoint, double pv); + // Returns the manipulated variable given a setpoint and current process value + double calculate(double setpoint, double pv); }; } // namespace dsp diff --git a/common/include/villas/dsp/window.hpp b/common/include/villas/dsp/window.hpp index 716bcb104..51a4c580c 100644 --- a/common/include/villas/dsp/window.hpp +++ b/common/include/villas/dsp/window.hpp @@ -12,79 +12,61 @@ namespace villas { namespace dsp { -template> +template > class Window : protected Container { public: - using iterator = typename Container::iterator; - using size_type = typename Container::size_type; + using iterator = typename Container::iterator; + using size_type = typename Container::size_type; protected: + virtual T filter(T in, size_type i) const { return in; } - virtual - T filter(T in, size_type i) const - { - return in; - } + class transform_iterator : public Container::const_iterator { + protected: + const Window *window; - class transform_iterator : public Container::const_iterator { - protected: - const Window *window; + using base_iterator = typename Container::const_iterator; - using base_iterator = typename Container::const_iterator; + public: + transform_iterator(const Window *w) + : base_iterator(w->Container::begin()), window(w) {} - public: - transform_iterator(const Window *w) : - base_iterator(w->Container::begin()), - window(w) - { } + T operator*() { + auto i = (*this) - window->begin(); + const auto &v = base_iterator::operator*(); - T operator*() - { - auto i = (*this) - window->begin(); - const auto &v = base_iterator::operator*(); - - return window->filter(v, i); - } - }; + return window->filter(v, i); + } + }; public: - Window(size_type l = 0, T i = 0) : - Container(l, i) - { } + Window(size_type l = 0, T i = 0) : Container(l, i) {} - T val(size_type pos) - { - return this->Container::operator[](pos); - } + T val(size_type pos) { return this->Container::operator[](pos); } - T update(T in) - { - Container::push_back(in); + T update(T in) { + Container::push_back(in); - auto out = (*this)[0]; + auto out = (*this)[0]; - Container::pop_front(); + Container::pop_front(); - return out; - } + return out; + } - // Expose a limited number of functions from deque + // Expose a limited number of functions from deque - using Container::size; - using Container::end; + using Container::end; + using Container::size; - transform_iterator begin() const noexcept - { - return transform_iterator(this); - } + transform_iterator begin() const noexcept { return transform_iterator(this); } - T operator[](size_type i) const noexcept - { - auto v = Container::operator[](i); + T operator[](size_type i) const noexcept { + auto v = Container::operator[](i); - return filter(v, i); - } + return filter(v, i); + } }; } // namespace dsp diff --git a/common/include/villas/dsp/window_cosine.hpp b/common/include/villas/dsp/window_cosine.hpp index dcd3cc688..96b5d75ba 100644 --- a/common/include/villas/dsp/window_cosine.hpp +++ b/common/include/villas/dsp/window_cosine.hpp @@ -16,97 +16,82 @@ namespace villas { namespace dsp { -template// a0 = 1.0, double a1 = 0.0, double a2 = 0.0, double a3 = 0.0, double a4 = 0.0> +template < + typename T> // a0 = 1.0, double a1 = 0.0, double a2 = 0.0, double a3 = 0.0, double a4 = 0.0> class CosineWindow : public Window { public: - using size_type = typename Window::size_type; + using size_type = typename Window::size_type; protected: - std::vector coefficients; + std::vector coefficients; - T correctionFactor; + T correctionFactor; - virtual - T filter(T in, size_type i) const - { - return in * coefficients[i]; - } + virtual T filter(T in, size_type i) const { return in * coefficients[i]; } public: - CosineWindow(double a0, double a1, double a2, double a3, double a4, size_type len, T i = 0) : - Window(len, i), - coefficients(len), - correctionFactor(0) - { - for (unsigned i = 0; i < len; i++) { - coefficients[i] = a0 - - a1 * cos(2 * M_PI * i / len) - + a2 * cos(4 * M_PI * i / len) - - a3 * cos(6 * M_PI * i / len) - + a4 * cos(8 * M_PI * i / len); + CosineWindow(double a0, double a1, double a2, double a3, double a4, + size_type len, T i = 0) + : Window(len, i), coefficients(len), correctionFactor(0) { + for (unsigned i = 0; i < len; i++) { + coefficients[i] = + a0 - a1 * cos(2 * M_PI * i / len) + a2 * cos(4 * M_PI * i / len) - + a3 * cos(6 * M_PI * i / len) + a4 * cos(8 * M_PI * i / len); - correctionFactor += coefficients[i]; - } + correctionFactor += coefficients[i]; + } - correctionFactor /= len; - } + correctionFactor /= len; + } - virtual - T getCorrectionFactor() const - { - return correctionFactor; - } + virtual T getCorrectionFactor() const { return correctionFactor; } }; // From: https://en.wikipedia.org/wiki/Window_function#Cosine-sum_windows -template -class RectangularWindow : public CosineWindow { +template class RectangularWindow : public CosineWindow { public: - RectangularWindow(typename Window::size_type len, T i = 0) : - CosineWindow(1, 0., 0., 0., 0., len, i) {} + RectangularWindow(typename Window::size_type len, T i = 0) + : CosineWindow(1, 0., 0., 0., 0., len, i) {} }; -template -class HannWindow : public CosineWindow { +template class HannWindow : public CosineWindow { public: - HannWindow(typename Window::size_type len, T i = 0) : - CosineWindow(0.5, 0.5, 0., 0., 0., len, i) {} + HannWindow(typename Window::size_type len, T i = 0) + : CosineWindow(0.5, 0.5, 0., 0., 0., len, i) {} }; -template -class HammingWindow : public CosineWindow { +template class HammingWindow : public CosineWindow { public: - HammingWindow(typename Window::size_type len, T i = 0) : - CosineWindow(25./46, 1 - 25./46, 0., 0., 0., len, i) {} + HammingWindow(typename Window::size_type len, T i = 0) + : CosineWindow(25. / 46, 1 - 25. / 46, 0., 0., 0., len, i) {} }; -template -class FlattopWindow : public CosineWindow { +template class FlattopWindow : public CosineWindow { public: - FlattopWindow(typename Window::size_type len, T i = 0) : - CosineWindow(0.21557895, 0.41663158, 0.277263158, 0.083578947, 0.006947368, len, i) {} + FlattopWindow(typename Window::size_type len, T i = 0) + : CosineWindow(0.21557895, 0.41663158, 0.277263158, 0.083578947, + 0.006947368, len, i) {} }; -template -class NuttallWindow : public CosineWindow { +template class NuttallWindow : public CosineWindow { public: - NuttallWindow(typename Window::size_type len, T i = 0) : - CosineWindow(0.355768, 0.487396, 0.144232, 0.012604, 0., len, i) {} + NuttallWindow(typename Window::size_type len, T i = 0) + : CosineWindow(0.355768, 0.487396, 0.144232, 0.012604, 0., len, i) {} }; -template -class BlackmanWindow : public CosineWindow { +template class BlackmanWindow : public CosineWindow { public: - BlackmanWindow(typename Window::size_type len, T i = 0) : - CosineWindow(0.3635819, 0.4891775, 0.1365995, 0.0106411, 0., len, i) {} + BlackmanWindow(typename Window::size_type len, T i = 0) + : CosineWindow(0.3635819, 0.4891775, 0.1365995, 0.0106411, 0., len, + i) {} }; } // namespace dsp diff --git a/common/include/villas/exceptions.hpp b/common/include/villas/exceptions.hpp index c2402a54f..93677cdd2 100644 --- a/common/include/villas/exceptions.hpp +++ b/common/include/villas/exceptions.hpp @@ -7,11 +7,11 @@ #pragma once -#include +#include #include +#include #include #include -#include #include #include @@ -23,151 +23,125 @@ namespace villas { class SystemError : public std::system_error { public: - SystemError(const std::string &what) : - std::system_error( - errno, - std::system_category(), - what - ) - { } + SystemError(const std::string &what) + : std::system_error(errno, std::system_category(), what) {} - template - SystemError(const std::string &what, Args&&... args) : - SystemError(fmt::format(what, std::forward(args)...)) - { } + template + SystemError(const std::string &what, Args &&...args) + : SystemError(fmt::format(what, std::forward(args)...)) {} }; class RuntimeError : public std::runtime_error { public: - template - RuntimeError(const std::string &what, Args&&... args) : - std::runtime_error(fmt::format(what, std::forward(args)...)) - { } + template + RuntimeError(const std::string &what, Args &&...args) + : std::runtime_error(fmt::format(what, std::forward(args)...)) {} }; class MemoryAllocationError : public RuntimeError { public: - MemoryAllocationError() : - RuntimeError("Failed to allocate memory") - { } + MemoryAllocationError() : RuntimeError("Failed to allocate memory") {} }; class JsonError : public std::runtime_error { protected: - const json_t *setting; - json_error_t error; + const json_t *setting; + json_error_t error; public: - template - JsonError(const json_t *s, const json_error_t &e, const std::string &what = std::string(), Args&&... args) : - std::runtime_error(fmt::format(what, std::forward(args)...)), - setting(s), - error(e) - { } + template + JsonError(const json_t *s, const json_error_t &e, + const std::string &what = std::string(), Args &&...args) + : std::runtime_error(fmt::format(what, std::forward(args)...)), + setting(s), error(e) {} - virtual - const char * what() const noexcept - { - return fmt::format("{}: {} in {}:{}:{}", - std::runtime_error::what(), - error.text, error.source, error.line, error.column - ).c_str(); - } + virtual const char *what() const noexcept { + return fmt::format("{}: {} in {}:{}:{}", std::runtime_error::what(), + error.text, error.source, error.line, error.column) + .c_str(); + } }; class ConfigError : public std::runtime_error { protected: - // A setting-id referencing the setting. - std::string id; - json_t *setting; - json_error_t error; + // A setting-id referencing the setting. + std::string id; + json_t *setting; + json_error_t error; - char *msg; + char *msg; - std::string getMessage() const - { - std::stringstream ss; + std::string getMessage() const { + std::stringstream ss; - ss << std::runtime_error::what() << std::endl; + ss << std::runtime_error::what() << std::endl; - if (error.position >= 0) { - ss << std::endl; - ss << " " << error.text << " in " << error.source << ":" << error.line << ":" << error.column << std::endl; - } + if (error.position >= 0) { + ss << std::endl; + ss << " " << error.text << " in " << error.source << ":" << error.line + << ":" << error.column << std::endl; + } - ss << std::endl << " Please consult the user documentation for details: " << std::endl; - ss << " " << docUri(); + ss << std::endl + << " Please consult the user documentation for details: " << std::endl; + ss << " " << docUri(); - ss << std::endl; + ss << std::endl; - return ss.str(); - } + return ss.str(); + } public: - ~ConfigError() - { - if (msg) - free(msg); - } + ~ConfigError() { + if (msg) + free(msg); + } - template - ConfigError(json_t *s, const std::string &i, const std::string &what = "Failed to parse configuration") : - std::runtime_error(what), - id(i), - setting(s) - { - error.position = -1; + template + ConfigError(json_t *s, const std::string &i, + const std::string &what = "Failed to parse configuration") + : std::runtime_error(what), id(i), setting(s) { + error.position = -1; - msg = strdup(getMessage().c_str()); - } + msg = strdup(getMessage().c_str()); + } - template - ConfigError(json_t *s, const std::string &i, const std::string &what, Args&&... args) : - std::runtime_error(fmt::format(what, std::forward(args)...)), - id(i), - setting(s) - { - error.position = -1; + template + ConfigError(json_t *s, const std::string &i, const std::string &what, + Args &&...args) + : std::runtime_error(fmt::format(what, std::forward(args)...)), + id(i), setting(s) { + error.position = -1; - msg = strdup(getMessage().c_str()); - } + msg = strdup(getMessage().c_str()); + } - template - ConfigError(json_t *s, const json_error_t &e, const std::string &i, const std::string &what = "Failed to parse configuration") : - std::runtime_error(what), - id(i), - setting(s), - error(e) - { - msg = strdup(getMessage().c_str()); - } + template + ConfigError(json_t *s, const json_error_t &e, const std::string &i, + const std::string &what = "Failed to parse configuration") + : std::runtime_error(what), id(i), setting(s), error(e) { + msg = strdup(getMessage().c_str()); + } - template - ConfigError(json_t *s, const json_error_t &e, const std::string &i, const std::string &what, Args&&... args) : - std::runtime_error(fmt::format(what, std::forward(args)...)), - id(i), - setting(s), - error(e) - { - msg = strdup(getMessage().c_str()); - } + template + ConfigError(json_t *s, const json_error_t &e, const std::string &i, + const std::string &what, Args &&...args) + : std::runtime_error(fmt::format(what, std::forward(args)...)), + id(i), setting(s), error(e) { + msg = strdup(getMessage().c_str()); + } - std::string docUri() const - { - std::string baseUri = "https://villas.fein-aachen.org/doc/jump?"; + std::string docUri() const { + std::string baseUri = "https://villas.fein-aachen.org/doc/jump?"; - return baseUri + id; - } + return baseUri + id; + } - virtual - const char * what() const noexcept - { - return msg; - } + virtual const char *what() const noexcept { return msg; } }; } // namespace villas diff --git a/common/include/villas/graph/directed.hpp b/common/include/villas/graph/directed.hpp index 239f5618e..ce19ef0db 100644 --- a/common/include/villas/graph/directed.hpp +++ b/common/include/villas/graph/directed.hpp @@ -7,274 +7,248 @@ #pragma once -#include +#include +#include #include +#include #include #include -#include -#include #include -#include +#include -#include -#include #include +#include +#include namespace villas { namespace graph { -template +template class DirectedGraph { public: + using VertexIdentifier = Vertex::Identifier; + using EdgeIdentifier = Edge::Identifier; + using Path = std::list; - using VertexIdentifier = Vertex::Identifier; - using EdgeIdentifier = Edge::Identifier; - using Path = std::list; + DirectedGraph(const std::string &name = "DirectedGraph") + : lastVertexId(0), lastEdgeId(0), logger(logging.get(name)) {} - DirectedGraph(const std::string &name = "DirectedGraph") : - lastVertexId(0), - lastEdgeId(0), - logger(logging.get(name)) - { } + std::shared_ptr getVertex(VertexIdentifier vertexId) const { + // Cannot use [] operator, because creates non-existing elements + // at() will throw std::out_of_range if element does not exist + return vertices.at(vertexId); + } - std::shared_ptr getVertex(VertexIdentifier vertexId) const - { - // Cannot use [] operator, because creates non-existing elements - // at() will throw std::out_of_range if element does not exist - return vertices.at(vertexId); - } + template + VertexIdentifier findVertex(UnaryPredicate p) { + for (auto &v : vertices) { + auto &vertexId = v.first; + auto &vertex = v.second; - template - VertexIdentifier findVertex(UnaryPredicate p) - { - for (auto &v : vertices) { - auto &vertexId = v.first; - auto &vertex = v.second; + if (p(vertex)) { + return vertexId; + } + } - if (p(vertex)) { - return vertexId; - } - } + throw std::out_of_range("vertex not found"); + } - throw std::out_of_range("vertex not found"); - } + std::shared_ptr getEdge(EdgeIdentifier edgeId) const { + if (edgeId >= lastEdgeId) + throw std::invalid_argument("edge doesn't exist"); - std::shared_ptr getEdge(EdgeIdentifier edgeId) const - { - if (edgeId >= lastEdgeId) - throw std::invalid_argument("edge doesn't exist"); + // Cannot use [] operator, because creates non-existing elements + // at() will throw std::out_of_range if element does not exist + return edges.at(edgeId); + } - // Cannot use [] operator, because creates non-existing elements - // at() will throw std::out_of_range if element does not exist - return edges.at(edgeId); - } + std::size_t getEdgeCount() const { return edges.size(); } - std::size_t getEdgeCount() const - { - return edges.size(); - } + std::size_t getVertexCount() const { return vertices.size(); } - std::size_t getVertexCount() const - { - return vertices.size(); - } + VertexIdentifier addVertex(std::shared_ptr vertex) { + vertex->id = lastVertexId++; - VertexIdentifier addVertex(std::shared_ptr vertex) - { - vertex->id = lastVertexId++; + logger->debug("New vertex: {}", vertex->toString()); + vertices[vertex->id] = vertex; - logger->debug("New vertex: {}", vertex->toString()); - vertices[vertex->id] = vertex; + return vertex->id; + } - return vertex->id; - } + EdgeIdentifier addEdge(std::shared_ptr edge, + VertexIdentifier fromVertexId, + VertexIdentifier toVertexId) { + // Allocate edge id + edge->id = lastEdgeId++; - EdgeIdentifier addEdge(std::shared_ptr edge, - VertexIdentifier fromVertexId, - VertexIdentifier toVertexId) - { - // Allocate edge id - edge->id = lastEdgeId++; + // Connect it + edge->from = fromVertexId; + edge->to = toVertexId; - // Connect it - edge->from = fromVertexId; - edge->to = toVertexId; + logger->debug("New edge {}: {} -> {}", edge->toString(), edge->from, + edge->to); - logger->debug("New edge {}: {} -> {}", edge->toString(), edge->from, edge->to); + // This is a directed graph, so only push edge to starting vertex + getVertex(edge->from)->edges.push_back(edge->id); - // This is a directed graph, so only push edge to starting vertex - getVertex(edge->from)->edges.push_back(edge->id); + // Add new edge to graph + edges[edge->id] = edge; - // Add new edge to graph - edges[edge->id] = edge; + return edge->id; + } - return edge->id; - } + EdgeIdentifier addDefaultEdge(VertexIdentifier fromVertexId, + VertexIdentifier toVertexId) { + // Create a new edge + std::shared_ptr edge(new EdgeType); - EdgeIdentifier addDefaultEdge(VertexIdentifier fromVertexId, - VertexIdentifier toVertexId) - { - // Create a new edge - std::shared_ptr edge(new EdgeType); + return addEdge(edge, fromVertexId, toVertexId); + } - return addEdge(edge, fromVertexId, toVertexId); - } + void removeEdge(EdgeIdentifier edgeId) { + auto edge = getEdge(edgeId); + auto startVertex = getVertex(edge->from); - void removeEdge(EdgeIdentifier edgeId) - { - auto edge = getEdge(edgeId); - auto startVertex = getVertex(edge->from); + // Remove edge only from starting vertex (this is a directed graph) + logger->debug("Remove edge {} from vertex {}", edgeId, edge->from); + startVertex->edges.remove(edgeId); - // Remove edge only from starting vertex (this is a directed graph) - logger->debug("Remove edge {} from vertex {}", edgeId, edge->from); - startVertex->edges.remove(edgeId); + logger->debug("Remove edge {}", edgeId); + edges.erase(edgeId); + } - logger->debug("Remove edge {}", edgeId); - edges.erase(edgeId); - } + void removeVertex(VertexIdentifier vertexId) { + // Delete every edge that start or ends at this vertex + auto it = edges.begin(); + while (it != edges.end()) { + auto &edgeId = it->first; + auto &edge = it->second; - void removeVertex(VertexIdentifier vertexId) - { - // Delete every edge that start or ends at this vertex - auto it = edges.begin(); - while (it != edges.end()) { - auto &edgeId = it->first; - auto &edge = it->second; + bool removeEdge = false; - bool removeEdge = false; + if (edge->to == vertexId) { + logger->debug("Remove edge {} from vertex {}'s edge list", edgeId, + edge->from); - if (edge->to == vertexId) { - logger->debug("Remove edge {} from vertex {}'s edge list", - edgeId, edge->from); + removeEdge = true; - removeEdge = true; + auto startVertex = getVertex(edge->from); + startVertex->edges.remove(edge->id); + } - auto startVertex = getVertex(edge->from); - startVertex->edges.remove(edge->id); + if ((edge->from == vertexId) or removeEdge) { + logger->debug("Remove edge {}", edgeId); + // Remove edge from global edge list + it = edges.erase(it); + } else + ++it; + } - } + logger->debug("Remove vertex {}", vertexId); + vertices.erase(vertexId); + lastVertexId--; + } - if ((edge->from == vertexId) or removeEdge) { - logger->debug("Remove edge {}", edgeId); - // Remove edge from global edge list - it = edges.erase(it); - } - else - ++it; - } + const std::list & + vertexGetEdges(VertexIdentifier vertexId) const { + return getVertex(vertexId)->edges; + } - logger->debug("Remove vertex {}", vertexId); - vertices.erase(vertexId); - lastVertexId--; - } + using check_path_fn = std::function; - const std::list& vertexGetEdges(VertexIdentifier vertexId) const - { - return getVertex(vertexId)->edges; - } + static bool checkPath(const Path &) { return true; } - using check_path_fn = std::function; + bool getPath(VertexIdentifier fromVertexId, VertexIdentifier toVertexId, + Path &path, check_path_fn pathCheckFunc = checkPath) { + if (fromVertexId == toVertexId) + // Arrived at the destination + return true; + else { + auto fromVertex = getVertex(fromVertexId); - static - bool checkPath(const Path&) - { - return true; - } + for (auto &edgeId : fromVertex->edges) { + auto edgeOfFromVertex = getEdge(edgeId); - bool getPath(VertexIdentifier fromVertexId, - VertexIdentifier toVertexId, - Path &path, - check_path_fn pathCheckFunc = checkPath) - { - if (fromVertexId == toVertexId) - // Arrived at the destination - return true; - else { - auto fromVertex = getVertex(fromVertexId); + // Loop detection + bool loop = false; + for (auto &edgeIdInPath : path) { + auto edgeInPath = getEdge(edgeIdInPath); + if (edgeInPath->from == edgeOfFromVertex->to) { + loop = true; + break; + } + } - for (auto &edgeId : fromVertex->edges) { - auto edgeOfFromVertex = getEdge(edgeId); + if (loop) { + logger->debug("Loop detected via edge {}", edgeId); + continue; + } - // Loop detection - bool loop = false; - for (auto &edgeIdInPath : path) { - auto edgeInPath = getEdge(edgeIdInPath); - if (edgeInPath->from == edgeOfFromVertex->to) { - loop = true; - break; - } - } + // Remember the path we're investigating to detect loops + path.push_back(edgeId); - if (loop) { - logger->debug("Loop detected via edge {}", edgeId); - continue; - } + // Recursive, depth-first search + if (getPath(edgeOfFromVertex->to, toVertexId, path, pathCheckFunc) and + pathCheckFunc(path)) + // Path found, we're done + return true; + else + // Tear down path that didn't lead to the destination + path.pop_back(); + } + } - // Remember the path we're investigating to detect loops - path.push_back(edgeId); + return false; + } - // Recursive, depth-first search - if (getPath(edgeOfFromVertex->to, toVertexId, path, pathCheckFunc) and pathCheckFunc(path)) - // Path found, we're done - return true; - else - // Tear down path that didn't lead to the destination - path.pop_back(); - } - } + void dump(const std::string &fileName = "") const { + logger->info("Vertices:"); + for (auto &v : vertices) { + auto &vertex = v.second; - return false; - } + // Format connected vertices into a list + std::stringstream ssEdges; + for (auto &edge : vertex->edges) { + ssEdges << getEdge(edge)->to << " "; + } - void dump(const std::string &fileName = "") const - { - logger->info("Vertices:"); - for (auto &v : vertices) { - auto &vertex = v.second; + logger->info(" {} connected to: {}", vertex->toString(), ssEdges.str()); + } - // Format connected vertices into a list - std::stringstream ssEdges; - for (auto &edge : vertex->edges) { - ssEdges << getEdge(edge)->to << " "; - } + std::fstream s(fileName, s.out | s.trunc); + if (s.is_open()) { + s << "digraph memgraph {" << std::endl; + } - logger->info(" {} connected to: {}", vertex->toString(), ssEdges.str()); - } + logger->info("Edges:"); + for (auto &e : edges) { + auto &edge = e.second; - std::fstream s(fileName, s.out | s.trunc); - if (s.is_open()) { - s << "digraph memgraph {" << std::endl; - } + logger->info(" {}: {} -> {}", edge->toString(), edge->from, edge->to); + if (s.is_open()) { + auto from = getVertex(edge->from); + auto to = getVertex(edge->to); - logger->info("Edges:"); - for (auto &e : edges) { - auto &edge = e.second; + s << std::dec; + s << " \"" << *from << "\" -> \"" << *to << "\"" + << " [label=\"" << *edge << "\"];" << std::endl; + } + } - logger->info(" {}: {} -> {}", edge->toString(), edge->from, edge->to); - if (s.is_open()) { - auto from = getVertex(edge->from); - auto to = getVertex(edge->to); - - s << std::dec; - s << " \"" << *from << "\" -> \"" << *to << "\"" - << " [label=\"" << *edge << "\"];" << std::endl; - } - } - - if (s.is_open()) { - s << "}" << std::endl; - s.close(); - } - } + if (s.is_open()) { + s << "}" << std::endl; + s.close(); + } + } protected: - VertexIdentifier lastVertexId; - EdgeIdentifier lastEdgeId; + VertexIdentifier lastVertexId; + EdgeIdentifier lastEdgeId; - std::map> vertices; - std::map> edges; + std::map> vertices; + std::map> edges; - Logger logger; + Logger logger; }; } // namespace graph diff --git a/common/include/villas/graph/edge.hpp b/common/include/villas/graph/edge.hpp index 6bfd235a9..37cf98dc9 100644 --- a/common/include/villas/graph/edge.hpp +++ b/common/include/villas/graph/edge.hpp @@ -11,43 +11,31 @@ namespace villas { namespace graph { class Edge { - template - friend class DirectedGraph; + template friend class DirectedGraph; public: - using Identifier = std::size_t; + using Identifier = std::size_t; - friend - std::ostream& operator<< (std::ostream &stream, const Edge &edge) - { - return stream << edge.id; - } + friend std::ostream &operator<<(std::ostream &stream, const Edge &edge) { + return stream << edge.id; + } - bool operator==(const Edge &other) - { - return this->id == other.id; - } + bool operator==(const Edge &other) { return this->id == other.id; } - Vertex::Identifier getVertexTo() const - { - return to; - } + Vertex::Identifier getVertexTo() const { return to; } - Vertex::Identifier getVertexFrom() const - { - return from; - } + Vertex::Identifier getVertexFrom() const { return from; } - std::string toString() { - std::stringstream ss; - ss << *this; - return ss.str(); - } + std::string toString() { + std::stringstream ss; + ss << *this; + return ss.str(); + } private: - Identifier id; - Vertex::Identifier from; - Vertex::Identifier to; + Identifier id; + Vertex::Identifier from; + Vertex::Identifier to; }; } // namespace graph diff --git a/common/include/villas/graph/vertex.hpp b/common/include/villas/graph/vertex.hpp index 7c9c690bc..ba65e2228 100644 --- a/common/include/villas/graph/vertex.hpp +++ b/common/include/villas/graph/vertex.hpp @@ -11,42 +11,31 @@ namespace villas { namespace graph { class Vertex { - template - friend class DirectedGraph; + template friend class DirectedGraph; public: - using Identifier = std::size_t; + using Identifier = std::size_t; - Vertex() : - id(0) - { } + Vertex() : id(0) {} - const Identifier& getIdentifier() const - { - return id; - } + const Identifier &getIdentifier() const { return id; } - friend - std::ostream& operator<<(std::ostream &stream, const Vertex &vertex) - { - return stream << vertex.id; - } + friend std::ostream &operator<<(std::ostream &stream, const Vertex &vertex) { + return stream << vertex.id; + } - bool operator==(const Vertex &other) - { - return this->id == other.id; - } + bool operator==(const Vertex &other) { return this->id == other.id; } - std::string toString() { - std::stringstream ss; - ss << *this; - return ss.str(); - } + std::string toString() { + std::stringstream ss; + ss << *this; + return ss.str(); + } private: - Identifier id; - // HACK: how to resolve this circular type dependency? - std::list edges; + Identifier id; + // HACK: how to resolve this circular type dependency? + std::list edges; }; } // namespace graph diff --git a/common/include/villas/hist.hpp b/common/include/villas/hist.hpp index 24761613a..a2c5c0b94 100644 --- a/common/include/villas/hist.hpp +++ b/common/include/villas/hist.hpp @@ -13,8 +13,8 @@ #include -#define HEIGHT (LOG_WIDTH - 55) -#define SEQ 17 +#define HEIGHT (LOG_WIDTH - 55) +#define SEQ 17 namespace villas { @@ -22,96 +22,78 @@ namespace villas { class Hist { public: - using cnt_t = uintmax_t; - using idx_t = std::vector::difference_type; + using cnt_t = uintmax_t; + using idx_t = std::vector::difference_type; - // Initialize struct Hist with supplied values and allocate memory for buckets. - Hist(int buckets = 0, cnt_t warmup = 0); + // Initialize struct Hist with supplied values and allocate memory for buckets. + Hist(int buckets = 0, cnt_t warmup = 0); - // Reset all counters and values back to zero. - void reset(); + // Reset all counters and values back to zero. + void reset(); - // Count a value within its corresponding bucket. - void put(double value); + // Count a value within its corresponding bucket. + void put(double value); - // Calcluate the variance of all counted values. - double getVar() const; + // Calcluate the variance of all counted values. + double getVar() const; - // Calculate the mean average of all counted values. - double getMean() const; + // Calculate the mean average of all counted values. + double getMean() const; - // Calculate the standard derivation of all counted values. - double getStddev() const; + // Calculate the standard derivation of all counted values. + double getStddev() const; - // Print all statistical properties of distribution including a graphilcal plot of the histogram. - void print(Logger logger, bool details) const; + // Print all statistical properties of distribution including a graphilcal plot of the histogram. + void print(Logger logger, bool details) const; - // Print ASCII style plot of histogram. - void plot(Logger logger) const; + // Print ASCII style plot of histogram. + void plot(Logger logger) const; - // Dump histogram data in Matlab format. - // - // @return The string containing the dump. The caller is responsible to free() the buffer. - char * dump() const; + // Dump histogram data in Matlab format. + // + // @return The string containing the dump. The caller is responsible to free() the buffer. + char *dump() const; - // Prints Matlab struct containing all infos to file. - int dumpMatlab(FILE *f) const; + // Prints Matlab struct containing all infos to file. + int dumpMatlab(FILE *f) const; - // Write the histogram in JSON format to fiel \p f. - int dumpJson(FILE *f) const; + // Write the histogram in JSON format to fiel \p f. + int dumpJson(FILE *f) const; - // Build a libjansson / JSON object of the histogram. - json_t * toJson() const; + // Build a libjansson / JSON object of the histogram. + json_t *toJson() const; - double getHigh() const - { - return high; - } + double getHigh() const { return high; } - double getLow() const - { - return low; - } + double getLow() const { return low; } - double getHighest() const - { - return highest; - } + double getHighest() const { return highest; } - double getLowest() const - { - return lowest; - } + double getLowest() const { return lowest; } - double getLast() const - { - return last; - } + double getLast() const { return last; } - cnt_t getTotal() const - { - return total; - } + cnt_t getTotal() const { return total; } protected: - double resolution; // The distance between two adjacent buckets. + double resolution; // The distance between two adjacent buckets. - double high; // The value of the highest bucket. - double low; // The value of the lowest bucket. + double high; // The value of the highest bucket. + double low; // The value of the lowest bucket. - double highest; // The highest value observed (may be higher than #high). - double lowest; // The lowest value observed (may be lower than #low). - double last; // The last value which has been put into the buckets. + double highest; // The highest value observed (may be higher than #high). + double lowest; // The lowest value observed (may be lower than #low). + double last; // The last value which has been put into the buckets. - cnt_t total; // Total number of counted values. - cnt_t warmup; // Number of values which are used during warmup phase. + cnt_t total; // Total number of counted values. + cnt_t warmup; // Number of values which are used during warmup phase. - cnt_t higher; // The number of values which are higher than #high. - cnt_t lower; // The number of values which are lower than #low. + cnt_t higher; // The number of values which are higher than #high. + cnt_t lower; // The number of values which are lower than #low. - std::vector data; // Bucket counters. + std::vector data; // Bucket counters. - double _m[2], _s[2]; // Private variables for online variance calculation. + double _m[2], _s[2]; // Private variables for online variance calculation. }; } // namespace villas diff --git a/common/include/villas/kernel/kernel.hpp b/common/include/villas/kernel/kernel.hpp index 787672ad0..30ad2800c 100644 --- a/common/include/villas/kernel/kernel.hpp +++ b/common/include/villas/kernel/kernel.hpp @@ -60,7 +60,7 @@ int getHugePageSize(); int get_cpu_frequency(uint64_t *freq); // Set SMP affinity of IRQ -int setIRQAffinity(unsigned irq, uintmax_t aff , uintmax_t *old); +int setIRQAffinity(unsigned irq, uintmax_t aff, uintmax_t *old); -} // namespace villas } // namespace kernel +} // namespace villas diff --git a/common/include/villas/kernel/pci.hpp b/common/include/villas/kernel/pci.hpp index 21b2787db..0e9f7a35c 100644 --- a/common/include/villas/kernel/pci.hpp +++ b/common/include/villas/kernel/pci.hpp @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include #include @@ -19,119 +19,105 @@ namespace villas { namespace kernel { namespace pci { -#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) -#define PCI_FUNC(devfn) ((devfn) & 0x07) +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define PCI_FUNC(devfn) ((devfn)&0x07) class Id { public: - Id(const std::string &str); + Id(const std::string &str); - Id(int vid = 0, int did = 0, int cc = 0) : - vendor(vid), - device(did), - class_code(cc) - { } + Id(int vid = 0, int did = 0, int cc = 0) + : vendor(vid), device(did), class_code(cc) {} - bool operator==(const Id &i); + bool operator==(const Id &i); - unsigned int vendor; - unsigned int device; - unsigned int class_code; + unsigned int vendor; + unsigned int device; + unsigned int class_code; }; class Slot { public: - Slot(const std::string &str); + Slot(const std::string &str); - Slot(int dom = 0, int b = 0, int dev = 0, int fcn = 0) : - domain(dom), - bus(b), - device(dev), - function(fcn) - { } + Slot(int dom = 0, int b = 0, int dev = 0, int fcn = 0) + : domain(dom), bus(b), device(dev), function(fcn) {} - bool operator==(const Slot &s); + bool operator==(const Slot &s); - unsigned int domain; - unsigned int bus; - unsigned int device; - unsigned int function; + unsigned int domain; + unsigned int bus; + unsigned int device; + unsigned int function; }; struct Region { - int num; - uintptr_t start; - uintptr_t end; - unsigned long long flags; + int num; + uintptr_t start; + uintptr_t end; + unsigned long long flags; }; class Device { public: - Device(Id i, Slot s) : - id(i), - slot(s), - log(logging.get("kernel:pci")) - { } + Device(Id i, Slot s) : id(i), slot(s), log(logging.get("kernel:pci")) {} - Device(Id i) : - id(i), - log(logging.get("kernel:pci")) - { } + Device(Id i) : id(i), log(logging.get("kernel:pci")) {} - Device(Slot s) : - slot(s), - log(logging.get("kernel:pci")) - { } + Device(Slot s) : slot(s), log(logging.get("kernel:pci")) {} - bool - operator==(const Device &other); + bool operator==(const Device &other); - // Get currently loaded driver for device - std::string getDriver() const; + // Get currently loaded driver for device + std::string getDriver() const; - // Bind a new LKM to the PCI device - bool attachDriver(const std::string &driver) const; + // Bind a new LKM to the PCI device + bool attachDriver(const std::string &driver) const; - // Return the IOMMU group of this PCI device or -1 if the device is not in a group - int getIommuGroup() const; + // Return the IOMMU group of this PCI device or -1 if the device is not in a group + int getIommuGroup() const; - std::list getRegions() const; + std::list getRegions() const; - // Write 32-bit BAR value from to the PCI configuration space - void writeBar(uint32_t addr, unsigned bar = 0); + // Write 32-bit BAR value from to the PCI configuration space + void writeBar(uint32_t addr, unsigned bar = 0); - // If BAR values in config space and in the kernel do not match, rewrite - // the BAR value of the kernel to PCIe config space - void rewriteBar(unsigned bar = 0); + // If BAR values in config space and in the kernel do not match, rewrite + // the BAR value of the kernel to PCIe config space + void rewriteBar(unsigned bar = 0); - // Read 32-bit BAR value from the PCI configuration space - uint32_t readBar(unsigned bar = 0) const; + // Read 32-bit BAR value from the PCI configuration space + uint32_t readBar(unsigned bar = 0) const; - // Read 32-bit BAR value from the devices resource file. - // This is what the kernel thinks the BAR should be. - uint32_t readHostBar(unsigned bar = 0) const; + // Read 32-bit BAR value from the devices resource file. + // This is what the kernel thinks the BAR should be. + uint32_t readHostBar(unsigned bar = 0) const; + + Id id; + Slot slot; - Id id; - Slot slot; private: - villas::Logger log; + villas::Logger log; protected: - std::fstream openSysFs(const std::string &subPath, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) const; + std::fstream + openSysFs(const std::string &subPath, + std::ios_base::openmode mode = std::ios_base::in | + std::ios_base::out) const; }; class DeviceList : public std::list> { public: - // Initialize Linux PCI handle. - // - // This search for all available PCI devices under /sys/bus/pci - DeviceList(); + // Initialize Linux PCI handle. + // + // This search for all available PCI devices under /sys/bus/pci + DeviceList(); - DeviceList::value_type lookupDevice(const Slot &s); + DeviceList::value_type lookupDevice(const Slot &s); - DeviceList::value_type lookupDevice(const Id &i); + DeviceList::value_type lookupDevice(const Id &i); - DeviceList::value_type lookupDevice(const Device &f); + DeviceList::value_type lookupDevice(const Device &f); }; } // namespace pci diff --git a/common/include/villas/kernel/rt.hpp b/common/include/villas/kernel/rt.hpp index 720535bbe..3fdf80b0f 100644 --- a/common/include/villas/kernel/rt.hpp +++ b/common/include/villas/kernel/rt.hpp @@ -29,6 +29,6 @@ void setPriority(int priority); // @retval false Kernel is not patched. bool isPreemptible(); -} // namespace villas -} // namespace kernel } // namespace rt +} // namespace kernel +} // namespace villas diff --git a/common/include/villas/kernel/vfio_container.hpp b/common/include/villas/kernel/vfio_container.hpp index 9d9ad2bc7..510f5f00e 100644 --- a/common/include/villas/kernel/vfio_container.hpp +++ b/common/include/villas/kernel/vfio_container.hpp @@ -12,8 +12,8 @@ #pragma once #include -#include #include +#include #include #include @@ -26,63 +26,57 @@ namespace vfio { // Backwards compatability with older kernels #ifdef VFIO_UPDATE_VADDR -static constexpr -size_t EXTENSION_SIZE = VFIO_UPDATE_VADDR+1; +static constexpr size_t EXTENSION_SIZE = VFIO_UPDATE_VADDR + 1; #elif defined(VFIO_UNMAP_ALL) -static constexpr -size_t EXTENSION_SIZE = VFIO_UNMAP_ALL+1; +static constexpr size_t EXTENSION_SIZE = VFIO_UNMAP_ALL + 1; #else -static constexpr -size_t EXTENSION_SIZE = VFIO_NOIOMMU_IOMMU+1; +static constexpr size_t EXTENSION_SIZE = VFIO_NOIOMMU_IOMMU + 1; #endif class Container { public: - Container(); + Container(); - // No copying allowed because we manage the vfio state in constructor and destructors - Container(Container const&) = delete; - void operator=(Container const&) = delete; + // No copying allowed because we manage the vfio state in constructor and destructors + Container(Container const &) = delete; + void operator=(Container const &) = delete; - ~Container(); + ~Container(); - void dump(); + void dump(); - void attachGroup(std::shared_ptr group); + void attachGroup(std::shared_ptr group); - std::shared_ptr attachDevice(const std::string& name, int groupIndex); - std::shared_ptr attachDevice(pci::Device &pdev); + std::shared_ptr attachDevice(const std::string &name, int groupIndex); + std::shared_ptr attachDevice(pci::Device &pdev); - // Map VM to an IOVA, which is accessible by devices in the container - // - // @param virt virtual address of memory - // @param phys IOVA where to map @p virt, -1 to use VFIO internal allocator - // @param length size of memory region in bytes - // @return IOVA address, UINTPTR_MAX on failure - uintptr_t memoryMap(uintptr_t virt, uintptr_t phys, size_t length); + // Map VM to an IOVA, which is accessible by devices in the container + // + // @param virt virtual address of memory + // @param phys IOVA where to map @p virt, -1 to use VFIO internal allocator + // @param length size of memory region in bytes + // @return IOVA address, UINTPTR_MAX on failure + uintptr_t memoryMap(uintptr_t virt, uintptr_t phys, size_t length); - // munmap() a region which has been mapped by vfio_map_region() - bool memoryUnmap(uintptr_t phys, size_t length); + // munmap() a region which has been mapped by vfio_map_region() + bool memoryUnmap(uintptr_t phys, size_t length); - bool isIommuEnabled() const - { - return this->hasIommu; - } + bool isIommuEnabled() const { return this->hasIommu; } private: - std::shared_ptr getOrAttachGroup(int index); + std::shared_ptr getOrAttachGroup(int index); - int fd; - int version; + int fd; + int version; - std::array extensions; - uint64_t iova_next; // Next free IOVA address - bool hasIommu; + std::array extensions; + uint64_t iova_next; // Next free IOVA address + bool hasIommu; - // All groups bound to this container - std::list> groups; + // All groups bound to this container + std::list> groups; - Logger log; + Logger log; }; } // namespace vfio diff --git a/common/include/villas/kernel/vfio_device.hpp b/common/include/villas/kernel/vfio_device.hpp index d396a9940..320f77e76 100644 --- a/common/include/villas/kernel/vfio_device.hpp +++ b/common/include/villas/kernel/vfio_device.hpp @@ -12,9 +12,9 @@ #pragma once #include -#include #include #include +#include #include #include @@ -28,74 +28,66 @@ namespace vfio { class Device { public: - Device(const std::string &name, int groupFileDescriptor, const kernel::pci::Device *pci_device = nullptr); - ~Device(); + Device(const std::string &name, int groupFileDescriptor, + const kernel::pci::Device *pci_device = nullptr); + ~Device(); - // No copying allowed because we manage the vfio state in constructor and destructors - Device(Device const&) = delete; - void operator=(Device const&) = delete; + // No copying allowed because we manage the vfio state in constructor and destructors + Device(Device const &) = delete; + void operator=(Device const &) = delete; - bool reset(); + bool reset(); std::string getName() { return name; }; // Map a device memory region to the application address space (e.g. PCI BARs) void* regionMap(size_t index); - // munmap() a region which has been mapped by vfio_map_region() - bool regionUnmap(size_t index); + // munmap() a region which has been mapped by vfio_map_region() + bool regionUnmap(size_t index); - // Get the size of a device memory region - size_t regionGetSize(size_t index); + // Get the size of a device memory region + size_t regionGetSize(size_t index); - // Enable memory accesses and bus mastering for PCI device - bool pciEnable(); + // Enable memory accesses and bus mastering for PCI device + bool pciEnable(); - int pciMsiInit(int efds[32]); - int pciMsiDeinit(int efds[32]); - bool pciMsiFind(int nos[32]); + int pciMsiInit(int efds[32]); + int pciMsiDeinit(int efds[32]); + bool pciMsiFind(int nos[32]); - bool isVfioPciDevice() const; - bool pciHotReset(); + bool isVfioPciDevice() const; + bool pciHotReset(); - int getFileDescriptor() const - { - return fd; - } + int getFileDescriptor() const { return fd; } - void dump(); + void dump(); - bool isAttachedToGroup() const - { - return attachedToGroup; - } + bool isAttachedToGroup() const { return attachedToGroup; } - void setAttachedToGroup() - { - this->attachedToGroup = true; - } + void setAttachedToGroup() { this->attachedToGroup = true; } private: - // Name of the device as listed under - // /sys/kernel/iommu_groups/[vfio_group::index]/devices/ - std::string name; + // Name of the device as listed under + // /sys/kernel/iommu_groups/[vfio_group::index]/devices/ + std::string name; - // VFIO device file descriptor - int fd; + // VFIO device file descriptor + int fd; - bool attachedToGroup; - int groupFd; + bool attachedToGroup; + int groupFd; - struct vfio_device_info info; + struct vfio_device_info info; - std::vector irqs; - std::vector regions; - std::vector mappings; + std::vector irqs; + std::vector regions; + std::vector mappings; - // libpci handle of the device - const kernel::pci::Device *pci_device; + // libpci handle of the device + const kernel::pci::Device *pci_device; - Logger log; + Logger log; }; } // namespace vfio diff --git a/common/include/villas/kernel/vfio_group.hpp b/common/include/villas/kernel/vfio_group.hpp index 66c9340e3..7c4fca580 100644 --- a/common/include/villas/kernel/vfio_group.hpp +++ b/common/include/villas/kernel/vfio_group.hpp @@ -12,8 +12,8 @@ #pragma once #include -#include #include +#include #include #include @@ -25,60 +25,50 @@ namespace villas { namespace kernel { namespace vfio { -#define VFIO_PATH "/dev/vfio/" -#define VFIO_DEV VFIO_PATH "vfio" +#define VFIO_PATH "/dev/vfio/" +#define VFIO_DEV VFIO_PATH "vfio" class Group { public: - Group(int index, bool iommuEnabled); - ~Group(); + Group(int index, bool iommuEnabled); + ~Group(); - // No copying allowed because we manage the vfio state in constructor and destructors - Group(Group const&) = delete; - void operator=(Group const&) = delete; + // No copying allowed because we manage the vfio state in constructor and destructors + Group(Group const &) = delete; + void operator=(Group const &) = delete; - void setAttachedToContainer() - { - attachedToContainer = true; - } + void setAttachedToContainer() { attachedToContainer = true; } - bool isAttachedToContainer() - { - return attachedToContainer; - } + bool isAttachedToContainer() { return attachedToContainer; } - int getFileDescriptor() - { - return fd; - } + int getFileDescriptor() { return fd; } - int getIndex() - { - return index; - } + int getIndex() { return index; } - std::shared_ptr attachDevice(std::shared_ptr device); - std::shared_ptr attachDevice(const std::string& name, const kernel::pci::Device *pci_device = nullptr); + std::shared_ptr attachDevice(std::shared_ptr device); + std::shared_ptr + attachDevice(const std::string &name, + const kernel::pci::Device *pci_device = nullptr); - bool checkStatus(); - void dump(); + bool checkStatus(); + void dump(); private: - // VFIO group file descriptor - int fd; + // VFIO group file descriptor + int fd; - // Index of the IOMMU group as listed under /sys/kernel/iommu_groups/ - int index; + // Index of the IOMMU group as listed under /sys/kernel/iommu_groups/ + int index; - bool attachedToContainer; + bool attachedToContainer; - // Status of group - struct vfio_group_status status; + // Status of group + struct vfio_group_status status; - // All devices owned by this group - std::list> devices; + // All devices owned by this group + std::list> devices; - Logger log; + Logger log; }; } // namespace vfio diff --git a/common/include/villas/list.hpp b/common/include/villas/list.hpp index 3bbc64b4f..f65f9c5e4 100644 --- a/common/include/villas/list.hpp +++ b/common/include/villas/list.hpp @@ -13,34 +13,33 @@ #pragma once -#include #include -#include #include +#include +#include #include -#define LIST_CHUNKSIZE 16 +#define LIST_CHUNKSIZE 16 // Static list initialization -#define LIST_INIT_STATIC(l) \ -__attribute__((constructor(105))) static \ -void UNIQUE(__ctor)() { \ - int ret __attribute__((unused)); \ - ret = list_init(l); \ -} \ -__attribute__((destructor(105))) static \ -void UNIQUE(__dtor)() { \ - int ret __attribute__((unused)); \ - ret = list_destroy(l, nullptr, false); \ -} +#define LIST_INIT_STATIC(l) \ + __attribute__((constructor(105))) static void UNIQUE(__ctor)() { \ + int ret __attribute__((unused)); \ + ret = list_init(l); \ + } \ + __attribute__((destructor(105))) static void UNIQUE(__dtor)() { \ + int ret __attribute__((unused)); \ + ret = list_destroy(l, nullptr, false); \ + } -#define list_length(list) ((list)->length) -#define list_at_safe(list, index) ((list)->length > index ? (list)->array[index] : nullptr) -#define list_at(list, index) ((list)->array[index]) +#define list_length(list) ((list)->length) +#define list_at_safe(list, index) \ + ((list)->length > index ? (list)->array[index] : nullptr) +#define list_at(list, index) ((list)->array[index]) -#define list_first(list) list_at(list, 0) -#define list_last(list) list_at(list, (list)->length-1) +#define list_first(list) list_at(list, 0) +#define list_last(list) list_at(list, (list)->length - 1) namespace villas { @@ -49,24 +48,25 @@ typedef int (*cmp_cb_t)(const void *, const void *); // The list data structure. struct List { - enum State state; // The state of this list. - void **array; // Array of pointers to list elements. - size_t capacity; // Size of list::array in elements. - size_t length; // Number of elements of list::array which are in use. - pthread_mutex_t lock; // A mutex to allow thread-safe accesses. + enum State state; // The state of this list. + void **array; // Array of pointers to list elements. + size_t capacity; // Size of list::array in elements. + size_t length; // Number of elements of list::array which are in use. + pthread_mutex_t lock; // A mutex to allow thread-safe accesses. }; // Initialize a list. // // @param l A pointer to the list data structure. -int list_init(struct List *l) __attribute__ ((warn_unused_result)); +int list_init(struct List *l) __attribute__((warn_unused_result)); // Destroy a list and call destructors for all list elements // // @param free free() all list members during when calling list_destroy() // @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed. // @param l A pointer to the list data structure. -int list_destroy(struct List *l, dtor_cb_t dtor = nullptr, bool free = false) __attribute__ ((warn_unused_result)); +int list_destroy(struct List *l, dtor_cb_t dtor = nullptr, bool free = false) + __attribute__((warn_unused_result)); // Append an element to the end of the list. void list_push(struct List *l, void *p); @@ -82,7 +82,7 @@ int list_remove(struct List *l, size_t idx); int list_insert(struct List *l, size_t idx, void *p); // Return the first element of the list for which cmp returns zero. -void * list_search(struct List *l, cmp_cb_t cmp, const void *ctx); +void *list_search(struct List *l, cmp_cb_t cmp, const void *ctx); // Returns the number of occurences for which cmp returns zero when called on all list elements. int list_count(struct List *l, cmp_cb_t cmp, void *ctx); @@ -109,24 +109,25 @@ void list_extend(struct List *l, size_t len, void *val); void list_filter(struct List *l, dtor_cb_t cb); // Lookup an element from the list based on a name. -template -T * list_lookup_name(struct List *l, const std::string &name) -{ - return (T *) list_search(l, [](const void *a, const void *b) -> int { - auto *e = reinterpret_cast(a); - auto *s = reinterpret_cast(b); +template +T *list_lookup_name(struct List *l, const std::string &name) { + return (T *)list_search( + l, + [](const void *a, const void *b) -> int { + auto *e = reinterpret_cast(a); + auto *s = reinterpret_cast(b); - return *s == e->name ? 0 : 1; - }, &name); + return *s == e->name ? 0 : 1; + }, + &name); } // Lookup index of list element based on name. -template -ssize_t list_lookup_index(struct List *l, const std::string &name) -{ - auto *f = list_lookup_name(l, name); +template +ssize_t list_lookup_index(struct List *l, const std::string &name) { + auto *f = list_lookup_name(l, name); - return f ? list_index(l, f) : -1; + return f ? list_index(l, f) : -1; } } // namespace villas diff --git a/common/include/villas/log.hpp b/common/include/villas/log.hpp index eccc81510..b61ec611a 100644 --- a/common/include/villas/log.hpp +++ b/common/include/villas/log.hpp @@ -8,13 +8,13 @@ #pragma once -#include #include +#include -#include +#include #include #include -#include +#include #include @@ -25,75 +25,68 @@ class Log; using Logger = std::shared_ptr; -extern -Log logging; +extern Log logging; class Log { public: - using Level = spdlog::level::level_enum; - using DefaultSink = std::shared_ptr; - using DistSink = std::shared_ptr; - using Formatter = std::shared_ptr; + using Level = spdlog::level::level_enum; + using DefaultSink = std::shared_ptr; + using DistSink = std::shared_ptr; + using Formatter = std::shared_ptr; - class Expression { - public: - std::string name; - Level level; + class Expression { + public: + std::string name; + Level level; - Expression(const std::string &n, Level lvl) : - name(n), - level(lvl) - { } + Expression(const std::string &n, Level lvl) : name(n), level(lvl) {} - Expression(json_t *json); - }; + Expression(json_t *json); + }; protected: - DistSink sinks; - DefaultSink sink; - Formatter formatter; + DistSink sinks; + DefaultSink sink; + Formatter formatter; - Level level; + Level level; - std::string pattern; // Logging format. - std::string prefix; // Prefix each line with this string. + std::string pattern; // Logging format. + std::string prefix; // Prefix each line with this string. - std::list expressions; + std::list expressions; public: + Log(Level level = Level::info); - Log(Level level = Level::info); + // Get the real usable log output width which fits into one line. + int getWidth(); - // Get the real usable log output width which fits into one line. - int getWidth(); + void parse(json_t *json); - void parse(json_t *json); + Logger get(const std::string &name); - Logger get(const std::string &name); + void setFormatter(const std::string &pattern, const std::string &pfx = ""); + void setLevel(Level lvl); + void setLevel(const std::string &lvl); - void setFormatter(const std::string &pattern, const std::string &pfx = ""); - void setLevel(Level lvl); - void setLevel(const std::string &lvl); + Level getLevel() const; + std::string getLevelName() const; - Level getLevel() const; - std::string getLevelName() const; + void addSink(std::shared_ptr sink) { + sink->set_formatter(formatter->clone()); + sink->set_level(level); - void addSink(std::shared_ptr sink) - { - sink->set_formatter(formatter->clone()); - sink->set_level(level); + sinks->add_sink(sink); + } - sinks->add_sink(sink); - } + void replaceStdSink(std::shared_ptr sink) { + sink->set_formatter(formatter->clone()); + sink->set_level(level); - void replaceStdSink(std::shared_ptr sink) - { - sink->set_formatter(formatter->clone()); - sink->set_level(level); - - sinks->sinks()[0] = sink; - } + sinks->sinks()[0] = sink; + } }; } // namespace villas diff --git a/common/include/villas/memory.hpp b/common/include/villas/memory.hpp index 3939d5602..fbd1a4ee1 100644 --- a/common/include/villas/memory.hpp +++ b/common/include/villas/memory.hpp @@ -21,34 +21,26 @@ namespace villas { // reside anywhere and represent different types of memory. class MemoryBlock { public: - using deallocator_fn = std::function; + using deallocator_fn = std::function; - using Ptr = std::shared_ptr; - using UniquePtr = std::unique_ptr; + using Ptr = std::shared_ptr; + using UniquePtr = std::unique_ptr; - // cppcheck-suppress passedByValue - MemoryBlock(size_t offset, size_t size, MemoryManager::AddressSpaceId addrSpaceId) : - offset(offset), size(size), addrSpaceId(addrSpaceId) {} + // cppcheck-suppress passedByValue + MemoryBlock(size_t offset, size_t size, + MemoryManager::AddressSpaceId addrSpaceId) + : offset(offset), size(size), addrSpaceId(addrSpaceId) {} - MemoryManager::AddressSpaceId getAddrSpaceId() const - { - return addrSpaceId; - } + MemoryManager::AddressSpaceId getAddrSpaceId() const { return addrSpaceId; } - size_t getSize() const - { - return size; - } + size_t getSize() const { return size; } - size_t getOffset() const - { - return offset; - } + size_t getOffset() const { return offset; } protected: - size_t offset; // Offset (or address) inside address space - size_t size; // Size in bytes of this block - MemoryManager::AddressSpaceId addrSpaceId; // Identifier in memory graph + size_t offset; // Offset (or address) inside address space + size_t size; // Size in bytes of this block + MemoryManager::AddressSpaceId addrSpaceId; // Identifier in memory graph }; // Wrapper for a MemoryBlock to access the underlying memory directly @@ -60,59 +52,54 @@ protected: // with a moved unique pointer. Otherwise, it just stores a reference to the // memory block and it's the users responsibility to take care that the memory // block is valid. -template -class MemoryAccessor { +template class MemoryAccessor { public: - using Type = T; + using Type = T; - // Take ownership of the MemoryBlock - MemoryAccessor(std::unique_ptr mem) : - translation(MemoryManager::get().getTranslationFromProcess(mem->getAddrSpaceId())), - memoryBlock(std::move(mem)) - { } + // Take ownership of the MemoryBlock + MemoryAccessor(std::unique_ptr mem) + : translation(MemoryManager::get().getTranslationFromProcess( + mem->getAddrSpaceId())), + memoryBlock(std::move(mem)) {} - // Just act as an accessor, do not take ownership of MemoryBlock - MemoryAccessor(const MemoryBlock &mem) : - translation(MemoryManager::get().getTranslationFromProcess(mem.getAddrSpaceId())) - { } + // Just act as an accessor, do not take ownership of MemoryBlock + MemoryAccessor(const MemoryBlock &mem) + : translation(MemoryManager::get().getTranslationFromProcess( + mem.getAddrSpaceId())) {} - MemoryAccessor(const MemoryTranslation &translation) : - translation(translation) - { } + MemoryAccessor(const MemoryTranslation &translation) + : translation(translation) {} - T & operator*() const - { - return *reinterpret_cast(translation.getLocalAddr(0)); - } + T &operator*() const { + return *reinterpret_cast(translation.getLocalAddr(0)); + } - T & operator[](size_t idx) const - { - const size_t offset = sizeof(T) * idx; - return *reinterpret_cast(translation.getLocalAddr(offset)); - } + T &operator[](size_t idx) const { + const size_t offset = sizeof(T) * idx; + return *reinterpret_cast(translation.getLocalAddr(offset)); + } - T* operator&() const - { - return reinterpret_cast(translation.getLocalAddr(0)); - } + T *operator&() const { + return reinterpret_cast(translation.getLocalAddr(0)); + } - T* operator->() const - { - return reinterpret_cast(translation.getLocalAddr(0)); - } + T *operator->() const { + return reinterpret_cast(translation.getLocalAddr(0)); + } - const MemoryBlock& - getMemoryBlock() const - { - if (not memoryBlock) throw std::bad_alloc(); else return *memoryBlock; - } + const MemoryBlock &getMemoryBlock() const { + if (not memoryBlock) + throw std::bad_alloc(); + else + return *memoryBlock; + } private: - // Cached memory translation for fast access - MemoryTranslation translation; + // Cached memory translation for fast access + MemoryTranslation translation; - // Take the unique pointer in case user wants this class to have ownership - std::unique_ptr memoryBlock; + // Take the unique pointer in case user wants this class to have ownership + std::unique_ptr memoryBlock; }; // Base memory allocator @@ -121,101 +108,89 @@ private: // The concept is explained here at [1]. // // [1] https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern -template -class BaseAllocator { +template class BaseAllocator { public: - // memoryAddrSpaceId: memory that is managed by this allocator - BaseAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId) : - memoryAddrSpaceId(memoryAddrSpaceId) - { - // CRTP - derivedAlloc = static_cast(this); - std::string loggerName = fmt::format("memory:", derivedAlloc->getName()); - logger = logging.get(loggerName); + // memoryAddrSpaceId: memory that is managed by this allocator + BaseAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId) + : memoryAddrSpaceId(memoryAddrSpaceId) { + // CRTP + derivedAlloc = static_cast(this); + std::string loggerName = fmt::format("memory:", derivedAlloc->getName()); + logger = logging.get(loggerName); - // Default deallocation callback - free = [&](MemoryBlock* mem) { - logger->warn("no free callback defined for addr space {}, not freeing", - mem->getAddrSpaceId()); + // Default deallocation callback + free = [&](MemoryBlock *mem) { + logger->warn("no free callback defined for addr space {}, not freeing", + mem->getAddrSpaceId()); - removeMemoryBlock(*mem); - }; - } + removeMemoryBlock(*mem); + }; + } - BaseAllocator(std::unique_ptr mem) : - BaseAllocator(mem->getAddrSpaceId()) - { - // cppcheck-suppress useInitializationList - memoryBlock = std::move(mem); - derivedAlloc = nullptr; - } + BaseAllocator(std::unique_ptr mem) + : BaseAllocator(mem->getAddrSpaceId()) { + // cppcheck-suppress useInitializationList + memoryBlock = std::move(mem); + derivedAlloc = nullptr; + } - virtual - std::unique_ptr + virtual std::unique_ptr - allocateBlock(size_t size) = 0; + allocateBlock(size_t size) = 0; - template - MemoryAccessor - allocate(size_t num) - { - if (num == 0) { - // Doesn't make sense to allocate an empty block - logger->error("Trying to allocate empty memory"); - throw std::bad_alloc(); - } + template MemoryAccessor allocate(size_t num) { + if (num == 0) { + // Doesn't make sense to allocate an empty block + logger->error("Trying to allocate empty memory"); + throw std::bad_alloc(); + } - const size_t size = num * sizeof(T); - auto mem = allocateBlock(size); + const size_t size = num * sizeof(T); + auto mem = allocateBlock(size); - // Check if the allocated memory is really accessible by writing to the - // allocated memory and reading back. Exponentially increase offset to - // speed up testing. - MemoryAccessor byteAccessor(*mem); - size_t idx = 0; - for (int i = 0; idx < mem->getSize(); i++, idx = (1 << i)) { - auto val = static_cast(i); - byteAccessor[idx] = val; - if (byteAccessor[idx] != val) { - logger->error("Cannot access allocated memory"); - throw std::bad_alloc(); - } - } + // Check if the allocated memory is really accessible by writing to the + // allocated memory and reading back. Exponentially increase offset to + // speed up testing. + MemoryAccessor byteAccessor(*mem); + size_t idx = 0; + for (int i = 0; idx < mem->getSize(); i++, idx = (1 << i)) { + auto val = static_cast(i); + byteAccessor[idx] = val; + if (byteAccessor[idx] != val) { + logger->error("Cannot access allocated memory"); + throw std::bad_alloc(); + } + } - return MemoryAccessor(std::move(mem)); - } + return MemoryAccessor(std::move(mem)); + } protected: - void insertMemoryBlock(const MemoryBlock &mem) - { - auto & mm = MemoryManager::get(); - mm.createMapping(mem.getOffset(), 0, mem.getSize(), - derivedAlloc->getName(), - memoryAddrSpaceId, - mem.getAddrSpaceId()); - } + void insertMemoryBlock(const MemoryBlock &mem) { + auto &mm = MemoryManager::get(); + mm.createMapping(mem.getOffset(), 0, mem.getSize(), derivedAlloc->getName(), + memoryAddrSpaceId, mem.getAddrSpaceId()); + } - void removeMemoryBlock(const MemoryBlock &mem) - { - // This will also remove any mapping to and from the memory block - auto & mm = MemoryManager::get(); - mm.removeAddressSpace(mem.getAddrSpaceId()); - } + void removeMemoryBlock(const MemoryBlock &mem) { + // This will also remove any mapping to and from the memory block + auto &mm = MemoryManager::get(); + mm.removeAddressSpace(mem.getAddrSpaceId()); + } - MemoryManager::AddressSpaceId getAddrSpaceId() const - { - return memoryAddrSpaceId; - } + MemoryManager::AddressSpaceId getAddrSpaceId() const { + return memoryAddrSpaceId; + } - MemoryBlock::deallocator_fn free; - Logger logger; + MemoryBlock::deallocator_fn free; + Logger logger; - // Optional, if allocator should own the memory block - std::unique_ptr memoryBlock; + // Optional, if allocator should own the memory block + std::unique_ptr memoryBlock; private: - MemoryManager::AddressSpaceId memoryAddrSpaceId; - DerivedAllocator* derivedAlloc; + MemoryManager::AddressSpaceId memoryAddrSpaceId; + DerivedAllocator *derivedAlloc; }; // Linear memory allocator @@ -227,46 +202,35 @@ private: // together. class LinearAllocator : public BaseAllocator { public: - LinearAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId, - size_t memorySize, - size_t internalOffset = 0); + LinearAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId, + size_t memorySize, size_t internalOffset = 0); - LinearAllocator(std::unique_ptr mem) : - LinearAllocator(mem->getAddrSpaceId(), mem->getSize()) - { - memoryBlock = std::move(mem); - } + LinearAllocator(std::unique_ptr mem) + : LinearAllocator(mem->getAddrSpaceId(), mem->getSize()) { + memoryBlock = std::move(mem); + } - size_t getAvailableMemory() const - { - return memorySize - nextFreeAddress; - } + size_t getAvailableMemory() const { return memorySize - nextFreeAddress; } - size_t getSize() const - { - return memorySize; - } + size_t getSize() const { return memorySize; } - std::string getName() const; + std::string getName() const; - std::unique_ptr - allocateBlock(size_t size); + std::unique_ptr + allocateBlock(size_t size); private: - static constexpr - size_t alignBytes = sizeof(uintptr_t); - static constexpr - size_t alignMask = alignBytes - 1; + static constexpr size_t alignBytes = sizeof(uintptr_t); + static constexpr size_t alignMask = alignBytes - 1; - size_t getAlignmentPadding(uintptr_t addr) const - { - return (alignBytes - (addr & alignMask)) & alignMask; - } + size_t getAlignmentPadding(uintptr_t addr) const { + return (alignBytes - (addr & alignMask)) & alignMask; + } - size_t nextFreeAddress; // Next chunk will be allocated here - size_t memorySize; // Total size of managed memory - size_t internalOffset; // Offset in address space (usually 0) - size_t allocationCount; // Number of individual allocations present + size_t nextFreeAddress; // Next chunk will be allocated here + size_t memorySize; // Total size of managed memory + size_t internalOffset; // Offset in address space (usually 0) + size_t allocationCount; // Number of individual allocations present }; // Wrapper around mmap() to create villas memory blocks @@ -275,71 +239,48 @@ private: // host memory via the OS. class HostRam { public: - class HostRamAllocator : public BaseAllocator { - public: - HostRamAllocator(); + class HostRamAllocator : public BaseAllocator { + public: + HostRamAllocator(); - std::string getName() const - { - return "HostRamAlloc"; - } + std::string getName() const { return "HostRamAlloc"; } - std::unique_ptr - allocateBlock(size_t size); - }; + std::unique_ptr + allocateBlock(size_t size); + }; - static - HostRamAllocator& getAllocator() - { - return allocator; - } + static HostRamAllocator &getAllocator() { return allocator; } private: - static - HostRamAllocator allocator; + static HostRamAllocator allocator; }; class HostDmaRam { public: - class HostDmaRamAllocator : public LinearAllocator { - public: - HostDmaRamAllocator(int num); + class HostDmaRamAllocator : public LinearAllocator { + public: + HostDmaRamAllocator(int num); - virtual - ~HostDmaRamAllocator(); + virtual ~HostDmaRamAllocator(); - std::string getName() const - { - return getUdmaBufName(num); - } + std::string getName() const { return getUdmaBufName(num); } - private: - int num; - }; + private: + int num; + }; - static - HostDmaRamAllocator& - getAllocator(int num = 0); + static HostDmaRamAllocator &getAllocator(int num = 0); private: - static - std::map> allocators; + static std::map> allocators; - static - std::string - getUdmaBufName(int num); + static std::string getUdmaBufName(int num); - static - std::string - getUdmaBufBasePath(int num); + static std::string getUdmaBufBasePath(int num); - static - size_t - getUdmaBufBufSize(int num); + static size_t getUdmaBufBufSize(int num); - static - uintptr_t - getUdmaBufPhysAddr(int num); + static uintptr_t getUdmaBufPhysAddr(int num); }; } // namespace villas diff --git a/common/include/villas/memory_manager.hpp b/common/include/villas/memory_manager.hpp index 01a11b60c..eaca7775f 100644 --- a/common/include/villas/memory_manager.hpp +++ b/common/include/villas/memory_manager.hpp @@ -8,13 +8,13 @@ #pragma once #include -#include #include #include +#include #include -#include #include +#include namespace villas { @@ -25,43 +25,32 @@ namespace villas { // multiple hops (memory mappings). class MemoryTranslation { public: + // MemoryTranslation + // @param src Base address of local address space + // @param dst Base address of foreign address space + // @param size Size of "memory window" + MemoryTranslation(uintptr_t src, uintptr_t dst, size_t size) + : src(src), dst(dst), size(size) {} - // MemoryTranslation - // @param src Base address of local address space - // @param dst Base address of foreign address space - // @param size Size of "memory window" - MemoryTranslation(uintptr_t src, uintptr_t dst, size_t size) : - src(src), - dst(dst), - size(size) - { } + uintptr_t getLocalAddr(uintptr_t addrInForeignAddrSpace) const; - uintptr_t getLocalAddr(uintptr_t addrInForeignAddrSpace) const; + uintptr_t getForeignAddr(uintptr_t addrInLocalAddrSpace) const; - uintptr_t getForeignAddr(uintptr_t addrInLocalAddrSpace) const; + size_t getSize() const { return size; } - size_t getSize() const - { - return size; - } + friend std::ostream &operator<<(std::ostream &stream, + const MemoryTranslation &translation) { + return stream << std::hex << "(src=0x" << translation.src << ", dst=0x" + << translation.dst << ", size=0x" << translation.size << ")"; + } - friend - std::ostream& operator<< (std::ostream &stream, const MemoryTranslation &translation) - { - return stream << std::hex - << "(src=0x" << translation.src - << ", dst=0x" << translation.dst - << ", size=0x" << translation.size - << ")"; - } - - // Merge two MemoryTranslations together - MemoryTranslation &operator+=(const MemoryTranslation &other); + // Merge two MemoryTranslations together + MemoryTranslation &operator+=(const MemoryTranslation &other); private: - uintptr_t src; // Base address of local address space - uintptr_t dst; // Base address of foreign address space - size_t size; // Size of "memory window" + uintptr_t src; // Base address of local address space + uintptr_t dst; // Base address of foreign address space + size_t size; // Size of "memory window" }; // Global memory manager to resolve addresses across address spaces @@ -73,41 +62,39 @@ private: // memory mappings. class MemoryManager { private: - // This is a singleton, so private constructor ... - MemoryManager() : - memoryGraph("memory:graph"), - logger(logging.get("memory:manager")) - { - pathCheckFunc = [&](const MemoryGraph::Path &path) { - return this->pathCheck(path); - }; - } + // This is a singleton, so private constructor ... + MemoryManager() + : memoryGraph("memory:graph"), logger(logging.get("memory:manager")) { + pathCheckFunc = [&](const MemoryGraph::Path &path) { + return this->pathCheck(path); + }; + } - // ... and no copying or assigning - MemoryManager(const MemoryManager&) = delete; - MemoryManager &operator=(const MemoryManager&) = delete; + // ... and no copying or assigning + MemoryManager(const MemoryManager &) = delete; + MemoryManager &operator=(const MemoryManager &) = delete; - // Custom edge in memory graph representing a memory mapping - // - // A memory mapping maps from one address space into another and can only be - // traversed in the forward direction which reflects the nature of real - // memory mappings. - // - // Implementation Notes: - // The member #src is the address in the "from" address space, where the - // destination address space is mapped. The member #dest is the address in - // the destination address space, where the mapping points to. Often, #dest - // will be zero for mappings to hardware, but consider the example when - // mapping FPGA to application memory: - // The application allocates a block 1kB at address 0x843001000 in its - // address space. The mapping would then have a #dest address of 0x843001000 - // and a #size of 1024. - class Mapping : public graph::Edge { - public: - std::string name; // Human-readable name - uintptr_t src; // Base address in "from" address space - uintptr_t dest; // Base address in "to" address space - size_t size; // Size of the mapping + // Custom edge in memory graph representing a memory mapping + // + // A memory mapping maps from one address space into another and can only be + // traversed in the forward direction which reflects the nature of real + // memory mappings. + // + // Implementation Notes: + // The member #src is the address in the "from" address space, where the + // destination address space is mapped. The member #dest is the address in + // the destination address space, where the mapping points to. Often, #dest + // will be zero for mappings to hardware, but consider the example when + // mapping FPGA to application memory: + // The application allocates a block 1kB at address 0x843001000 in its + // address space. The mapping would then have a #dest address of 0x843001000 + // and a #size of 1024. + class Mapping : public graph::Edge { + public: + std::string name; // Human-readable name + uintptr_t src; // Base address in "from" address space + uintptr_t dest; // Base address in "to" address space + size_t size; // Size of the mapping friend std::ostream& operator<< (std::ostream &stream, const Mapping &mapping) @@ -125,129 +112,118 @@ private: { std::stringstream s; s << *this; - return s.str(); + return s.str(); } }; - // Custom vertex in memory graph representing an address space - // - // Since most information in the memory graph is stored in the edges (memory - // mappings), this is just a small extension to the default vertex. It only - // associates an additional string #name for human-readability. - class AddressSpace : public graph::Vertex { - public: - std::string name; // Human-readable name + // Custom vertex in memory graph representing an address space + // + // Since most information in the memory graph is stored in the edges (memory + // mappings), this is just a small extension to the default vertex. It only + // associates an additional string #name for human-readability. + class AddressSpace : public graph::Vertex { + public: + std::string name; // Human-readable name - friend std::ostream& - operator<< (std::ostream &stream, const AddressSpace &addrSpace) - { - return stream << static_cast(addrSpace) << " = " - << addrSpace.name; - } - }; + friend std::ostream &operator<<(std::ostream &stream, + const AddressSpace &addrSpace) { + return stream << static_cast(addrSpace) << " = " + << addrSpace.name; + } + }; - // Memory graph with custom edges and vertices for address resolution - using MemoryGraph = graph::DirectedGraph; + // Memory graph with custom edges and vertices for address resolution + using MemoryGraph = graph::DirectedGraph; public: - using AddressSpaceId = MemoryGraph::VertexIdentifier; - using MappingId = MemoryGraph::EdgeIdentifier; + using AddressSpaceId = MemoryGraph::VertexIdentifier; + using MappingId = MemoryGraph::EdgeIdentifier; - struct InvalidTranslation : public std::exception {}; + struct InvalidTranslation : public std::exception {}; - // Get singleton instance - static - MemoryManager& get(); + // Get singleton instance + static MemoryManager &get(); - MemoryGraph & getGraph() - { - return memoryGraph; - } + MemoryGraph &getGraph() { return memoryGraph; } - AddressSpaceId getProcessAddressSpace() - { - return getOrCreateAddressSpace("process"); - } + AddressSpaceId getProcessAddressSpace() { + return getOrCreateAddressSpace("process"); + } - AddressSpaceId getPciAddressSpace() - { - return getOrCreateAddressSpace("pcie"); - } + AddressSpaceId getPciAddressSpace() { + return getOrCreateAddressSpace("pcie"); + } - AddressSpaceId getProcessAddressSpaceMemoryBlock(const std::string &memoryBlock) - { - return getOrCreateAddressSpace(getSlaveAddrSpaceName("process", memoryBlock)); - } + AddressSpaceId + getProcessAddressSpaceMemoryBlock(const std::string &memoryBlock) { + return getOrCreateAddressSpace( + getSlaveAddrSpaceName("process", memoryBlock)); + } - AddressSpaceId getOrCreateAddressSpace(std::string name); + AddressSpaceId getOrCreateAddressSpace(std::string name); - void removeAddressSpace(const AddressSpaceId &addrSpaceId) - { - memoryGraph.removeVertex(addrSpaceId); - } + void removeAddressSpace(const AddressSpaceId &addrSpaceId) { + memoryGraph.removeVertex(addrSpaceId); + } - // Create a default mapping - MappingId createMapping(uintptr_t src, uintptr_t dest, size_t size, - const std::string &name, - AddressSpaceId fromAddrSpace, - AddressSpaceId toAddrSpace); + // Create a default mapping + MappingId createMapping(uintptr_t src, uintptr_t dest, size_t size, + const std::string &name, AddressSpaceId fromAddrSpace, + AddressSpaceId toAddrSpace); - // Add a mapping - // - // Can be used to derive from Mapping in order to implement custom - // constructor/destructor. - MappingId addMapping(std::shared_ptr mapping, - AddressSpaceId fromAddrSpace, - AddressSpaceId toAddrSpace); + // Add a mapping + // + // Can be used to derive from Mapping in order to implement custom + // constructor/destructor. + MappingId addMapping(std::shared_ptr mapping, + AddressSpaceId fromAddrSpace, + AddressSpaceId toAddrSpace); - AddressSpaceId findAddressSpace(const std::string &name); + AddressSpaceId findAddressSpace(const std::string &name); - std::list findPath(const AddressSpaceId &fromAddrSpaceId, const AddressSpaceId &toAddrSpaceId); + std::list findPath(const AddressSpaceId &fromAddrSpaceId, + const AddressSpaceId &toAddrSpaceId); - MemoryTranslation getTranslation(const AddressSpaceId &fromAddrSpaceId, const AddressSpaceId &toAddrSpaceId); + MemoryTranslation getTranslation(const AddressSpaceId &fromAddrSpaceId, + const AddressSpaceId &toAddrSpaceId); - // cppcheck-suppress passedByValue - MemoryTranslation getTranslationFromProcess(AddressSpaceId foreignAddrSpaceId) - { - return getTranslation(getProcessAddressSpace(), foreignAddrSpaceId); - } + // cppcheck-suppress passedByValue + MemoryTranslation + getTranslationFromProcess(AddressSpaceId foreignAddrSpaceId) { + return getTranslation(getProcessAddressSpace(), foreignAddrSpaceId); + } - static - std::string getSlaveAddrSpaceName(const std::string &ipInstance, const std::string &memoryBlock) - { - return ipInstance + "/" + memoryBlock; - } + static std::string getSlaveAddrSpaceName(const std::string &ipInstance, + const std::string &memoryBlock) { + return ipInstance + "/" + memoryBlock; + } - static - std::string getMasterAddrSpaceName(const std::string &ipInstance, const std::string &busInterface) - { - return ipInstance + ":" + busInterface; - } + static std::string getMasterAddrSpaceName(const std::string &ipInstance, + const std::string &busInterface) { + return ipInstance + ":" + busInterface; + } private: - // Convert a Mapping to MemoryTranslation for calculations - static - MemoryTranslation getTranslationFromMapping(const Mapping &mapping) - { - return MemoryTranslation(mapping.src, mapping.dest, mapping.size); - } + // Convert a Mapping to MemoryTranslation for calculations + static MemoryTranslation getTranslationFromMapping(const Mapping &mapping) { + return MemoryTranslation(mapping.src, mapping.dest, mapping.size); + } - bool pathCheck(const MemoryGraph::Path &path); + bool pathCheck(const MemoryGraph::Path &path); - // Directed graph that stores address spaces and memory mappings - MemoryGraph memoryGraph; + // Directed graph that stores address spaces and memory mappings + MemoryGraph memoryGraph; - // Cache mapping of names to address space ids for fast lookup - std::map addrSpaceLookup; + // Cache mapping of names to address space ids for fast lookup + std::map addrSpaceLookup; - // Logger for universal access in this class - Logger logger; + // Logger for universal access in this class + Logger logger; - MemoryGraph::check_path_fn pathCheckFunc; + MemoryGraph::check_path_fn pathCheckFunc; - // Static pointer to global instance, because this is a singleton - static - MemoryManager* instance; + // Static pointer to global instance, because this is a singleton + static MemoryManager *instance; }; } // namespace villas diff --git a/common/include/villas/plugin.hpp b/common/include/villas/plugin.hpp index 94b8946f5..284853e3a 100644 --- a/common/include/villas/plugin.hpp +++ b/common/include/villas/plugin.hpp @@ -9,13 +9,13 @@ #pragma once #include -#include -#include #include +#include #include +#include -#include #include +#include namespace villas { namespace plugin { @@ -24,163 +24,129 @@ namespace plugin { class Plugin; class Registry; -extern -Registry *registry; +extern Registry *registry; -template -using List = std::list; +template using List = std::list; class SubRegistry { public: - virtual - List<> lookup() = 0; + virtual List<> lookup() = 0; }; class Registry { protected: - List<> plugins; - List registries; + List<> plugins; + List registries; public: + Logger getLogger() { return logging.get("plugin:registry"); } - Logger getLogger() - { - return logging.get("plugin:registry"); - } + void add(Plugin *p) { plugins.push_back(p); } - void add(Plugin *p) - { - plugins.push_back(p); - } + void addSubRegistry(SubRegistry *sr) { registries.push_back(sr); } - void addSubRegistry(SubRegistry *sr) - { - registries.push_back(sr); - } + void remove(Plugin *p) { plugins.remove(p); } - void remove(Plugin *p) - { - plugins.remove(p); - } + // Get all plugins including sub-registries + List<> lookup() { + List<> all; - // Get all plugins including sub-registries - List<> lookup() { - List<> all; + all.insert(all.end(), plugins.begin(), plugins.end()); - all.insert(all.end(), plugins.begin(), plugins.end()); + for (auto r : registries) { + auto p = r->lookup(); - for (auto r : registries) { - auto p = r->lookup(); + all.insert(all.end(), p.begin(), p.end()); + } - all.insert(all.end(), p.begin(), p.end()); - } + return all; + } - return all; - } + // Get all plugins of specific type + template List lookup() { + List list; - // Get all plugins of specific type - template - List lookup() - { - List list; + for (Plugin *p : lookup()) { + T *t = dynamic_cast(p); + if (t) + list.push_back(t); + } - for (Plugin *p : lookup()) { - T *t = dynamic_cast(p); - if (t) - list.push_back(t); - } + // Sort alphabetically + list.sort( + [](const T *a, const T *b) { return a->getName() < b->getName(); }); - // Sort alphabetically - list.sort([](const T *a, const T *b) { - return a->getName() < b->getName(); - }); + return list; + } - return list; - } + // Get all plugins of specific type and name + template T *lookup(const std::string &name) { + for (T *p : lookup()) { + if (p->getName() != name) + continue; - // Get all plugins of specific type and name - template - T * lookup(const std::string &name) - { - for (T *p : lookup()) { - if (p->getName() != name) - continue; + return p; + } - return p; - } + return nullptr; + } - return nullptr; - } - - template - void dump(); + template void dump(); }; class Plugin { - friend plugin::Registry; + friend plugin::Registry; protected: - Logger logger; + Logger logger; public: - Plugin(); + Plugin(); - virtual - ~Plugin(); + virtual ~Plugin(); - // Copying a plugin doesn't make sense, so explicitly deny it - Plugin(Plugin const&) = delete; - void operator=(Plugin const&) = delete; + // Copying a plugin doesn't make sense, so explicitly deny it + Plugin(Plugin const &) = delete; + void operator=(Plugin const &) = delete; - virtual - void dump(); + virtual void dump(); - // Get plugin name - virtual - std::string getName() const = 0; + // Get plugin name + virtual std::string getName() const = 0; - // Get plugin type - virtual - std::string getType() const = 0; + // Get plugin type + virtual std::string getType() const = 0; - // Get plugin description - virtual - std::string getDescription() const = 0; + // Get plugin description + virtual std::string getDescription() const = 0; - virtual - Logger getLogger() - { - if (!logger) { - auto name = fmt::format("{}:{}", getType(), getName()); - logger = logging.get(name); - } + virtual Logger getLogger() { + if (!logger) { + auto name = fmt::format("{}:{}", getType(), getName()); + logger = logging.get(name); + } - return logger; - } - - // Custom formatter for spdlog - template - friend OStream &operator<<(OStream &os, const class Plugin &p) - { - return os << p.getName(); - } + return logger; + } + // Custom formatter for spdlog + template + friend OStream &operator<<(OStream &os, const class Plugin &p) { + return os << p.getName(); + } }; -template -void -Registry::dump() -{ - getLogger()->info("Available plugins:"); +template void Registry::dump() { + getLogger()->info("Available plugins:"); - for (Plugin *p : plugins) { - T *t = dynamic_cast(p); - if (t) - getLogger()->info(" - {}: {}", p->getName(), p->getDescription()); - } + for (Plugin *p : plugins) { + T *t = dynamic_cast(p); + if (t) + getLogger()->info(" - {}: {}", p->getName(), p->getDescription()); + } } } // namespace plugin diff --git a/common/include/villas/popen.hpp b/common/include/villas/popen.hpp index 612ef0e8f..9a5ef8c1e 100644 --- a/common/include/villas/popen.hpp +++ b/common/include/villas/popen.hpp @@ -11,11 +11,11 @@ #include -#include -#include #include -#include +#include #include +#include +#include namespace villas { namespace utils { @@ -23,90 +23,69 @@ namespace utils { class Popen { public: - using arg_list = std::vector; - using env_map = std::map; + using arg_list = std::vector; + using env_map = std::map; - using char_type = char; - using stdio_buf = __gnu_cxx::stdio_filebuf; + using char_type = char; + using stdio_buf = __gnu_cxx::stdio_filebuf; - Popen(const std::string &cmd, - const arg_list &args = arg_list(), - const env_map &env = env_map(), - const std::string &wd = std::string(), - bool shell = false); - ~Popen(); + Popen(const std::string &cmd, const arg_list &args = arg_list(), + const env_map &env = env_map(), const std::string &wd = std::string(), + bool shell = false); + ~Popen(); - void open(); - int close(); - void kill(int signal = SIGINT); + void open(); + int close(); + void kill(int signal = SIGINT); - int getFdIn() - { - return fd_in; - } + int getFdIn() { return fd_in; } - int getFdOut() - { - return fd_out; - } + int getFdOut() { return fd_out; } - pid_t getPid() const - { - return pid; - } + pid_t getPid() const { return pid; } protected: - std::string command; - std::string working_dir; - arg_list arguments; - env_map environment; - bool shell; - pid_t pid; + std::string command; + std::string working_dir; + arg_list arguments; + env_map environment; + bool shell; + pid_t pid; - int fd_in, fd_out; + int fd_in, fd_out; }; class PopenStream : public Popen { public: - PopenStream(const std::string &cmd, - const arg_list &args = arg_list(), - const env_map &env = env_map(), - const std::string &wd = std::string(), - bool shell = false); - ~PopenStream(); + PopenStream(const std::string &cmd, const arg_list &args = arg_list(), + const env_map &env = env_map(), + const std::string &wd = std::string(), bool shell = false); + ~PopenStream(); - std::istream &cin() - { - return *(input.stream); - } + std::istream &cin() { return *(input.stream); } - std::ostream &cout() - { - return *(output.stream); - } + std::ostream &cout() { return *(output.stream); } - void open(); - int close(); + void open(); + int close(); protected: + struct { + std::unique_ptr stream; + std::unique_ptr buffer; + } input; - struct { - std::unique_ptr stream; - std::unique_ptr buffer; - } input; - - struct { - std::unique_ptr stream; - std::unique_ptr buffer; - } output; + struct { + std::unique_ptr stream; + std::unique_ptr buffer; + } output; }; } // namespace utils } // namespace villas -template -std::istream &operator>>(villas::utils::PopenStream &po, T &value) -{ - return *(po.input.stream) >> value; +template +std::istream &operator>>(villas::utils::PopenStream &po, T &value) { + return *(po.input.stream) >> value; } diff --git a/common/include/villas/table.hpp b/common/include/villas/table.hpp index 3995598dd..555dd3141 100644 --- a/common/include/villas/table.hpp +++ b/common/include/villas/table.hpp @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include @@ -18,69 +18,52 @@ class Table; class TableColumn { - friend Table; + friend Table; public: - enum class Alignment { - LEFT, - RIGHT - }; + enum class Alignment { LEFT, RIGHT }; protected: - int _width; // The real width of this column. Calculated by Table::resize(). + int _width; // The real width of this column. Calculated by Table::resize(). - int width; // Width of the column. + int width; // Width of the column. public: - TableColumn(int w, enum Alignment a, const std::string &t, const std::string &f, const std::string &u = "") : - _width(0), - width(w), - title(t), - format(f), - unit(u), - align(a) - { } + TableColumn(int w, enum Alignment a, const std::string &t, + const std::string &f, const std::string &u = "") + : _width(0), width(w), title(t), format(f), unit(u), align(a) {} - std::string title; // The title as shown in the table header. - std::string format; // The format which is used to print the table rows. - std::string unit; // An optional unit which will be shown in the table header. + std::string title; // The title as shown in the table header. + std::string format; // The format which is used to print the table rows. + std::string unit; // An optional unit which will be shown in the table header. - enum Alignment align; + enum Alignment align; - int getWidth() const - { - return _width; - } + int getWidth() const { return _width; } }; class Table { protected: - int resize(int w); + int resize(int w); - int width; + int width; - std::vector columns; + std::vector columns; - Logger logger; + Logger logger; public: - Table(Logger log, const std::vector &cols) : - width(-1), - columns(cols), - logger(log) - { } + Table(Logger log, const std::vector &cols) + : width(-1), columns(cols), logger(log) {} - // Print a table header consisting of \p n columns. - void header(); + // Print a table header consisting of \p n columns. + void header(); - // Print table rows. - void row(int count, ...); + // Print table rows. + void row(int count, ...); - int getWidth() const - { - return width; - } + int getWidth() const { return width; } }; } // namespace villas diff --git a/common/include/villas/task.hpp b/common/include/villas/task.hpp index 9c9a8608f..3ef65461e 100644 --- a/common/include/villas/task.hpp +++ b/common/include/villas/task.hpp @@ -7,66 +7,66 @@ #pragma once -#include #include +#include #include // We can choose between two periodic task implementations //#define PERIODIC_TASK_IMPL NANOSLEEP -#define TIMERFD 1 -#define CLOCK_NANOSLEEP 2 -#define NANOSLEEP 3 -#define RDTSC 4 +#define TIMERFD 1 +#define CLOCK_NANOSLEEP 2 +#define NANOSLEEP 3 +#define RDTSC 4 #if defined(__MACH__) - #define PERIODIC_TASK_IMPL NANOSLEEP +#define PERIODIC_TASK_IMPL NANOSLEEP #elif defined(__linux__) - #define PERIODIC_TASK_IMPL TIMERFD +#define PERIODIC_TASK_IMPL TIMERFD #else - #error "Platform not supported" +#error "Platform not supported" #endif #if PERIODIC_TASK_IMPL == RDTSC - #include +#include #endif struct Task { - int clock; // CLOCK_{MONOTONIC,REALTIME} + int clock; // CLOCK_{MONOTONIC,REALTIME} -#if PERIODIC_TASK_IMPL == RDTSC // We use cycle counts in RDTSC mode - uint64_t period; - uint64_t next; +#if PERIODIC_TASK_IMPL == RDTSC // We use cycle counts in RDTSC mode + uint64_t period; + uint64_t next; #else - struct timespec period; // The period of periodic invations of this task - struct timespec next; // The timer value for the next invocation + struct timespec period; // The period of periodic invations of this task + struct timespec next; // The timer value for the next invocation #endif #if PERIODIC_TASK_IMPL == TIMERFD - int fd; // The timerfd_create(2) file descriptior. + int fd; // The timerfd_create(2) file descriptior. #elif PERIODIC_TASK_IMPL == RDTSC - struct Tsc tsc; // Initialized by tsc_init(). + struct Tsc tsc; // Initialized by tsc_init(). #endif - // Create a new task with the given rate. - Task(int clock = CLOCK_REALTIME); + // Create a new task with the given rate. + Task(int clock = CLOCK_REALTIME); - ~Task(); + ~Task(); - // Wait until task elapsed - // - // @retval 0 An error occured. Maybe the task was stopped. - // @retval >0 The nummer of runs this task already fired. - uint64_t wait(); + // Wait until task elapsed + // + // @retval 0 An error occured. Maybe the task was stopped. + // @retval >0 The nummer of runs this task already fired. + uint64_t wait(); - void setNext(const struct timespec *next); - void setTimeout(double to); - void setRate(double rate); + void setNext(const struct timespec *next); + void setTimeout(double to); + void setRate(double rate); - void stop(); + void stop(); - // Returns a poll'able file descriptor which becomes readable when the timer expires. - // - // Note: currently not supported on all platforms. - int getFD() const; + // Returns a poll'able file descriptor which becomes readable when the timer expires. + // + // Note: currently not supported on all platforms. + int getFD() const; }; diff --git a/common/include/villas/terminal.hpp b/common/include/villas/terminal.hpp index 65bd40a89..a564a459e 100644 --- a/common/include/villas/terminal.hpp +++ b/common/include/villas/terminal.hpp @@ -17,37 +17,31 @@ namespace villas { class Terminal { protected: - struct winsize window; // Size of the terminal window. + struct winsize window; // Size of the terminal window. - bool isTty; + bool isTty; - static - class Terminal *current; + static class Terminal *current; public: - Terminal(); + Terminal(); - // Signal handler for TIOCGWINSZ - static - void resize(int signal, siginfo_t *sinfo, void *ctx); + // Signal handler for TIOCGWINSZ + static void resize(int signal, siginfo_t *sinfo, void *ctx); - static - int getCols() - { - if (!current) - current = new Terminal(); + static int getCols() { + if (!current) + current = new Terminal(); - return current->window.ws_col; - } + return current->window.ws_col; + } - static - int getRows() - { - if (!current) - current = new Terminal(); + static int getRows() { + if (!current) + current = new Terminal(); - return current->window.ws_row; - } + return current->window.ws_row; + } }; } // namespace villas diff --git a/common/include/villas/timing.hpp b/common/include/villas/timing.hpp index df1468264..36f8ab8c4 100644 --- a/common/include/villas/timing.hpp +++ b/common/include/villas/timing.hpp @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include @@ -16,10 +16,12 @@ ssize_t time_cmp(const struct timespec *a, const struct timespec *b); // Get delta between two timespec structs. -struct timespec time_diff(const struct timespec *start, const struct timespec *end); +struct timespec time_diff(const struct timespec *start, + const struct timespec *end); // Get sum of two timespec structs. -struct timespec time_add(const struct timespec *start, const struct timespec *end); +struct timespec time_add(const struct timespec *start, + const struct timespec *end); // Return current time as a struct timespec. struct timespec time_now(); diff --git a/common/include/villas/tool.hpp b/common/include/villas/tool.hpp index 7247a0738..bbe4b72c4 100644 --- a/common/include/villas/tool.hpp +++ b/common/include/villas/tool.hpp @@ -7,10 +7,10 @@ #pragma once -#include #include #include #include +#include #include namespace villas { @@ -18,50 +18,36 @@ namespace villas { class Tool { protected: - Logger logger; + Logger logger; - int argc; - char **argv; + int argc; + char **argv; - std::string name; + std::string name; - static - Tool *current_tool; + static Tool *current_tool; - static - void staticHandler(int signal, siginfo_t *sinfo, void *ctx); + static void staticHandler(int signal, siginfo_t *sinfo, void *ctx); - virtual - void handler(int, siginfo_t *, void *) - { } + virtual void handler(int, siginfo_t *, void *) {} - std::list handlerSignals; + std::list handlerSignals; - static - void printCopyright(); + static void printCopyright(); - static - void printVersion(); + static void printVersion(); public: - Tool(int ac, char *av[], const std::string &name, const std::list &sigs = { }); + Tool(int ac, char *av[], const std::string &name, + const std::list &sigs = {}); - virtual - int main() - { - return 0; - } + virtual int main() { return 0; } - virtual - void usage() - { } + virtual void usage() {} - virtual - void parse() - { } + virtual void parse() {} - virtual - int run(); + virtual int run(); }; } // namespace villas diff --git a/common/include/villas/tsc.hpp b/common/include/villas/tsc.hpp index 0370a0a67..ca8c1bf26 100644 --- a/common/include/villas/tsc.hpp +++ b/common/include/villas/tsc.hpp @@ -8,38 +8,34 @@ #pragma once #if !(__x86_64__ || __i386__) - #error this header is for x86 only +#error this header is for x86 only #endif -#include #include +#include #include #include #ifndef bit_TSC - #define bit_TSC (1 << 4) +#define bit_TSC (1 << 4) #endif -#define bit_TSC_INVARIANT (1 << 8) -#define bit_RDTSCP (1 << 27) +#define bit_TSC_INVARIANT (1 << 8) +#define bit_RDTSCP (1 << 27) struct Tsc { - uint64_t frequency; + uint64_t frequency; - bool rdtscp_supported; - bool is_invariant; + bool rdtscp_supported; + bool is_invariant; }; -__attribute__((unused)) static -uint64_t tsc_now(struct Tsc *t) -{ - uint32_t tsc_aux; - return t->rdtscp_supported - ? __rdtscp(&tsc_aux) - : __rdtsc(); +__attribute__((unused)) static uint64_t tsc_now(struct Tsc *t) { + uint32_t tsc_aux; + return t->rdtscp_supported ? __rdtscp(&tsc_aux) : __rdtsc(); } -int tsc_init(struct Tsc *t) __attribute__ ((warn_unused_result)); +int tsc_init(struct Tsc *t) __attribute__((warn_unused_result)); uint64_t tsc_rate_to_cycles(struct Tsc *t, double rate); diff --git a/common/include/villas/utils.hpp b/common/include/villas/utils.hpp index 2a8ee744b..6ca28736d 100644 --- a/common/include/villas/utils.hpp +++ b/common/include/villas/utils.hpp @@ -8,15 +8,15 @@ #pragma once +#include #include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include @@ -24,110 +24,120 @@ #include #ifdef __GNUC__ - #define LIKELY(x) __builtin_expect((x),1) - #define UNLIKELY(x) __builtin_expect((x),0) +#define LIKELY(x) __builtin_expect((x), 1) +#define UNLIKELY(x) __builtin_expect((x), 0) #else - #define LIKELY(x) (x) - #define UNLIKELY(x) (x) +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) #endif // Check assertion and exit if failed. #ifndef assert - #define assert(exp) do { \ - if (!EXPECT(exp, 0)) \ - error("Assertion failed: '%s' in %s(), %s:%d", \ - XSTR(exp), __FUNCTION__, __BASE_FILE__, __LINE__); \ - } while (0) +#define assert(exp) \ + do { \ + if (!EXPECT(exp, 0)) \ + error("Assertion failed: '%s' in %s(), %s:%d", XSTR(exp), __FUNCTION__, \ + __BASE_FILE__, __LINE__); \ + } while (0) #endif // CPP stringification -#define XSTR(x) STR(x) -#define STR(x) #x +#define XSTR(x) STR(x) +#define STR(x) #x -#define CONCAT_DETAIL(x, y) x##y -#define CONCAT(x, y) CONCAT_DETAIL(x, y) -#define UNIQUE(x) CONCAT(x, __COUNTER__) +#define CONCAT_DETAIL(x, y) x##y +#define CONCAT(x, y) CONCAT_DETAIL(x, y) +#define UNIQUE(x) CONCAT(x, __COUNTER__) #ifdef ALIGN - #undef ALIGN +#undef ALIGN #endif -#define ALIGN(x, a) ALIGN_MASK(x, (uintptr_t) (a) - 1) -#define ALIGN_MASK(x, m) (((uintptr_t) (x) + (m)) & ~(m)) -#define IS_ALIGNED(x, a) (ALIGN(x, a) == (uintptr_t) x) +#define ALIGN(x, a) ALIGN_MASK(x, (uintptr_t)(a)-1) +#define ALIGN_MASK(x, m) (((uintptr_t)(x) + (m)) & ~(m)) +#define IS_ALIGNED(x, a) (ALIGN(x, a) == (uintptr_t)x) -#define SWAP(x, y) do { \ - auto t = x; \ - x = y; \ - y = t; \ -} while (0) +#define SWAP(x, y) \ + do { \ + auto t = x; \ + x = y; \ + y = t; \ + } while (0) // Round-up integer division -#define CEIL(x, y) (((x) + (y) - 1) / (y)) +#define CEIL(x, y) (((x) + (y)-1) / (y)) // Get nearest up-rounded power of 2 -#define LOG2_CEIL(x) (1 << (villas::utils::log2i((x) - 1) + 1)) +#define LOG2_CEIL(x) (1 << (villas::utils::log2i((x)-1) + 1)) // Check if the number is a power of 2 -#define IS_POW2(x) (((x) != 0) && !((x) & ((x) - 1))) +#define IS_POW2(x) (((x) != 0) && !((x) & ((x)-1))) // Calculate the number of elements in an array. -#define ARRAY_LEN(a) ( sizeof (a) / sizeof (a)[0] ) +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a)[0]) // Return the bigger value #ifdef MAX - #undef MAX +#undef MAX #endif -#define MAX(a, b) ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) +#define MAX(a, b) \ + ({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) // Return the smaller value #ifdef MIN - #undef MIN +#undef MIN #endif -#define MIN(a, b) ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) -#define MIN3(a, b, c) MIN(MIN((a), (b)), (c)) +#define MIN(a, b) \ + ({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a < _b ? _a : _b; \ + }) +#define MIN3(a, b, c) MIN(MIN((a), (b)), (c)) #ifndef offsetof - #define offsetof(type, member) __builtin_offsetof(type, member) +#define offsetof(type, member) __builtin_offsetof(type, member) #endif #ifndef container_of - #define container_of(ptr, type, member) ({ const typeof( ((type *) 0)->member ) *__mptr = (ptr); \ - (type *) ( (char *) __mptr - offsetof(type, member) ); \ - }) +#define container_of(ptr, type, member) \ + ({ \ + const typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) #endif -#define BITS_PER_LONGLONG (sizeof(long long) * 8) +#define BITS_PER_LONGLONG (sizeof(long long) * 8) // Some helper macros -#define BITMASK(h, l) (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONGLONG - 1 - (h)))) -#define BIT(nr) (1UL << (nr)) +#define BITMASK(h, l) \ + (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONGLONG - 1 - (h)))) +#define BIT(nr) (1UL << (nr)) namespace villas { namespace utils { -std::vector -tokenize(std::string s, const std::string &delimiter); +std::vector tokenize(std::string s, const std::string &delimiter); -template -void -assertExcept(bool condition, const T &exception) -{ - if (not condition) - throw exception; +template void assertExcept(bool condition, const T &exception) { + if (not condition) + throw exception; } // Register a exit callback for program termination: SIGINT, SIGKILL & SIGALRM. -int signalsInit(void (*cb)(int signal, siginfo_t *sinfo, void *ctx), std::list cbSignals = {}, std::list ignoreSignals = { SIGCHLD }) __attribute__ ((warn_unused_result)); +int signalsInit(void (*cb)(int signal, siginfo_t *sinfo, void *ctx), + std::list cbSignals = {}, + std::list ignoreSignals = {SIGCHLD}) + __attribute__((warn_unused_result)); // Fill buffer with random data. ssize_t readRandom(char *buf, size_t len); // Remove ANSI control sequences for colored output. -char * decolor(char *str); +char *decolor(char *str); // Normal random variate generator using the Box-Muller method // @@ -148,18 +158,18 @@ double randf(); // @param fmt A format string like for printf() // @param ... Optional parameters like for printf() // @retval The the new value of the dest buffer. -char * strcatf(char **dest, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); +char *strcatf(char **dest, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); // Variadic version of strcatf() -char * vstrcatf(char **dest, const char *fmt, va_list va) - __attribute__ ((format(printf, 2, 0))); +char *vstrcatf(char **dest, const char *fmt, va_list va) + __attribute__((format(printf, 2, 0))); -char * strf(const char *fmt, ...); -char * vstrf(const char *fmt, va_list va); +char *strf(const char *fmt, ...); +char *vstrf(const char *fmt, va_list va); // Allocate and copy memory. -void * memdup(const void *src, size_t bytes); +void *memdup(const void *src, size_t bytes); // Call quit() in the main thread. void die(); @@ -194,12 +204,12 @@ bool isContainer(); bool isPrivileged(); // helper type for std::visit -template -struct overloaded : Ts... { using Ts::operator()...; }; +template struct overloaded : Ts... { + using Ts::operator()...; +}; // explicit deduction guide (not needed as of C++20) -template -overloaded(Ts...) -> overloaded; +template overloaded(Ts...) -> overloaded; namespace base64 { diff --git a/common/include/villas/uuid.hpp b/common/include/villas/uuid.hpp index 4fc024cd7..660ccf79d 100644 --- a/common/include/villas/uuid.hpp +++ b/common/include/villas/uuid.hpp @@ -21,7 +21,8 @@ namespace uuid { std::string toString(const uuid_t in); // Generate an UUID by MD5 hashing the provided string -int generateFromString(uuid_t out, const std::string &data, const std::string &ns = ""); +int generateFromString(uuid_t out, const std::string &data, + const std::string &ns = ""); // Generate an UUID by MD5 hashing the provided string int generateFromString(uuid_t out, const std::string &data, const uuid_t ns); diff --git a/common/include/villas/version.hpp b/common/include/villas/version.hpp index bde614baa..fc4d6c03d 100644 --- a/common/include/villas/version.hpp +++ b/common/include/villas/version.hpp @@ -15,53 +15,28 @@ namespace utils { class Version { protected: - int components[3]; + int components[3]; - static - int cmp(const Version &lhs, const Version &rhs); + static int cmp(const Version &lhs, const Version &rhs); public: - // Parse a dotted version string. - Version(const std::string &s); + // Parse a dotted version string. + Version(const std::string &s); - Version(int maj, int min = 0, int pat = 0); + Version(int maj, int min = 0, int pat = 0); - inline - bool operator==(const Version &rhs) - { - return cmp(*this, rhs) == 0; - } + inline bool operator==(const Version &rhs) { return cmp(*this, rhs) == 0; } - inline - bool operator!=(const Version &rhs) - { - return cmp(*this, rhs) != 0; - } + inline bool operator!=(const Version &rhs) { return cmp(*this, rhs) != 0; } - inline - bool operator<(const Version &rhs) - { - return cmp(*this, rhs) < 0; - } + inline bool operator<(const Version &rhs) { return cmp(*this, rhs) < 0; } - inline - bool operator>(const Version &rhs) - { - return cmp(*this, rhs) > 0; - } + inline bool operator>(const Version &rhs) { return cmp(*this, rhs) > 0; } - inline - bool operator<=(const Version &rhs) - { - return cmp(*this, rhs) <= 0; - } + inline bool operator<=(const Version &rhs) { return cmp(*this, rhs) <= 0; } - inline - bool operator>=(const Version &rhs) - { - return cmp(*this, rhs) >= 0; - } + inline bool operator>=(const Version &rhs) { return cmp(*this, rhs) >= 0; } }; -} // namespace villas } // namespace utils +} // namespace villas diff --git a/common/lib/base64.cpp b/common/lib/base64.cpp index 249d28c35..bcd3e58ec 100644 --- a/common/lib/base64.cpp +++ b/common/lib/base64.cpp @@ -5,10 +5,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include #include #include -#include -#include #include @@ -16,101 +16,104 @@ namespace villas { namespace utils { namespace base64 { -static -const char kEncodeLookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static -const char kPadCharacter = '='; +static const char kEncodeLookup[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char kPadCharacter = '='; -std::string encode(const std::vector& input) -{ - std::string encoded; - encoded.reserve(((input.size() / 3) + (input.size() % 3 > 0)) * 4); +std::string encode(const std::vector &input) { + std::string encoded; + encoded.reserve(((input.size() / 3) + (input.size() % 3 > 0)) * 4); - std::uint32_t temp{}; - auto it = input.begin(); + std::uint32_t temp{}; + auto it = input.begin(); - for (std::size_t i = 0; i < input.size() / 3; ++i) { - temp = (*it++) << 16; - temp += (*it++) << 8; - temp += (*it++); - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6 ]); - encoded.append(1, kEncodeLookup[(temp & 0x0000003F) ]); - } + for (std::size_t i = 0; i < input.size() / 3; ++i) { + temp = (*it++) << 16; + temp += (*it++) << 8; + temp += (*it++); + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); + encoded.append(1, kEncodeLookup[(temp & 0x0000003F)]); + } - switch (input.size() % 3) { - case 1: - temp = (*it++) << 16; - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(2, kPadCharacter); - break; + switch (input.size() % 3) { + case 1: + temp = (*it++) << 16; + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(2, kPadCharacter); + break; - case 2: - temp = (*it++) << 16; - temp += (*it++) << 8; - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6 ]); - encoded.append(1, kPadCharacter); - break; - } + case 2: + temp = (*it++) << 16; + temp += (*it++) << 8; + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); + encoded.append(1, kPadCharacter); + break; + } - return encoded; + return encoded; } -std::vector decode(const std::string &input) -{ - if (input.length() % 4) - throw std::runtime_error("Invalid base64 length!"); +std::vector decode(const std::string &input) { + if (input.length() % 4) + throw std::runtime_error("Invalid base64 length!"); - std::size_t padding{}; + std::size_t padding{}; - if (input.length()) { - if (input[input.length() - 1] == kPadCharacter) padding++; - if (input[input.length() - 2] == kPadCharacter) padding++; - } + if (input.length()) { + if (input[input.length() - 1] == kPadCharacter) + padding++; + if (input[input.length() - 2] == kPadCharacter) + padding++; + } - std::vector decoded; - decoded.reserve(((input.length() / 4) * 3) - padding); + std::vector decoded; + decoded.reserve(((input.length() / 4) * 3) - padding); - std::uint32_t temp{}; - auto it = input.begin(); + std::uint32_t temp{}; + auto it = input.begin(); - while (it < input.end()) { - for (std::size_t i = 0; i < 4; ++i) { - temp <<= 6; - if (*it >= 0x41 && *it <= 0x5A) temp |= *it - 0x41; - else if (*it >= 0x61 && *it <= 0x7A) temp |= *it - 0x47; - else if (*it >= 0x30 && *it <= 0x39) temp |= *it + 0x04; - else if (*it == 0x2B) temp |= 0x3E; - else if (*it == 0x2F) temp |= 0x3F; - else if (*it == kPadCharacter) { - switch(input.end() - it) { - case 1: - decoded.push_back((temp >> 16) & 0x000000FF); - decoded.push_back((temp >> 8 ) & 0x000000FF); - return decoded; - case 2: - decoded.push_back((temp >> 10) & 0x000000FF); - return decoded; - default: - throw std::runtime_error("Invalid padding in base64!"); - } - } - else - throw std::runtime_error("Invalid character in base64!"); + while (it < input.end()) { + for (std::size_t i = 0; i < 4; ++i) { + temp <<= 6; + if (*it >= 0x41 && *it <= 0x5A) + temp |= *it - 0x41; + else if (*it >= 0x61 && *it <= 0x7A) + temp |= *it - 0x47; + else if (*it >= 0x30 && *it <= 0x39) + temp |= *it + 0x04; + else if (*it == 0x2B) + temp |= 0x3E; + else if (*it == 0x2F) + temp |= 0x3F; + else if (*it == kPadCharacter) { + switch (input.end() - it) { + case 1: + decoded.push_back((temp >> 16) & 0x000000FF); + decoded.push_back((temp >> 8) & 0x000000FF); + return decoded; + case 2: + decoded.push_back((temp >> 10) & 0x000000FF); + return decoded; + default: + throw std::runtime_error("Invalid padding in base64!"); + } + } else + throw std::runtime_error("Invalid character in base64!"); - ++it; - } + ++it; + } - decoded.push_back((temp >> 16) & 0x000000FF); - decoded.push_back((temp >> 8 ) & 0x000000FF); - decoded.push_back((temp ) & 0x000000FF); - } + decoded.push_back((temp >> 16) & 0x000000FF); + decoded.push_back((temp >> 8) & 0x000000FF); + decoded.push_back((temp)&0x000000FF); + } - return decoded; + return decoded; } } // namespace base64 diff --git a/common/lib/buffer.cpp b/common/lib/buffer.cpp index e6c814ded..eede18d4a 100644 --- a/common/lib/buffer.cpp +++ b/common/lib/buffer.cpp @@ -5,37 +5,34 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include using namespace villas; -json_t * Buffer::decode() -{ - json_t *j; - json_error_t err; +json_t *Buffer::decode() { + json_t *j; + json_error_t err; - j = json_loadb(data(), size(), JSON_DISABLE_EOF_CHECK, &err); - if (!j) - return nullptr; + j = json_loadb(data(), size(), JSON_DISABLE_EOF_CHECK, &err); + if (!j) + return nullptr; - // Remove decoded JSON document from beginning - erase(begin(), begin() + err.position); + // Remove decoded JSON document from beginning + erase(begin(), begin() + err.position); - return j; + return j; } -int Buffer::encode(json_t *j, int flags) -{ - return json_dump_callback(j, callback, this, flags); +int Buffer::encode(json_t *j, int flags) { + return json_dump_callback(j, callback, this, flags); } -int Buffer::callback(const char *data, size_t len, void *ctx) -{ - Buffer *b = static_cast(ctx); +int Buffer::callback(const char *data, size_t len, void *ctx) { + Buffer *b = static_cast(ctx); - // Append junk of JSON to buffer - b->insert(b->end(), &data[0], &data[len]); + // Append junk of JSON to buffer + b->insert(b->end(), &data[0], &data[len]); - return 0; + return 0; } diff --git a/common/lib/common.cpp b/common/lib/common.cpp index db6c5fb5d..9a15b9efa 100644 --- a/common/lib/common.cpp +++ b/common/lib/common.cpp @@ -9,37 +9,36 @@ #include -std::string stateToString(enum State s) -{ - switch (s) { - case State::DESTROYED: - return "destroyed"; +std::string stateToString(enum State s) { + switch (s) { + case State::DESTROYED: + return "destroyed"; - case State::INITIALIZED: - return "initialized"; + case State::INITIALIZED: + return "initialized"; - case State::PARSED: - return "parsed"; + case State::PARSED: + return "parsed"; - case State::CHECKED: - return "checked"; + case State::CHECKED: + return "checked"; - case State::STARTED: - return "running"; + case State::STARTED: + return "running"; - case State::STOPPED: - return "stopped"; + case State::STOPPED: + return "stopped"; - case State::PENDING_CONNECT: - return "pending-connect"; + case State::PENDING_CONNECT: + return "pending-connect"; - case State::CONNECTED: - return "connected"; + case State::CONNECTED: + return "connected"; - case State::PAUSED: - return "paused"; + case State::PAUSED: + return "paused"; - default: - return ""; - } + default: + return ""; + } } diff --git a/common/lib/compat.cpp b/common/lib/compat.cpp index 8aa26e4ba..fb19b45ef 100644 --- a/common/lib/compat.cpp +++ b/common/lib/compat.cpp @@ -12,56 +12,49 @@ #include #if JANSSON_VERSION_HEX < 0x020A00 -size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) -{ - char *str; - size_t len; +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) { + char *str; + size_t len; - str = json_dumps(json, flags); - if (!str) - return 0; + str = json_dumps(json, flags); + if (!str) + return 0; - len = strlen(str); // Not \0 terminated - if (buffer && len <= size) - memcpy(buffer, str, len); + len = strlen(str); // Not \0 terminated + if (buffer && len <= size) + memcpy(buffer, str, len); - free(str); + free(str); - return len; + return len; } -static -size_t json_loadfd_callback(void *buffer, size_t buflen, void *data) -{ - int *fd = (int *) data; +static size_t json_loadfd_callback(void *buffer, size_t buflen, void *data) { + int *fd = (int *)data; - return (size_t) read(*fd, buffer, buflen); + return (size_t)read(*fd, buffer, buflen); } -json_t *json_loadfd(int input, size_t flags, json_error_t *error) -{ - return json_load_callback(json_loadfd_callback, (void *) &input, flags, error); +json_t *json_loadfd(int input, size_t flags, json_error_t *error) { + return json_load_callback(json_loadfd_callback, (void *)&input, flags, error); } -static -int json_dumpfd_callback(const char *buffer, size_t size, void *data) -{ +static int json_dumpfd_callback(const char *buffer, size_t size, void *data) { #ifdef HAVE_UNISTD_H - int *dest = (int *)data; + int *dest = (int *)data; - if (write(*dest, buffer, size) == (ssize_t)size) - return 0; + if (write(*dest, buffer, size) == (ssize_t)size) + return 0; #else - (void)buffer; - (void)size; - (void)data; + (void)buffer; + (void)size; + (void)data; #endif // HAVE_UNISTD_H - return -1; + return -1; } -int json_dumpfd(const json_t *json, int output, size_t flags) -{ - return json_dump_callback(json, json_dumpfd_callback, (void *) &output, flags); +int json_dumpfd(const json_t *json, int output, size_t flags) { + return json_dump_callback(json, json_dumpfd_callback, (void *)&output, flags); } #endif // JANSSON_VERSION_HEX < 0x020A00 diff --git a/common/lib/cpuset.cpp b/common/lib/cpuset.cpp index e080c486e..d781a30d2 100644 --- a/common/lib/cpuset.cpp +++ b/common/lib/cpuset.cpp @@ -12,104 +12,94 @@ using namespace villas::utils; #ifdef __linux__ -CpuSet::CpuSet(uintmax_t iset) : - CpuSet() -{ - zero(); +CpuSet::CpuSet(uintmax_t iset) : CpuSet() { + zero(); - for (size_t i = 0; i < num_cpus; i++) { - if (iset & (1L << i)) - set(i); - } + for (size_t i = 0; i < num_cpus; i++) { + if (iset & (1L << i)) + set(i); + } } -CpuSet::CpuSet(const std::string &str) : - CpuSet() -{ - size_t endpos, start, end; +CpuSet::CpuSet(const std::string &str) : CpuSet() { + size_t endpos, start, end; - for (auto token : tokenize(str, ",")) { - auto sep = token.find('-'); + for (auto token : tokenize(str, ",")) { + auto sep = token.find('-'); - if (sep == std::string::npos) { - start = std::stoi(token, &endpos); + if (sep == std::string::npos) { + start = std::stoi(token, &endpos); - if (token.begin() + endpos != token.end()) - throw std::invalid_argument("Not a valid CPU set"); + if (token.begin() + endpos != token.end()) + throw std::invalid_argument("Not a valid CPU set"); - if (start < num_cpus) - set(start); - } - else { - start = std::stoi(token, &endpos); + if (start < num_cpus) + set(start); + } else { + start = std::stoi(token, &endpos); - if (token.begin() + endpos != token.begin() + sep) - throw std::invalid_argument("Not a valid CPU set"); + if (token.begin() + endpos != token.begin() + sep) + throw std::invalid_argument("Not a valid CPU set"); - auto token2 = token.substr(endpos + 1); + auto token2 = token.substr(endpos + 1); - end = std::stoi(token2, &endpos); + end = std::stoi(token2, &endpos); - if (token2.begin() + endpos != token2.end()) - throw std::invalid_argument("Not a valid CPU set"); + if (token2.begin() + endpos != token2.end()) + throw std::invalid_argument("Not a valid CPU set"); - for (size_t i = start; i <= end && i < num_cpus; i++) - set(i); - } - } + for (size_t i = start; i <= end && i < num_cpus; i++) + set(i); + } + } } -CpuSet::CpuSet(const char *str) - : CpuSet(std::string(str)) -{ } +CpuSet::CpuSet(const char *str) : CpuSet(std::string(str)) {} -CpuSet::operator uintmax_t() -{ - uintmax_t iset = 0; +CpuSet::operator uintmax_t() { + uintmax_t iset = 0; - for (size_t i = 0; i < num_cpus; i++) { - if (isSet(i)) - iset |= 1ULL << i; - } + for (size_t i = 0; i < num_cpus; i++) { + if (isSet(i)) + iset |= 1ULL << i; + } - return iset; + return iset; } -CpuSet::operator std::string () -{ - std::stringstream ss; +CpuSet::operator std::string() { + std::stringstream ss; - bool first = true; + bool first = true; - for (size_t i = 0; i < num_cpus; i++) { - if (isSet(i)) { - size_t run = 0; - for (size_t j = i + 1; j < num_cpus; j++) { - if (!isSet(j)) - break; + for (size_t i = 0; i < num_cpus; i++) { + if (isSet(i)) { + size_t run = 0; + for (size_t j = i + 1; j < num_cpus; j++) { + if (!isSet(j)) + break; - run++; - } + run++; + } - if (first) - first = false; - else - ss << ","; + if (first) + first = false; + else + ss << ","; - ss << i; + ss << i; - if (run == 1) { - ss << "," << (i + 1); - i++; - } - else if (run > 1) { - ss << "-" << (i + run); - i += run; - } - } - } + if (run == 1) { + ss << "," << (i + 1); + i++; + } else if (run > 1) { + ss << "-" << (i + run); + i += run; + } + } + } - return ss.str(); + return ss.str(); } #endif // __linux__ diff --git a/common/lib/dsp/pid.cpp b/common/lib/dsp/pid.cpp index ba8739910..5924dfcff 100644 --- a/common/lib/dsp/pid.cpp +++ b/common/lib/dsp/pid.cpp @@ -5,51 +5,44 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include using namespace std; using namespace villas::dsp; -PID::PID(double _dt, double _max, double _min, double _Kp, double _Kd, double _Ki) : - dt(_dt), - max(_max), - min(_min), - Kp(_Kp), - Kd(_Kd), - Ki(_Ki), - pre_error(0), - integral(0) -{ } +PID::PID(double _dt, double _max, double _min, double _Kp, double _Kd, + double _Ki) + : dt(_dt), max(_max), min(_min), Kp(_Kp), Kd(_Kd), Ki(_Ki), pre_error(0), + integral(0) {} -double PID::calculate(double setpoint, double pv) -{ - // Calculate error - double error = setpoint - pv; +double PID::calculate(double setpoint, double pv) { + // Calculate error + double error = setpoint - pv; - // Proportional term - double Pout = Kp * error; + // Proportional term + double Pout = Kp * error; - // Integral term - integral += error * dt; - double Iout = Ki * integral; + // Integral term + integral += error * dt; + double Iout = Ki * integral; - // Derivative term - double derivative = (error - pre_error) / dt; - double Dout = Kd * derivative; + // Derivative term + double derivative = (error - pre_error) / dt; + double Dout = Kd * derivative; - // Calculate total output - double output = Pout + Iout + Dout; + // Calculate total output + double output = Pout + Iout + Dout; - // Restrict to max/min - if (output > max) - output = max; - else if (output < min) - output = min; + // Restrict to max/min + if (output > max) + output = max; + else if (output < min) + output = min; - // Save error to previous error - pre_error = error; + // Save error to previous error + pre_error = error; - return output; + return output; } diff --git a/common/lib/hist.cpp b/common/lib/hist.cpp index f39067496..7ee048873 100644 --- a/common/lib/hist.cpp +++ b/common/lib/hist.cpp @@ -5,262 +5,227 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include -#include -#include #include -#include #include +#include +#include +#include using namespace villas; using namespace villas::utils; namespace villas { -Hist::Hist(int buckets, Hist::cnt_t wu) : - resolution(0), - high(0), - low(0), - highest(std::numeric_limits::min()), - lowest(std::numeric_limits::max()), - last(0), - total(0), - warmup(wu), - higher(0), - lower(0), - data(buckets, 0), - _m{0, 0}, - _s{0, 0} -{ } +Hist::Hist(int buckets, Hist::cnt_t wu) + : resolution(0), high(0), low(0), + highest(std::numeric_limits::min()), + lowest(std::numeric_limits::max()), last(0), total(0), warmup(wu), + higher(0), lower(0), data(buckets, 0), _m{0, 0}, _s{0, 0} {} -void Hist::put(double value) -{ - last = value; +void Hist::put(double value) { + last = value; - // Update min/max - if (value > highest) - highest = value; - if (value < lowest) - lowest = value; + // Update min/max + if (value > highest) + highest = value; + if (value < lowest) + lowest = value; - if (data.size()) { - if (total < warmup) { - // We are still in warmup phase... Waiting for more samples... - } - else if (data.size() && total == warmup && warmup != 0) { - low = getMean() - 3 * getStddev(); - high = getMean() + 3 * getStddev(); - resolution = (high - low) / data.size(); - } - else if (data.size() && (total == warmup) && (warmup == 0)) { - // There is no warmup phase - // TODO resolution = ? - } - else { - idx_t idx = std::round((value - low) / resolution); + if (data.size()) { + if (total < warmup) { + // We are still in warmup phase... Waiting for more samples... + } else if (data.size() && total == warmup && warmup != 0) { + low = getMean() - 3 * getStddev(); + high = getMean() + 3 * getStddev(); + resolution = (high - low) / data.size(); + } else if (data.size() && (total == warmup) && (warmup == 0)) { + // There is no warmup phase + // TODO resolution = ? + } else { + idx_t idx = std::round((value - low) / resolution); - // Check bounds and increment - if (idx >= (idx_t) data.size()) - higher++; - else if (idx < 0) - lower++; - else - data[idx]++; - } - } + // Check bounds and increment + if (idx >= (idx_t)data.size()) + higher++; + else if (idx < 0) + lower++; + else + data[idx]++; + } + } - total++; + total++; - // Online / running calculation of variance and mean - // by Donald Knuth’s Art of Computer Programming, Vol 2, page 232, 3rd edition - if (total == 1) { - _m[1] = _m[0] = value; - _s[1] = 0.0; - } - else { - _m[0] = _m[1] + (value - _m[1]) / total; - _s[0] = _s[1] + (value - _m[1]) * (value - _m[0]); + // Online / running calculation of variance and mean + // by Donald Knuth’s Art of Computer Programming, Vol 2, page 232, 3rd edition + if (total == 1) { + _m[1] = _m[0] = value; + _s[1] = 0.0; + } else { + _m[0] = _m[1] + (value - _m[1]) / total; + _s[0] = _s[1] + (value - _m[1]) * (value - _m[0]); - // Set up for next iteration - _m[1] = _m[0]; - _s[1] = _s[0]; - } + // Set up for next iteration + _m[1] = _m[0]; + _s[1] = _s[0]; + } } -void Hist::reset() -{ - total = 0; - higher = 0; - lower = 0; +void Hist::reset() { + total = 0; + higher = 0; + lower = 0; - highest = std::numeric_limits::min(); - lowest = std::numeric_limits::max(); + highest = std::numeric_limits::min(); + lowest = std::numeric_limits::max(); - for (auto &elm : data) - elm = 0; + for (auto &elm : data) + elm = 0; } -double Hist::getMean() const -{ - return total > 0 ? _m[0] : std::numeric_limits::quiet_NaN(); +double Hist::getMean() const { + return total > 0 ? _m[0] : std::numeric_limits::quiet_NaN(); } -double Hist::getVar() const -{ - return total > 1 ? _s[0] / (total - 1) : std::numeric_limits::quiet_NaN(); +double Hist::getVar() const { + return total > 1 ? _s[0] / (total - 1) + : std::numeric_limits::quiet_NaN(); } -double Hist::getStddev() const -{ - return sqrt(getVar()); +double Hist::getStddev() const { return sqrt(getVar()); } + +void Hist::print(Logger logger, bool details) const { + if (total > 0) { + Hist::cnt_t missed = total - higher - lower; + + logger->info("Counted values: {} ({} between {} and {})", total, missed, + low, high); + logger->info("Highest: {:g}", highest); + logger->info("Lowest: {:g}", lowest); + logger->info("Mu: {:g}", getMean()); + logger->info("1/Mu: {:g}", 1.0 / getMean()); + logger->info("Variance: {:g}", getVar()); + logger->info("Stddev: {:g}", getStddev()); + + if (details && total - higher - lower > 0) { + char *buf = dump(); + logger->info("Matlab: {}", buf); + free(buf); + + plot(logger); + } + } else + logger->info("Counted values: {}", total); } -void Hist::print(Logger logger, bool details) const -{ - if (total > 0) { - Hist::cnt_t missed = total - higher - lower; +void Hist::plot(Logger logger) const { + // Get highest bar + Hist::cnt_t max = *std::max_element(data.begin(), data.end()); - logger->info("Counted values: {} ({} between {} and {})", total, missed, low, high); - logger->info("Highest: {:g}", highest); - logger->info("Lowest: {:g}", lowest); - logger->info("Mu: {:g}", getMean()); - logger->info("1/Mu: {:g}", 1.0 / getMean()); - logger->info("Variance: {:g}", getVar()); - logger->info("Stddev: {:g}", getStddev()); + std::vector cols = { + {-9, TableColumn::Alignment::RIGHT, "Value", "%+9.3g"}, + {-6, TableColumn::Alignment::RIGHT, "Count", "%6ju"}, + {0, TableColumn::Alignment::LEFT, "Plot", "%s", "occurences"}}; - if (details && total - higher - lower > 0) { - char *buf = dump(); - logger->info("Matlab: {}", buf); - free(buf); + Table table = Table(logger, cols); - plot(logger); - } - } - else - logger->info("Counted values: {}", total); + // Print plot + table.header(); + + for (size_t i = 0; i < data.size(); i++) { + double value = low + (i)*resolution; + Hist::cnt_t cnt = data[i]; + int bar = cols[2].getWidth() * ((double)cnt / max); + + char *buf = strf("%s", ""); + for (int i = 0; i < bar; i++) + buf = strcatf(&buf, "\u2588"); + + table.row(3, value, cnt, buf); + + free(buf); + } } -void Hist::plot(Logger logger) const -{ - // Get highest bar - Hist::cnt_t max = *std::max_element(data.begin(), data.end()); +char *Hist::dump() const { + char *buf = new char[128]; + if (!buf) + throw MemoryAllocationError(); - std::vector cols = { - { -9, TableColumn::Alignment::RIGHT, "Value", "%+9.3g" }, - { -6, TableColumn::Alignment::RIGHT, "Count", "%6ju" }, - { 0, TableColumn::Alignment::LEFT, "Plot", "%s", "occurences" } - }; + memset(buf, 0, 128); - Table table = Table(logger, cols); + strcatf(&buf, "[ "); - // Print plot - table.header(); + for (auto elm : data) + strcatf(&buf, "%ju ", elm); - for (size_t i = 0; i < data.size(); i++) { - double value = low + (i) * resolution; - Hist::cnt_t cnt = data[i]; - int bar = cols[2].getWidth() * ((double) cnt / max); + strcatf(&buf, "]"); - char *buf = strf("%s", ""); - for (int i = 0; i < bar; i++) - buf = strcatf(&buf, "\u2588"); - - table.row(3, value, cnt, buf); - - free(buf); - } + return buf; } -char * Hist::dump() const -{ - char *buf = new char[128]; - if (!buf) - throw MemoryAllocationError(); +json_t *Hist::toJson() const { + json_t *json_buckets, *json_hist; - memset(buf, 0, 128); + json_hist = json_pack("{ s: f, s: f, s: i }", "low", low, "high", high, + "total", total); - strcatf(&buf, "[ "); + if (total > 0) { + json_object_update(json_hist, + json_pack("{ s: i, s: i, s: f, s: f, s: f, s: f, s: f }", + "higher", higher, "lower", lower, "highest", + highest, "lowest", lowest, "mean", getMean(), + "variance", getVar(), "stddev", getStddev())); + } - for (auto elm : data) - strcatf(&buf, "%ju ", elm); + if (total - lower - higher > 0) { + json_buckets = json_array(); - strcatf(&buf, "]"); + for (auto elm : data) + json_array_append(json_buckets, json_integer(elm)); - return buf; + json_object_set(json_hist, "buckets", json_buckets); + } + + return json_hist; } -json_t * Hist::toJson() const -{ - json_t *json_buckets, *json_hist; +int Hist::dumpJson(FILE *f) const { + json_t *j = Hist::toJson(); - json_hist = json_pack("{ s: f, s: f, s: i }", - "low", low, - "high", high, - "total", total - ); + int ret = json_dumpf(j, f, 0); - if (total > 0) { - json_object_update(json_hist, json_pack("{ s: i, s: i, s: f, s: f, s: f, s: f, s: f }", - "higher", higher, - "lower", lower, - "highest", highest, - "lowest", lowest, - "mean", getMean(), - "variance", getVar(), - "stddev", getStddev() - )); - } + json_decref(j); - if (total - lower - higher > 0) { - json_buckets = json_array(); - - for (auto elm : data) - json_array_append(json_buckets, json_integer(elm)); - - json_object_set(json_hist, "buckets", json_buckets); - } - - return json_hist; + return ret; } -int Hist::dumpJson(FILE *f) const -{ - json_t *j = Hist::toJson(); +int Hist::dumpMatlab(FILE *f) const { + fprintf(f, "struct("); + fprintf(f, "'low', %f, ", low); + fprintf(f, "'high', %f, ", high); + fprintf(f, "'total', %ju, ", total); + fprintf(f, "'higher', %ju, ", higher); + fprintf(f, "'lower', %ju, ", lower); + fprintf(f, "'highest', %f, ", highest); + fprintf(f, "'lowest', %f, ", lowest); + fprintf(f, "'mean', %f, ", getMean()); + fprintf(f, "'variance', %f, ", getVar()); + fprintf(f, "'stddev', %f, ", getStddev()); - int ret = json_dumpf(j, f, 0); + if (total - lower - higher > 0) { + char *buf = dump(); + fprintf(f, "'buckets', %s", buf); + free(buf); + } else + fprintf(f, "'buckets', zeros(1, %zu)", data.size()); - json_decref(j); + fprintf(f, ")"); - return ret; -} - -int Hist::dumpMatlab(FILE *f) const -{ - fprintf(f, "struct("); - fprintf(f, "'low', %f, ", low); - fprintf(f, "'high', %f, ", high); - fprintf(f, "'total', %ju, ", total); - fprintf(f, "'higher', %ju, ", higher); - fprintf(f, "'lower', %ju, ", lower); - fprintf(f, "'highest', %f, ", highest); - fprintf(f, "'lowest', %f, ", lowest); - fprintf(f, "'mean', %f, ", getMean()); - fprintf(f, "'variance', %f, ", getVar()); - fprintf(f, "'stddev', %f, ", getStddev()); - - if (total - lower - higher > 0) { - char *buf = dump(); - fprintf(f, "'buckets', %s", buf); - free(buf); - } - else - fprintf(f, "'buckets', zeros(1, %zu)", data.size()); - - fprintf(f, ")"); - - return 0; + return 0; } } // namespace villas diff --git a/common/lib/kernel/kernel.cpp b/common/lib/kernel/kernel.cpp index 0ccdeb073..70100da1e 100644 --- a/common/lib/kernel/kernel.cpp +++ b/common/lib/kernel/kernel.cpp @@ -5,336 +5,329 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include -#include #include -#include +#include +#include -#include #include #include -#include -#include #include #include +#include +#include -#include #include +#include using namespace villas; using namespace villas::utils; -Version villas::kernel::getVersion() -{ - struct utsname uts; +Version villas::kernel::getVersion() { + struct utsname uts; - if (uname(&uts) < 0) - throw SystemError("Failed to retrieve system identification"); + if (uname(&uts) < 0) + throw SystemError("Failed to retrieve system identification"); - std::string rel = uts.release; + std::string rel = uts.release; - // Remove release part. E.g. 4.9.93-linuxkit-aufs - auto sep = rel.find('-'); - auto ver = rel.substr(0, sep - 1); + // Remove release part. E.g. 4.9.93-linuxkit-aufs + auto sep = rel.find('-'); + auto ver = rel.substr(0, sep - 1); - return Version(ver); + return Version(ver); } -int villas::kernel::getCachelineSize() -{ +int villas::kernel::getCachelineSize() { #if defined(__linux__) && defined(__x86_64__) && defined(__GLIBC__) - return sysconf(_SC_LEVEL1_ICACHE_LINESIZE); + return sysconf(_SC_LEVEL1_ICACHE_LINESIZE); #elif defined(__MACH__) - // Open the command for reading. - FILE *fp = popen("sysctl -n machdep.cpu.cache.linesize", "r"); - if (fp == nullptr) - return -1; + // Open the command for reading. + FILE *fp = popen("sysctl -n machdep.cpu.cache.linesize", "r"); + if (fp == nullptr) + return -1; - int ret, size; + int ret, size; - ret = fscanf(fp, "%d", &size); + ret = fscanf(fp, "%d", &size); - pclose(fp); + pclose(fp); - return ret == 1 ? size : -1; + return ret == 1 ? size : -1; #else - return CACHELINE_SIZE; + return CACHELINE_SIZE; #endif } #if defined(__linux__) -int villas::kernel::getPageSize() -{ - return sysconf(_SC_PAGESIZE); -} +int villas::kernel::getPageSize() { return sysconf(_SC_PAGESIZE); } #else - #error "Unsupported platform" +#error "Unsupported platform" #endif // There is no sysconf interface to get the hugepage size -int villas::kernel::getHugePageSize() -{ +int villas::kernel::getHugePageSize() { #ifdef __linux__ - char *key, *value, *unit, *line = nullptr, *lasts; - int sz = -1; - size_t len = 0; - FILE *f; + char *key, *value, *unit, *line = nullptr, *lasts; + int sz = -1; + size_t len = 0; + FILE *f; - f = fopen(PROCFS_PATH "/meminfo", "r"); - if (!f) - return -1; + f = fopen(PROCFS_PATH "/meminfo", "r"); + if (!f) + return -1; - while (getline(&line, &len, f) != -1) { - key = strtok_r(line, ": ", &lasts); - value = strtok_r(nullptr, " ", &lasts); - unit = strtok_r(nullptr, "\n", &lasts); + while (getline(&line, &len, f) != -1) { + key = strtok_r(line, ": ", &lasts); + value = strtok_r(nullptr, " ", &lasts); + unit = strtok_r(nullptr, "\n", &lasts); - if (!strcmp(key, "Hugepagesize") && !strcmp(unit, "kB")) { - sz = strtoul(value, nullptr, 10) * 1024; - break; - } - } + if (!strcmp(key, "Hugepagesize") && !strcmp(unit, "kB")) { + sz = strtoul(value, nullptr, 10) * 1024; + break; + } + } - free(line); - fclose(f); + free(line); + fclose(f); - return sz; + return sz; #elif defined(__x86_64__) - return 1 << 21; + return 1 << 21; #elif defined(__i386__) - return 1 << 22; + return 1 << 22; #else - #error "Unsupported architecture" +#error "Unsupported architecture" #endif } #ifdef __linux__ -int villas::kernel::setModuleParam(const char *module, const char *param, const char *value) -{ - FILE *f; - char fn[256]; +int villas::kernel::setModuleParam(const char *module, const char *param, + const char *value) { + FILE *f; + char fn[256]; - snprintf(fn, sizeof(fn), "%s/module/%s/parameters/%s", SYSFS_PATH, module, param); - f = fopen(fn, "w"); - if (!f) - throw RuntimeError("Failed set parameter {} for kernel module {} to {}", module, param, value); + snprintf(fn, sizeof(fn), "%s/module/%s/parameters/%s", SYSFS_PATH, module, + param); + f = fopen(fn, "w"); + if (!f) + throw RuntimeError("Failed set parameter {} for kernel module {} to {}", + module, param, value); - auto logger = logging.get("kernel"); - logger->debug("Set parameter {} of kernel module {} to {}", module, param, value); + auto logger = logging.get("kernel"); + logger->debug("Set parameter {} of kernel module {} to {}", module, param, + value); - fprintf(f, "%s", value); - fclose(f); + fprintf(f, "%s", value); + fclose(f); - return 0; + return 0; } -int villas::kernel::loadModule(const char *module) -{ - int ret; +int villas::kernel::loadModule(const char *module) { + int ret; - ret = isModuleLoaded(module); - if (!ret) { - auto logger = logging.get("kernel"); - logger->debug("Kernel module {} already loaded...", module); - return 0; - } + ret = isModuleLoaded(module); + if (!ret) { + auto logger = logging.get("kernel"); + logger->debug("Kernel module {} already loaded...", module); + return 0; + } - pid_t pid = fork(); - switch (pid) { - case -1: // Error - return -1; + pid_t pid = fork(); + switch (pid) { + case -1: // Error + return -1; - case 0: // Child - execlp("modprobe", "modprobe", module, (char *) 0); - exit(EXIT_FAILURE); // exec() never returns + case 0: // Child + execlp("modprobe", "modprobe", module, (char *)0); + exit(EXIT_FAILURE); // exec() never returns - default: - wait(&ret); + default: + wait(&ret); - return isModuleLoaded(module); - } + return isModuleLoaded(module); + } } -int villas::kernel::isModuleLoaded(const char *module) -{ - FILE *f; - int ret = -1; - char *line = nullptr; - size_t len = 0; +int villas::kernel::isModuleLoaded(const char *module) { + FILE *f; + int ret = -1; + char *line = nullptr; + size_t len = 0; - f = fopen(PROCFS_PATH "/modules", "r"); - if (!f) - return -1; + f = fopen(PROCFS_PATH "/modules", "r"); + if (!f) + return -1; - while (getline(&line, &len, f) >= 0) { - if (strstr(line, module) == line) { - ret = 0; - break; - } - } + while (getline(&line, &len, f) >= 0) { + if (strstr(line, module) == line) { + ret = 0; + break; + } + } - free(line); - fclose(f); + free(line); + fclose(f); - return ret; + return ret; } -int villas::kernel::getCmdlineParam(const char *param, char *buf, size_t len) -{ - int ret; - char cmdline[512], key[128], value[128], *lasts, *tok; +int villas::kernel::getCmdlineParam(const char *param, char *buf, size_t len) { + int ret; + char cmdline[512], key[128], value[128], *lasts, *tok; - FILE *f = fopen(PROCFS_PATH "/cmdline", "r"); - if (!f) - return -1; + FILE *f = fopen(PROCFS_PATH "/cmdline", "r"); + if (!f) + return -1; - if (!fgets(cmdline, sizeof(cmdline), f)) - goto out; + if (!fgets(cmdline, sizeof(cmdline), f)) + goto out; - tok = strtok_r(cmdline, " \t", &lasts); - do { - ret = sscanf(tok, "%127[^=]=%127s", key, value); - if (ret >= 1) { - auto logger = logging.get("kernel"); - if (ret >= 2) - logger->debug("Found kernel param: {}={}", key, value); - else - logger->debug("Found kernel param: {}", key); + tok = strtok_r(cmdline, " \t", &lasts); + do { + ret = sscanf(tok, "%127[^=]=%127s", key, value); + if (ret >= 1) { + auto logger = logging.get("kernel"); + if (ret >= 2) + logger->debug("Found kernel param: {}={}", key, value); + else + logger->debug("Found kernel param: {}", key); - if (strcmp(param, key) == 0) { - if (ret >= 2 && buf) - snprintf(buf, len, "%s", value); + if (strcmp(param, key) == 0) { + if (ret >= 2 && buf) + snprintf(buf, len, "%s", value); - return 0; // Found - } - } - } while ((tok = strtok_r(nullptr, " \t", &lasts))); + return 0; // Found + } + } + } while ((tok = strtok_r(nullptr, " \t", &lasts))); out: - fclose(f); + fclose(f); - return -1; // Not found or error + return -1; // Not found or error } -int villas::kernel::getNrHugepages() -{ - FILE *f; - int nr, ret; +int villas::kernel::getNrHugepages() { + FILE *f; + int nr, ret; - f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "r"); - if (!f) { - auto logger = logging.get("kernel"); - logger->error("Failed to open {}: {}", PROCFS_PATH "/sys/vm/nr_hugepages", strerror(errno)); - return -1; - } + f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "r"); + if (!f) { + auto logger = logging.get("kernel"); + logger->error("Failed to open {}: {}", PROCFS_PATH "/sys/vm/nr_hugepages", + strerror(errno)); + return -1; + } - ret = fscanf(f, "%d", &nr); - if (ret != 1) - nr = -1; + ret = fscanf(f, "%d", &nr); + if (ret != 1) + nr = -1; - fclose(f); + fclose(f); - return nr; + return nr; } -int villas::kernel::setNrHugepages(int nr) -{ - FILE *f; +int villas::kernel::setNrHugepages(int nr) { + FILE *f; - f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w"); - if (!f) - return -1; + f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w"); + if (!f) + return -1; - fprintf(f, "%d\n", nr); - fclose(f); + fprintf(f, "%d\n", nr); + fclose(f); - return 0; + return 0; } -int villas::kernel::setIRQAffinity(unsigned irq, uintmax_t aff, uintmax_t *old) -{ - char fn[64]; - FILE *f; - int ret = 0; +int villas::kernel::setIRQAffinity(unsigned irq, uintmax_t aff, + uintmax_t *old) { + char fn[64]; + FILE *f; + int ret = 0; - snprintf(fn, sizeof(fn), "/proc/irq/%u/smp_affinity", irq); + snprintf(fn, sizeof(fn), "/proc/irq/%u/smp_affinity", irq); - f = fopen(fn, "w+"); - if (!f) - return -1; // IRQ does not exist + f = fopen(fn, "w+"); + if (!f) + return -1; // IRQ does not exist - if (old) - ret = fscanf(f, "%jx", old); + if (old) + ret = fscanf(f, "%jx", old); - fprintf(f, "%jx", aff); - fclose(f); + fprintf(f, "%jx", aff); + fclose(f); - return ret; + return ret; } -int villas::kernel::get_cpu_frequency(uint64_t *freq) -{ - char *line = nullptr, *sep, *end; - size_t len = 0; - double dfreq; - int ret; - FILE *f; +int villas::kernel::get_cpu_frequency(uint64_t *freq) { + char *line = nullptr, *sep, *end; + size_t len = 0; + double dfreq; + int ret; + FILE *f; - // Try to get CPU frequency from cpufreq module - f = fopen(SYSFS_PATH "/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r"); - if (!f) - goto cpuinfo; + // Try to get CPU frequency from cpufreq module + f = fopen(SYSFS_PATH "/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + "r"); + if (!f) + goto cpuinfo; - ret = fscanf(f, "%" PRIu64, freq); - fclose(f); - if (ret != 1) - return -1; + ret = fscanf(f, "%" PRIu64, freq); + fclose(f); + if (ret != 1) + return -1; - // cpufreq reports kHz - *freq = *freq * 1000; + // cpufreq reports kHz + *freq = *freq * 1000; - return 0; + return 0; cpuinfo: - // Try to read CPU frequency from /proc/cpuinfo - f = fopen(PROCFS_PATH "/cpuinfo", "r"); - if (!f) - return -1; // We give up here + // Try to read CPU frequency from /proc/cpuinfo + f = fopen(PROCFS_PATH "/cpuinfo", "r"); + if (!f) + return -1; // We give up here - ret = -1; - while (getline(&line, &len, f) >= 0) { - if (strstr(line, "cpu MHz") == line) { - ret = 0; - break; - } - } - if (ret) - goto out; + ret = -1; + while (getline(&line, &len, f) >= 0) { + if (strstr(line, "cpu MHz") == line) { + ret = 0; + break; + } + } + if (ret) + goto out; - sep = strchr(line, ':'); - if (!sep) { - ret = -1; - goto out; - } + sep = strchr(line, ':'); + if (!sep) { + ret = -1; + goto out; + } - dfreq = strtod(sep+1, &end); + dfreq = strtod(sep + 1, &end); - if (end == sep+1) { - ret = -1; - goto out; - } + if (end == sep + 1) { + ret = -1; + goto out; + } - // Frequency is given in MHz - *freq = dfreq * 1e6; + // Frequency is given in MHz + *freq = dfreq * 1e6; -out: fclose(f); - free(line); +out: + fclose(f); + free(line); - return ret; + return ret; } #endif // __linux__ diff --git a/common/lib/kernel/pci.cpp b/common/lib/kernel/pci.cpp index 74a5024bc..19a532864 100644 --- a/common/lib/kernel/pci.cpp +++ b/common/lib/kernel/pci.cpp @@ -5,456 +5,441 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include -#include -#include +#include +#include +#include #include #include -#include +#include +#include -#include -#include #include +#include #include +#include using namespace villas::kernel::pci; #define PCI_BASE_ADDRESS_N(n) (PCI_BASE_ADDRESS_0 + sizeof(uint32_t) * (n)) -DeviceList::DeviceList() -{ - struct dirent *e; - DIR *dp; - FILE *f; - char path[PATH_MAX]; - int ret; +DeviceList::DeviceList() { + struct dirent *e; + DIR *dp; + FILE *f; + char path[PATH_MAX]; + int ret; - snprintf(path, sizeof(path), "%s/bus/pci/devices", SYSFS_PATH); + snprintf(path, sizeof(path), "%s/bus/pci/devices", SYSFS_PATH); - dp = opendir(path); - if (!dp) - throw SystemError("Failed to detect PCI devices"); + dp = opendir(path); + if (!dp) + throw SystemError("Failed to detect PCI devices"); - while ((e = readdir(dp))) { - // Ignore special entries - if ((strcmp(e->d_name, ".") == 0) || - (strcmp(e->d_name, "..") == 0)) - continue; + while ((e = readdir(dp))) { + // Ignore special entries + if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) + continue; - Id id; - Slot slot; + Id id; + Slot slot; - struct { - const char *s; - unsigned int *p; - } map[] = { - {"vendor", &id.vendor}, - {"device", &id.device}}; + struct { + const char *s; + unsigned int *p; + } map[] = {{"vendor", &id.vendor}, {"device", &id.device}}; - // Read vendor & device id - for (int i = 0; i < 2; i++) { - snprintf(path, sizeof(path), "%s/bus/pci/devices/%s/%s", SYSFS_PATH, e->d_name, map[i].s); + // Read vendor & device id + for (int i = 0; i < 2; i++) { + snprintf(path, sizeof(path), "%s/bus/pci/devices/%s/%s", SYSFS_PATH, + e->d_name, map[i].s); - f = fopen(path, "r"); - if (!f) - throw SystemError("Failed to open '{}'", path); + f = fopen(path, "r"); + if (!f) + throw SystemError("Failed to open '{}'", path); - ret = fscanf(f, "%x", map[i].p); - if (ret != 1) - throw RuntimeError("Failed to parse {} ID from: {}", map[i].s, path); + ret = fscanf(f, "%x", map[i].p); + if (ret != 1) + throw RuntimeError("Failed to parse {} ID from: {}", map[i].s, path); - fclose(f); - } + fclose(f); + } - // Get slot id - ret = sscanf(e->d_name, "%4x:%2x:%2x.%u", &slot.domain, &slot.bus, &slot.device, &slot.function); - if (ret != 4) - throw RuntimeError("Failed to parse PCI slot number: {}", e->d_name); + // Get slot id + ret = sscanf(e->d_name, "%4x:%2x:%2x.%u", &slot.domain, &slot.bus, + &slot.device, &slot.function); + if (ret != 4) + throw RuntimeError("Failed to parse PCI slot number: {}", e->d_name); - emplace_back(std::make_shared(id, slot)); - } + emplace_back(std::make_shared(id, slot)); + } - closedir(dp); + closedir(dp); } -DeviceList::value_type DeviceList::lookupDevice(const Slot &s) -{ - return *std::find_if(begin(), end(), [s](const DeviceList::value_type &d) - { return d->slot == s; }); +DeviceList::value_type DeviceList::lookupDevice(const Slot &s) { + return *std::find_if(begin(), end(), [s](const DeviceList::value_type &d) { + return d->slot == s; + }); } -DeviceList::value_type DeviceList::lookupDevice(const Id &i) -{ - return *std::find_if(begin(), end(), [i](const DeviceList::value_type &d) - { return d->id == i; }); +DeviceList::value_type DeviceList::lookupDevice(const Id &i) { + return *std::find_if(begin(), end(), [i](const DeviceList::value_type &d) { + return d->id == i; + }); } -DeviceList::value_type DeviceList::lookupDevice(const Device &d) -{ - auto dev = std::find_if(begin(), end(), [d](const DeviceList::value_type &e) - { return *e == d; }); +DeviceList::value_type DeviceList::lookupDevice(const Device &d) { + auto dev = std::find_if( + begin(), end(), [d](const DeviceList::value_type &e) { return *e == d; }); - return dev == end() ? value_type() : *dev; + return dev == end() ? value_type() : *dev; } -Id::Id(const std::string &str) : - vendor(0), - device(0), - class_code(0) -{ - char *s, *c, *e; - char *tmp = strdup(str.c_str()); +Id::Id(const std::string &str) : vendor(0), device(0), class_code(0) { + char *s, *c, *e; + char *tmp = strdup(str.c_str()); - if (!*tmp) - return; + if (!*tmp) + return; - s = strchr(tmp, ':'); - if (!s) { - free(tmp); - throw RuntimeError("Failed to parse PCI id: ':' expected", str); - } + s = strchr(tmp, ':'); + if (!s) { + free(tmp); + throw RuntimeError("Failed to parse PCI id: ':' expected", str); + } - *s++ = 0; - if (tmp[0] && strcmp(tmp, "*")) { - long int x = strtol(tmp, &e, 16); + *s++ = 0; + if (tmp[0] && strcmp(tmp, "*")) { + long int x = strtol(tmp, &e, 16); - if ((e && *e) || (x < 0 || x > 0xffff)) { - free(tmp); - throw RuntimeError("Failed to parse PCI id: {}: Invalid vendor id", str); - } + if ((e && *e) || (x < 0 || x > 0xffff)) { + free(tmp); + throw RuntimeError("Failed to parse PCI id: {}: Invalid vendor id", str); + } - vendor = x; - } + vendor = x; + } - c = strchr(s, ':'); - if (c) - *c++ = 0; + c = strchr(s, ':'); + if (c) + *c++ = 0; - if (s[0] && strcmp(s, "*")) { - long int x = strtol(s, &e, 16); - if ((e && *e) || (x < 0 || x > 0xffff)) { - free(tmp); - throw RuntimeError("Failed to parse PCI id: {}: Invalid device id", str); - } + if (s[0] && strcmp(s, "*")) { + long int x = strtol(s, &e, 16); + if ((e && *e) || (x < 0 || x > 0xffff)) { + free(tmp); + throw RuntimeError("Failed to parse PCI id: {}: Invalid device id", str); + } - device = x; - } + device = x; + } - if (c && c[0] && strcmp(s, "*")) { - long int x = strtol(c, &e, 16); + if (c && c[0] && strcmp(s, "*")) { + long int x = strtol(c, &e, 16); - if ((e && *e) || (x < 0 || x > 0xffff)) { - free(tmp); - throw RuntimeError("Failed to parse PCI id: {}: Invalid class code", str); - } + if ((e && *e) || (x < 0 || x > 0xffff)) { + free(tmp); + throw RuntimeError("Failed to parse PCI id: {}: Invalid class code", str); + } - class_code = x; - } + class_code = x; + } } -bool Id::operator==(const Id &i) -{ - if ((i.device != 0 && i.device != device) || - (i.vendor != 0 && i.vendor != vendor)) - return false; +bool Id::operator==(const Id &i) { + if ((i.device != 0 && i.device != device) || + (i.vendor != 0 && i.vendor != vendor)) + return false; - if ((i.class_code != 0) || (i.class_code != class_code)) - return false; + if ((i.class_code != 0) || (i.class_code != class_code)) + return false; - return true; + return true; } -Slot::Slot(const std::string &str) : - domain(0), - bus(0), - device(0), - function(0) -{ - char *tmp = strdup(str.c_str()); - char *colon = strrchr(tmp, ':'); - char *dot = strchr((colon ? colon + 1 : tmp), '.'); - char *mid = tmp; - char *e, *buss, *colon2; +Slot::Slot(const std::string &str) : domain(0), bus(0), device(0), function(0) { + char *tmp = strdup(str.c_str()); + char *colon = strrchr(tmp, ':'); + char *dot = strchr((colon ? colon + 1 : tmp), '.'); + char *mid = tmp; + char *e, *buss, *colon2; - if (colon) { - *colon++ = 0; - mid = colon; + if (colon) { + *colon++ = 0; + mid = colon; - colon2 = strchr(tmp, ':'); - if (colon2) { - *colon2++ = 0; - buss = colon2; + colon2 = strchr(tmp, ':'); + if (colon2) { + *colon2++ = 0; + buss = colon2; - if (tmp[0] && strcmp(tmp, "*")) { - long int x = strtol(tmp, &e, 16); - if ((e && *e) || (x < 0 || x > 0x7fffffff)) { - free(tmp); - throw RuntimeError("Failed to parse PCI slot: {}: invalid domain", str); - } + if (tmp[0] && strcmp(tmp, "*")) { + long int x = strtol(tmp, &e, 16); + if ((e && *e) || (x < 0 || x > 0x7fffffff)) { + free(tmp); + throw RuntimeError("Failed to parse PCI slot: {}: invalid domain", + str); + } - domain = x; - } - } - else - buss = tmp; + domain = x; + } + } else + buss = tmp; - if (buss[0] && strcmp(buss, "*")) { - long int x = strtol(buss, &e, 16); - if ((e && *e) || (x < 0 || x > 0xff)) { - free(tmp); - throw RuntimeError("Failed to parse PCI slot: {}: invalid bus", str); - } + if (buss[0] && strcmp(buss, "*")) { + long int x = strtol(buss, &e, 16); + if ((e && *e) || (x < 0 || x > 0xff)) { + free(tmp); + throw RuntimeError("Failed to parse PCI slot: {}: invalid bus", str); + } - bus = x; - } - } + bus = x; + } + } - if (dot) - *dot++ = 0; + if (dot) + *dot++ = 0; - if (mid[0] && strcmp(mid, "*")) { - long int x = strtol(mid, &e, 16); + if (mid[0] && strcmp(mid, "*")) { + long int x = strtol(mid, &e, 16); - if ((e && *e) || (x < 0 || x > 0x1f)) { - free(tmp); - throw RuntimeError("Failed to parse PCI slot: {}: invalid slot", str); - } + if ((e && *e) || (x < 0 || x > 0x1f)) { + free(tmp); + throw RuntimeError("Failed to parse PCI slot: {}: invalid slot", str); + } - device = x; - } + device = x; + } - if (dot && dot[0] && strcmp(dot, "*")) { - long int x = strtol(dot, &e, 16); + if (dot && dot[0] && strcmp(dot, "*")) { + long int x = strtol(dot, &e, 16); - if ((e && *e) || (x < 0 || x > 7)) { - free(tmp); - throw RuntimeError("Failed to parse PCI slot: {}: invalid function", str); - } + if ((e && *e) || (x < 0 || x > 7)) { + free(tmp); + throw RuntimeError("Failed to parse PCI slot: {}: invalid function", str); + } - function = x; - } + function = x; + } - free(tmp); + free(tmp); } -bool Slot::operator==(const Slot &s) -{ - if ((s.domain != 0 && s.domain != domain) || - (s.bus != 0 && s.bus != bus) || - (s.device != 0 && s.device != device) || - (s.function != 0 && s.function != function)) - return false; +bool Slot::operator==(const Slot &s) { + if ((s.domain != 0 && s.domain != domain) || (s.bus != 0 && s.bus != bus) || + (s.device != 0 && s.device != device) || + (s.function != 0 && s.function != function)) + return false; - return true; + return true; } -bool Device::operator==(const Device &f) -{ - return id == f.id && slot == f.slot; +bool Device::operator==(const Device &f) { + return id == f.id && slot == f.slot; } -std::list Device::getRegions() const -{ - FILE *f; - char sysfs[1024]; +std::list Device::getRegions() const { + FILE *f; + char sysfs[1024]; - snprintf(sysfs, sizeof(sysfs), "%s/bus/pci/devices/%04x:%02x:%02x.%x/resource", - SYSFS_PATH, slot.domain, slot.bus, slot.device, slot.function); + snprintf(sysfs, sizeof(sysfs), + "%s/bus/pci/devices/%04x:%02x:%02x.%x/resource", SYSFS_PATH, + slot.domain, slot.bus, slot.device, slot.function); - f = fopen(sysfs, "r"); - if (!f) - throw SystemError("Failed to open resource mapping {}", sysfs); + f = fopen(sysfs, "r"); + if (!f) + throw SystemError("Failed to open resource mapping {}", sysfs); - std::list regions; + std::list regions; - ssize_t bytesRead; - char *line = nullptr; - size_t len = 0; + ssize_t bytesRead; + char *line = nullptr; + size_t len = 0; - int reg_num = 0; + int reg_num = 0; - // Cap to 8 regions, just because we don't know how many may exist. - while (reg_num < 8 && (bytesRead = getline(&line, &len, f)) != -1) { - unsigned long long tokens[3]; - char *s = line; - for (int i = 0; i < 3; i++) { - char *end; - tokens[i] = strtoull(s, &end, 16); - if (s == end) { - log->debug("Error parsing line {} of {}", reg_num + 1, sysfs); - tokens[0] = tokens[1] = 0; // Mark invalid - break; - } - s = end; - } + // Cap to 8 regions, just because we don't know how many may exist. + while (reg_num < 8 && (bytesRead = getline(&line, &len, f)) != -1) { + unsigned long long tokens[3]; + char *s = line; + for (int i = 0; i < 3; i++) { + char *end; + tokens[i] = strtoull(s, &end, 16); + if (s == end) { + log->debug("Error parsing line {} of {}", reg_num + 1, sysfs); + tokens[0] = tokens[1] = 0; // Mark invalid + break; + } + s = end; + } - free(line); + free(line); - // Required for getline() to allocate a new buffer on the next iteration. - line = nullptr; - len = 0; + // Required for getline() to allocate a new buffer on the next iteration. + line = nullptr; + len = 0; - if (tokens[0] != tokens[1]) { // This is a valid region - Region region; + if (tokens[0] != tokens[1]) { // This is a valid region + Region region; - region.num = reg_num; - region.start = tokens[0]; - region.end = tokens[1]; - region.flags = tokens[2]; + region.num = reg_num; + region.start = tokens[0]; + region.end = tokens[1]; + region.flags = tokens[2]; - regions.push_back(region); - } + regions.push_back(region); + } - reg_num++; - } + reg_num++; + } - fclose(f); + fclose(f); - return regions; + return regions; } -std::string Device::getDriver() const -{ - int ret; - char sysfs[1024], syml[1024]; - memset(syml, 0, sizeof(syml)); +std::string Device::getDriver() const { + int ret; + char sysfs[1024], syml[1024]; + memset(syml, 0, sizeof(syml)); - snprintf(sysfs, sizeof(sysfs), "%s/bus/pci/devices/%04x:%02x:%02x.%x/driver", SYSFS_PATH, - slot.domain, slot.bus, slot.device, slot.function); + snprintf(sysfs, sizeof(sysfs), "%s/bus/pci/devices/%04x:%02x:%02x.%x/driver", + SYSFS_PATH, slot.domain, slot.bus, slot.device, slot.function); - struct stat st; - ret = stat(sysfs, &st); - if (ret) - return ""; + struct stat st; + ret = stat(sysfs, &st); + if (ret) + return ""; - ret = readlink(sysfs, syml, sizeof(syml)); - if (ret < 0) - throw SystemError("Failed to follow link: {}", sysfs); + ret = readlink(sysfs, syml, sizeof(syml)); + if (ret < 0) + throw SystemError("Failed to follow link: {}", sysfs); - return basename(syml); + return basename(syml); } -bool Device::attachDriver(const std::string &driver) const -{ - FILE *f; - char fn[1024]; +bool Device::attachDriver(const std::string &driver) const { + FILE *f; + char fn[1024]; - // Add new ID to driver - snprintf(fn, sizeof(fn), "%s/bus/pci/drivers/%s/new_id", SYSFS_PATH, driver.c_str()); - f = fopen(fn, "w"); - if (!f) - throw SystemError("Failed to add PCI id to {} driver ({})", driver, fn); + // Add new ID to driver + snprintf(fn, sizeof(fn), "%s/bus/pci/drivers/%s/new_id", SYSFS_PATH, + driver.c_str()); + f = fopen(fn, "w"); + if (!f) + throw SystemError("Failed to add PCI id to {} driver ({})", driver, fn); - log->info("Adding ID to {} module: {:04x} {:04x}", driver, id.vendor, id.device); - fprintf(f, "%04x %04x", id.vendor, id.device); - fclose(f); + log->info("Adding ID to {} module: {:04x} {:04x}", driver, id.vendor, + id.device); + fprintf(f, "%04x %04x", id.vendor, id.device); + fclose(f); - // Bind to driver - snprintf(fn, sizeof(fn), "%s/bus/pci/drivers/%s/bind", SYSFS_PATH, driver.c_str()); - f = fopen(fn, "w"); - if (!f) - throw SystemError("Failed to bind PCI device to {} driver ({})", driver, fn); + // Bind to driver + snprintf(fn, sizeof(fn), "%s/bus/pci/drivers/%s/bind", SYSFS_PATH, + driver.c_str()); + f = fopen(fn, "w"); + if (!f) + throw SystemError("Failed to bind PCI device to {} driver ({})", driver, + fn); - log->info("Bind device to {} driver", driver); - fprintf(f, "%04x:%02x:%02x.%x\n", slot.domain, slot.bus, slot.device, slot.function); - fclose(f); + log->info("Bind device to {} driver", driver); + fprintf(f, "%04x:%02x:%02x.%x\n", slot.domain, slot.bus, slot.device, + slot.function); + fclose(f); - return true; + return true; } -uint32_t Device::readHostBar(unsigned barNum) const -{ - auto file = openSysFs("resource", std::ios_base::in); +uint32_t Device::readHostBar(unsigned barNum) const { + auto file = openSysFs("resource", std::ios_base::in); - std::string line; + std::string line; - unsigned i; - for (i = 0; i <= barNum && !file.eof(); i++) - std::getline(file, line); + unsigned i; + for (i = 0; i <= barNum && !file.eof(); i++) + std::getline(file, line); - if (i != barNum && file.eof()) - throw RuntimeError("Failed to read resource file"); + if (i != barNum && file.eof()) + throw RuntimeError("Failed to read resource file"); - unsigned long long start, end, flags; - if (std::sscanf(line.c_str(), "%llx %llx %llx", &start, &end, &flags) != 3) - throw SystemError("Failed to parse BAR line"); + unsigned long long start, end, flags; + if (std::sscanf(line.c_str(), "%llx %llx %llx", &start, &end, &flags) != 3) + throw SystemError("Failed to parse BAR line"); - if (end > start) - throw SystemError("Invalid BAR: start={}, end={}", start, end); + if (end > start) + throw SystemError("Invalid BAR: start={}, end={}", start, end); - log->debug("Host BAR: start={:#x}, end={:#x}, size={:#x}, flags={:#x}", start, end, end - start, flags); + log->debug("Host BAR: start={:#x}, end={:#x}, size={:#x}, flags={:#x}", start, + end, end - start, flags); - return start; + return start; } -void Device::rewriteBar(unsigned barNum) -{ - auto hostBar = readHostBar(barNum); - auto configBar = readBar(barNum); +void Device::rewriteBar(unsigned barNum) { + auto hostBar = readHostBar(barNum); + auto configBar = readBar(barNum); - log->debug("Host BAR: {:#x}, configbar: {:#x}", hostBar, configBar); + log->debug("Host BAR: {:#x}, configbar: {:#x}", hostBar, configBar); - if (hostBar == configBar) { - log->debug("BAR is already correct"); - return; - } + if (hostBar == configBar) { + log->debug("BAR is already correct"); + return; + } - log->debug("BAR is incorrect, rewriting"); + log->debug("BAR is incorrect, rewriting"); - writeBar(hostBar, barNum); + writeBar(hostBar, barNum); } -uint32_t Device::readBar(unsigned barNum) const -{ - uint32_t addr; - auto file = openSysFs("config", std::ios_base::in); +uint32_t Device::readBar(unsigned barNum) const { + uint32_t addr; + auto file = openSysFs("config", std::ios_base::in); - file.seekg(PCI_BASE_ADDRESS_N(barNum)); - file.read(reinterpret_cast(&addr), sizeof(addr)); + file.seekg(PCI_BASE_ADDRESS_N(barNum)); + file.read(reinterpret_cast(&addr), sizeof(addr)); - return addr; + return addr; } -void Device::writeBar(uint32_t addr, unsigned barNum) -{ - auto file = openSysFs("config", std::ios_base::out); +void Device::writeBar(uint32_t addr, unsigned barNum) { + auto file = openSysFs("config", std::ios_base::out); - file.seekp(PCI_BASE_ADDRESS_N(barNum)); - file.write(reinterpret_cast(&addr), sizeof(addr)); + file.seekp(PCI_BASE_ADDRESS_N(barNum)); + file.write(reinterpret_cast(&addr), sizeof(addr)); } -int Device::getIommuGroup() const -{ - int ret; - char *group; +int Device::getIommuGroup() const { + int ret; + char *group; - // readlink() does not add a null terminator! - char link[1024] = {0}; - char sysfs[1024]; + // readlink() does not add a null terminator! + char link[1024] = {0}; + char sysfs[1024]; - snprintf(sysfs, sizeof(sysfs), "%s/bus/pci/devices/%04x:%02x:%02x.%x/iommu_group", SYSFS_PATH, - slot.domain, slot.bus, slot.device, slot.function); + snprintf(sysfs, sizeof(sysfs), + "%s/bus/pci/devices/%04x:%02x:%02x.%x/iommu_group", SYSFS_PATH, + slot.domain, slot.bus, slot.device, slot.function); - ret = readlink(sysfs, link, sizeof(link)); - if (ret < 0) - return -1; + ret = readlink(sysfs, link, sizeof(link)); + if (ret < 0) + return -1; - group = basename(link); + group = basename(link); - return atoi(group); + return atoi(group); } -std::fstream Device::openSysFs(const std::string &subPath, std::ios_base::openmode mode) const -{ - std::fstream file; +std::fstream Device::openSysFs(const std::string &subPath, + std::ios_base::openmode mode) const { + std::fstream file; - auto sysFsFilename = fmt::format("{}/bus/pci/devices/{:04x}:{:02x}:{:02x}.{:x}/{}", SYSFS_PATH, - slot.domain, slot.bus, slot.device, slot.function, subPath); + auto sysFsFilename = + fmt::format("{}/bus/pci/devices/{:04x}:{:02x}:{:02x}.{:x}/{}", SYSFS_PATH, + slot.domain, slot.bus, slot.device, slot.function, subPath); - file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - file.open(sysFsFilename, mode); + file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + file.open(sysFsFilename, mode); - return file; + return file; } diff --git a/common/lib/kernel/rt.cpp b/common/lib/kernel/rt.cpp index d66899855..14887fde1 100644 --- a/common/lib/kernel/rt.cpp +++ b/common/lib/kernel/rt.cpp @@ -8,127 +8,132 @@ #include #include -#include -#include #include -#include +#include #include +#include +#include -#include #include #include #ifdef __linux__ - using villas::utils::CpuSet; +using villas::utils::CpuSet; #endif // __linux__ namespace villas { namespace kernel { namespace rt { -void init(int priority, int affinity) -{ - Logger logger = logging.get("kernel:rt"); +void init(int priority, int affinity) { + Logger logger = logging.get("kernel:rt"); - logger->info("Initialize sub-system"); + logger->info("Initialize sub-system"); #ifdef __linux__ - int is_rt, is_isol; - char isolcpus[255]; + int is_rt, is_isol; + char isolcpus[255]; - // Use FIFO scheduler with real time priority - is_rt = isPreemptible(); - if (!is_rt) - logger->warn("We recommend to use an PREEMPT_RT patched kernel!"); + // Use FIFO scheduler with real time priority + is_rt = isPreemptible(); + if (!is_rt) + logger->warn("We recommend to use an PREEMPT_RT patched kernel!"); - if (priority) - setPriority(priority); - else - logger->warn("You might want to use the 'priority' setting to increase " PROJECT_NAME "'s process priority"); + if (priority) + setPriority(priority); + else + logger->warn( + "You might want to use the 'priority' setting to increase " PROJECT_NAME + "'s process priority"); - if (affinity) { - is_isol = getCmdlineParam("isolcpus", isolcpus, sizeof(isolcpus)); - if (is_isol) - logger->warn("You should reserve some cores for " PROJECT_NAME " (see 'isolcpus')"); - else { - CpuSet cset_pin(affinity); - CpuSet cset_isol(isolcpus); - CpuSet cset_non_isol = ~cset_isol & cset_pin; + if (affinity) { + is_isol = getCmdlineParam("isolcpus", isolcpus, sizeof(isolcpus)); + if (is_isol) + logger->warn("You should reserve some cores for " PROJECT_NAME + " (see 'isolcpus')"); + else { + CpuSet cset_pin(affinity); + CpuSet cset_isol(isolcpus); + CpuSet cset_non_isol = ~cset_isol & cset_pin; - if (cset_non_isol.count() > 0) - logger->warn("Affinity setting includes cores which are not isolated: affinity={}, isolcpus={}, non_isolated={}", (std::string) cset_pin, (std::string) cset_isol, (std::string) cset_non_isol); - } + if (cset_non_isol.count() > 0) + logger->warn("Affinity setting includes cores which are not isolated: " + "affinity={}, isolcpus={}, non_isolated={}", + (std::string)cset_pin, (std::string)cset_isol, + (std::string)cset_non_isol); + } - setProcessAffinity(affinity); - } - else - logger->warn("You might want to use the 'affinity' setting to pin " PROJECT_NAME " to dedicate CPU cores"); + setProcessAffinity(affinity); + } else + logger->warn( + "You might want to use the 'affinity' setting to pin " PROJECT_NAME + " to dedicate CPU cores"); #else - logger->warn("This platform is not optimized for real-time execution"); + logger->warn("This platform is not optimized for real-time execution"); - (void) affinity; - (void) priority; + (void)affinity; + (void)priority; #endif // __linux__ } #ifdef __linux__ -void setProcessAffinity(int affinity) -{ - int ret; +void setProcessAffinity(int affinity) { + int ret; - assert(affinity != 0); + assert(affinity != 0); - Logger logger = logging.get("kernel:rt"); + Logger logger = logging.get("kernel:rt"); - // Pin threads to CPUs by setting the affinity - CpuSet cset_pin(affinity); + // Pin threads to CPUs by setting the affinity + CpuSet cset_pin(affinity); - ret = sched_setaffinity(0, cset_pin.size(), cset_pin); - if (ret) - throw SystemError("Failed to set CPU affinity of process"); + ret = sched_setaffinity(0, cset_pin.size(), cset_pin); + if (ret) + throw SystemError("Failed to set CPU affinity of process"); - logger->debug("Set affinity to {} {}", cset_pin.count() == 1 ? "core" : "cores", (std::string) cset_pin); + logger->debug("Set affinity to {} {}", + cset_pin.count() == 1 ? "core" : "cores", + (std::string)cset_pin); } -void setThreadAffinity(pthread_t thread, int affinity) -{ - int ret; +void setThreadAffinity(pthread_t thread, int affinity) { + int ret; - assert(affinity != 0); + assert(affinity != 0); - Logger logger = logging.get("kernel:rt"); + Logger logger = logging.get("kernel:rt"); - CpuSet cset_pin(affinity); + CpuSet cset_pin(affinity); - ret = pthread_setaffinity_np(thread, cset_pin.size(), cset_pin); - if (ret) - throw SystemError("Failed to set CPU affinity of thread"); + ret = pthread_setaffinity_np(thread, cset_pin.size(), cset_pin); + if (ret) + throw SystemError("Failed to set CPU affinity of thread"); - logger->debug("Set affinity of thread {} to {} {}", (long unsigned) thread, cset_pin.count() == 1 ? "core" : "cores", (std::string) cset_pin); + logger->debug("Set affinity of thread {} to {} {}", (long unsigned)thread, + cset_pin.count() == 1 ? "core" : "cores", + (std::string)cset_pin); } -void setPriority(int priority) -{ - int ret; - struct sched_param param; - param.sched_priority = priority; +void setPriority(int priority) { + int ret; + struct sched_param param; + param.sched_priority = priority; - Logger logger = logging.get("kernel:rt"); + Logger logger = logging.get("kernel:rt"); - ret = sched_setscheduler(0, SCHED_FIFO, ¶m); - if (ret) - throw SystemError("Failed to set real time priority"); + ret = sched_setscheduler(0, SCHED_FIFO, ¶m); + if (ret) + throw SystemError("Failed to set real time priority"); - logger->debug("Task priority set to {}", priority); + logger->debug("Task priority set to {}", priority); } -bool isPreemptible() -{ - return access(SYSFS_PATH "/kernel/realtime", R_OK) == 0; +bool isPreemptible() { + return access(SYSFS_PATH "/kernel/realtime", R_OK) == 0; } #endif // __linux__ -} // namespace villas -} // namespace kernel } // namespace rt +} // namespace kernel +} // namespace villas diff --git a/common/lib/kernel/vfio_container.cpp b/common/lib/kernel/vfio_container.cpp index b813f99a6..2b78faef1 100644 --- a/common/lib/kernel/vfio_container.cpp +++ b/common/lib/kernel/vfio_container.cpp @@ -10,61 +10,62 @@ #define _DEFAULT_SOURCE #if defined(__arm__) || defined(__aarch64__) - #define _LARGEFILE64_SOURCE 1 - #define _FILE_OFFSET_BITS 64 +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 #endif #include -#include -#include -#include #include +#include +#include +#include #include #include #include -#include #include -#include -#include #include +#include +#include +#include #include #include #include #include #include +#include +#include using namespace villas::kernel::vfio; #ifndef VFIO_NOIOMMU_IOMMU - #define VFIO_NOIOMMU_IOMMU 8 +#define VFIO_NOIOMMU_IOMMU 8 #endif -static -std::array construct_vfio_extension_str() { - std::array ret; - ret[VFIO_TYPE1_IOMMU] = "Type 1"; - ret[VFIO_SPAPR_TCE_IOMMU] = "SPAPR TCE"; - ret[VFIO_TYPE1v2_IOMMU] = "Type 1 v2"; - ret[VFIO_DMA_CC_IOMMU] = "DMA CC"; - ret[VFIO_EEH] = "EEH"; - ret[VFIO_TYPE1_NESTING_IOMMU] = "Type 1 Nesting"; - ret[VFIO_SPAPR_TCE_v2_IOMMU] = "SPAPR TCE v2"; - ret[VFIO_NOIOMMU_IOMMU] = "No IOMMU"; +static std::array construct_vfio_extension_str() { + std::array ret; + ret[VFIO_TYPE1_IOMMU] = "Type 1"; + ret[VFIO_SPAPR_TCE_IOMMU] = "SPAPR TCE"; + ret[VFIO_TYPE1v2_IOMMU] = "Type 1 v2"; + ret[VFIO_DMA_CC_IOMMU] = "DMA CC"; + ret[VFIO_EEH] = "EEH"; + ret[VFIO_TYPE1_NESTING_IOMMU] = "Type 1 Nesting"; + ret[VFIO_SPAPR_TCE_v2_IOMMU] = "SPAPR TCE v2"; + ret[VFIO_NOIOMMU_IOMMU] = "No IOMMU"; // Backwards compatability with older kernels #ifdef VFIO_UNMAP_ALL - ret[VFIO_UNMAP_ALL] = "Unmap all"; + ret[VFIO_UNMAP_ALL] = "Unmap all"; #endif #ifdef VFIO_UPDATE_VADDR - ret[VFIO_UPDATE_VADDR] = "Update vaddr"; + ret[VFIO_UPDATE_VADDR] = "Update vaddr"; #endif - return ret; + return ret; } -static -std::array VFIO_EXTENSION_STR = construct_vfio_extension_str(); +static std::array VFIO_EXTENSION_STR = + construct_vfio_extension_str(); Container::Container() : fd(-1), @@ -82,231 +83,232 @@ Container::Container() : } } - // Create a VFIO Container - fd = open(VFIO_DEV, O_RDWR); - if (fd < 0) - throw RuntimeError("Failed to open VFIO container"); + // Create a VFIO Container + fd = open(VFIO_DEV, O_RDWR); + if (fd < 0) + throw RuntimeError("Failed to open VFIO container"); - // Check VFIO API version - version = ioctl(fd, VFIO_GET_API_VERSION); - if (version < 0 || version != VFIO_API_VERSION) - throw RuntimeError("Unknown API version: {}", version); + // Check VFIO API version + version = ioctl(fd, VFIO_GET_API_VERSION); + if (version < 0 || version != VFIO_API_VERSION) + throw RuntimeError("Unknown API version: {}", version); - // Check available VFIO extensions (IOMMU types) - for (unsigned int i = VFIO_TYPE1_IOMMU; i < EXTENSION_SIZE; i++) { - int ret = ioctl(fd, VFIO_CHECK_EXTENSION, i); + // Check available VFIO extensions (IOMMU types) + for (unsigned int i = VFIO_TYPE1_IOMMU; i < EXTENSION_SIZE; i++) { + int ret = ioctl(fd, VFIO_CHECK_EXTENSION, i); - extensions[i] = ret != 0; + extensions[i] = ret != 0; - log->debug("VFIO extension {} is {} ({})", i, extensions[i] ? "available" : "not available", VFIO_EXTENSION_STR[i]); - } + log->debug("VFIO extension {} is {} ({})", i, + extensions[i] ? "available" : "not available", + VFIO_EXTENSION_STR[i]); + } - if (extensions[VFIO_TYPE1_IOMMU]) { - log->debug("Using VFIO type {} ({})", VFIO_TYPE1_IOMMU, VFIO_EXTENSION_STR[VFIO_TYPE1_IOMMU]); - hasIommu = true; - } else if (extensions[VFIO_NOIOMMU_IOMMU]) { - log->debug("Using VFIO type {} ({})", VFIO_NOIOMMU_IOMMU, VFIO_EXTENSION_STR[VFIO_NOIOMMU_IOMMU]); - hasIommu = false; - } else - throw RuntimeError("No supported IOMMU type available"); + if (extensions[VFIO_TYPE1_IOMMU]) { + log->debug("Using VFIO type {} ({})", VFIO_TYPE1_IOMMU, + VFIO_EXTENSION_STR[VFIO_TYPE1_IOMMU]); + hasIommu = true; + } else if (extensions[VFIO_NOIOMMU_IOMMU]) { + log->debug("Using VFIO type {} ({})", VFIO_NOIOMMU_IOMMU, + VFIO_EXTENSION_STR[VFIO_NOIOMMU_IOMMU]); + hasIommu = false; + } else + throw RuntimeError("No supported IOMMU type available"); - log->debug("Version: {:#x}", version); - log->debug("IOMMU: {}", hasIommu ? "yes" : "no"); + log->debug("Version: {:#x}", version); + log->debug("IOMMU: {}", hasIommu ? "yes" : "no"); } -Container::~Container() -{ - // Release memory and close fds - groups.clear(); +Container::~Container() { + // Release memory and close fds + groups.clear(); - log->debug("Cleaning up container with fd {}", fd); + log->debug("Cleaning up container with fd {}", fd); - // Close container - int ret = close(fd); - if (ret < 0) - log->error("Error closing vfio container fd {}: {}", fd, ret); + // Close container + int ret = close(fd); + if (ret < 0) + log->error("Error closing vfio container fd {}: {}", fd, ret); } -void Container::attachGroup(std::shared_ptr group) -{ - if (group->isAttachedToContainer()) - throw RuntimeError("Group is already attached to a container"); +void Container::attachGroup(std::shared_ptr group) { + if (group->isAttachedToContainer()) + throw RuntimeError("Group is already attached to a container"); - // Claim group ownership - int ret = ioctl(group->getFileDescriptor(), VFIO_GROUP_SET_CONTAINER, &fd); - if (ret < 0) - throw SystemError("Failed to attach VFIO group {} to container fd {}", - group->getIndex(), fd); + // Claim group ownership + int ret = ioctl(group->getFileDescriptor(), VFIO_GROUP_SET_CONTAINER, &fd); + if (ret < 0) + throw SystemError("Failed to attach VFIO group {} to container fd {}", + group->getIndex(), fd); - // Set IOMMU type - int iommu_type = isIommuEnabled() ? VFIO_TYPE1_IOMMU : VFIO_NOIOMMU_IOMMU; + // Set IOMMU type + int iommu_type = isIommuEnabled() ? VFIO_TYPE1_IOMMU : VFIO_NOIOMMU_IOMMU; - ret = ioctl(fd, VFIO_SET_IOMMU, iommu_type); - if (ret < 0) - throw SystemError("Failed to set IOMMU type of container"); + ret = ioctl(fd, VFIO_SET_IOMMU, iommu_type); + if (ret < 0) + throw SystemError("Failed to set IOMMU type of container"); - group->setAttachedToContainer(); + group->setAttachedToContainer(); - log->debug("Attached new group {} to VFIO container with fd {}", group->getIndex(), fd); + log->debug("Attached new group {} to VFIO container with fd {}", + group->getIndex(), fd); - // Push to our list - groups.push_back(std::move(group)); + // Push to our list + groups.push_back(std::move(group)); } -std::shared_ptr Container::getOrAttachGroup(int index) -{ - // Search if group with index already exists - for (auto &group : groups) { - if (group->getIndex() == index) - return group; - } +std::shared_ptr Container::getOrAttachGroup(int index) { + // Search if group with index already exists + for (auto &group : groups) { + if (group->getIndex() == index) + return group; + } - // Group not yet part of this container, so acquire ownership - auto group = std::make_shared(index, isIommuEnabled()); - attachGroup(group); + // Group not yet part of this container, so acquire ownership + auto group = std::make_shared(index, isIommuEnabled()); + attachGroup(group); - return group; + return group; } -void Container::dump() -{ - log->info("File descriptor: {}", fd); - log->info("Version: {}", version); +void Container::dump() { + log->info("File descriptor: {}", fd); + log->info("Version: {}", version); - // Check available VFIO extensions (IOMMU types) - for (size_t i = 0; i < extensions.size(); i++) - log->debug("VFIO extension {} ({}) is {}", extensions[i], VFIO_EXTENSION_STR[i], extensions[i] ? "available" : "not available"); + // Check available VFIO extensions (IOMMU types) + for (size_t i = 0; i < extensions.size(); i++) + log->debug("VFIO extension {} ({}) is {}", extensions[i], + VFIO_EXTENSION_STR[i], + extensions[i] ? "available" : "not available"); - for (auto &group : groups) - group->dump(); + for (auto &group : groups) + group->dump(); } -std::shared_ptr Container::attachDevice(const std::string& name, int index) -{ - auto group = getOrAttachGroup(index); - auto device = group->attachDevice(name); +std::shared_ptr Container::attachDevice(const std::string &name, + int index) { + auto group = getOrAttachGroup(index); + auto device = group->attachDevice(name); - return device; + return device; } -std::shared_ptr Container::attachDevice(pci::Device &pdev) -{ - int ret; - char name[32], iommu_state[4]; - static constexpr - const char* kernelDriver = "vfio-pci"; +std::shared_ptr Container::attachDevice(pci::Device &pdev) { + int ret; + char name[32], iommu_state[4]; + static constexpr const char *kernelDriver = "vfio-pci"; - // Load PCI bus driver for VFIO - if (kernel::loadModule("vfio_pci")) - throw RuntimeError("Failed to load kernel driver: vfio_pci"); + // Load PCI bus driver for VFIO + if (kernel::loadModule("vfio_pci")) + throw RuntimeError("Failed to load kernel driver: vfio_pci"); - // Bind PCI card to vfio-pci driver if not already bound - if (pdev.getDriver() != kernelDriver) { - log->debug("Bind PCI card to kernel driver '{}'", kernelDriver); - pdev.attachDriver(kernelDriver); - } + // Bind PCI card to vfio-pci driver if not already bound + if (pdev.getDriver() != kernelDriver) { + log->debug("Bind PCI card to kernel driver '{}'", kernelDriver); + pdev.attachDriver(kernelDriver); + } - try { - pdev.rewriteBar(); - } catch (std::exception &e) { - throw RuntimeError("BAR of device is in inconsistent state. Rewriting the BAR " - "failed. Please remove, rescan and reset the device and try again."); - } + try { + pdev.rewriteBar(); + } catch (std::exception &e) { + throw RuntimeError( + "BAR of device is in inconsistent state. Rewriting the BAR " + "failed. Please remove, rescan and reset the device and try again."); + } - // Get IOMMU group of device - int index = isIommuEnabled() ? pdev.getIommuGroup() : 0; - if (index < 0) { - ret = kernel::getCmdlineParam("intel_iommu", iommu_state, sizeof(iommu_state)); - if (ret != 0 || strcmp("on", iommu_state) != 0) - log->warn("Kernel booted without command line parameter " - "'intel_iommu' set to 'on'. Please check documentation " - "(https://villas.fein-aachen.org/doc/fpga-setup.html) " - "for help with troubleshooting."); + // Get IOMMU group of device + int index = isIommuEnabled() ? pdev.getIommuGroup() : 0; + if (index < 0) { + ret = kernel::getCmdlineParam("intel_iommu", iommu_state, + sizeof(iommu_state)); + if (ret != 0 || strcmp("on", iommu_state) != 0) + log->warn("Kernel booted without command line parameter " + "'intel_iommu' set to 'on'. Please check documentation " + "(https://villas.fein-aachen.org/doc/fpga-setup.html) " + "for help with troubleshooting."); - throw RuntimeError("Failed to get IOMMU group of device"); - } + throw RuntimeError("Failed to get IOMMU group of device"); + } - // VFIO device name consists of PCI BDF - snprintf(name, sizeof(name), "%04x:%02x:%02x.%x", pdev.slot.domain, - pdev.slot.bus, pdev.slot.device, pdev.slot.function); + // VFIO device name consists of PCI BDF + snprintf(name, sizeof(name), "%04x:%02x:%02x.%x", pdev.slot.domain, + pdev.slot.bus, pdev.slot.device, pdev.slot.function); - log->info("Attach to device {} with index {}", std::string(name), index); - auto group = getOrAttachGroup(index); - auto device = group->attachDevice(name, &pdev); + log->info("Attach to device {} with index {}", std::string(name), index); + auto group = getOrAttachGroup(index); + auto device = group->attachDevice(name, &pdev); - // Check if this is really a vfio-pci device - if (!device->isVfioPciDevice()) - throw RuntimeError("Device is not a vfio-pci device"); + // Check if this is really a vfio-pci device + if (!device->isVfioPciDevice()) + throw RuntimeError("Device is not a vfio-pci device"); - return device; + return device; } -uintptr_t Container::memoryMap(uintptr_t virt, uintptr_t phys, size_t length) -{ - int ret; +uintptr_t Container::memoryMap(uintptr_t virt, uintptr_t phys, size_t length) { + int ret; - if (not hasIommu) { - log->error("DMA mapping not supported without IOMMU"); - return UINTPTR_MAX; - } + if (not hasIommu) { + log->error("DMA mapping not supported without IOMMU"); + return UINTPTR_MAX; + } - if (length & 0xFFF) { - length += 0x1000; - length &= ~0xFFF; - } + if (length & 0xFFF) { + length += 0x1000; + length &= ~0xFFF; + } - // Super stupid allocator - size_t iovaIncrement = 0; - if (phys == UINTPTR_MAX) { - phys = this->iova_next; - iovaIncrement = length; - } + // Super stupid allocator + size_t iovaIncrement = 0; + if (phys == UINTPTR_MAX) { + phys = this->iova_next; + iovaIncrement = length; + } - struct vfio_iommu_type1_dma_map dmaMap; - memset(&dmaMap, 0, sizeof(dmaMap)); + struct vfio_iommu_type1_dma_map dmaMap; + memset(&dmaMap, 0, sizeof(dmaMap)); - dmaMap.argsz = sizeof(dmaMap); - dmaMap.vaddr = virt; - dmaMap.iova = phys; - dmaMap.size = length; - dmaMap.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE; + dmaMap.argsz = sizeof(dmaMap); + dmaMap.vaddr = virt; + dmaMap.iova = phys; + dmaMap.size = length; + dmaMap.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE; - ret = ioctl(this->fd, VFIO_IOMMU_MAP_DMA, &dmaMap); - if (ret) { - log->error("Failed to create DMA mapping: {}", ret); - return UINTPTR_MAX; - } + ret = ioctl(this->fd, VFIO_IOMMU_MAP_DMA, &dmaMap); + if (ret) { + log->error("Failed to create DMA mapping: {}", ret); + return UINTPTR_MAX; + } - log->debug("DMA map size={:#x}, iova={:#x}, vaddr={:#x}", - dmaMap.size, dmaMap.iova, dmaMap.vaddr); + log->debug("DMA map size={:#x}, iova={:#x}, vaddr={:#x}", dmaMap.size, + dmaMap.iova, dmaMap.vaddr); - // Mapping successful, advance IOVA allocator - this->iova_next += iovaIncrement; + // Mapping successful, advance IOVA allocator + this->iova_next += iovaIncrement; - // We intentionally don't return the actual mapped length, the users are - // only guaranteed to have their demanded memory mapped correctly - return dmaMap.iova; + // We intentionally don't return the actual mapped length, the users are + // only guaranteed to have their demanded memory mapped correctly + return dmaMap.iova; } -bool Container::memoryUnmap(uintptr_t phys, size_t length) -{ - int ret; +bool Container::memoryUnmap(uintptr_t phys, size_t length) { + int ret; - if (not hasIommu) - return true; + if (not hasIommu) + return true; - struct vfio_iommu_type1_dma_unmap dmaUnmap; - dmaUnmap.argsz = sizeof(struct vfio_iommu_type1_dma_unmap); - dmaUnmap.flags = 0; - dmaUnmap.iova = phys; - dmaUnmap.size = length; + struct vfio_iommu_type1_dma_unmap dmaUnmap; + dmaUnmap.argsz = sizeof(struct vfio_iommu_type1_dma_unmap); + dmaUnmap.flags = 0; + dmaUnmap.iova = phys; + dmaUnmap.size = length; - ret = ioctl(this->fd, VFIO_IOMMU_UNMAP_DMA, &dmaUnmap); - if (ret) { - log->error("Failed to unmap DMA mapping"); - return false; - } - log->debug("DMA unmap size={:#x}, iova={:#x}", dmaUnmap.size, dmaUnmap.iova); + ret = ioctl(this->fd, VFIO_IOMMU_UNMAP_DMA, &dmaUnmap); + if (ret) { + log->error("Failed to unmap DMA mapping"); + return false; + } + log->debug("DMA unmap size={:#x}, iova={:#x}", dmaUnmap.size, dmaUnmap.iova); - return true; + return true; } diff --git a/common/lib/kernel/vfio_device.cpp b/common/lib/kernel/vfio_device.cpp index e476e227f..9655ddec9 100644 --- a/common/lib/kernel/vfio_device.cpp +++ b/common/lib/kernel/vfio_device.cpp @@ -12,77 +12,68 @@ #define _DEFAULT_SOURCE #if defined(__arm__) || defined(__aarch64__) - #define _LARGEFILE64_SOURCE 1 - #define _FILE_OFFSET_BITS 64 +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 #endif #include -#include -#include #include +#include +#include -#include #include -#include -#include #include +#include +#include +#include #include #include using namespace villas::kernel::vfio; -static -const char *vfio_pci_region_names[] = { - "PCI_BAR0", // VFIO_PCI_BAR0_REGION_INDEX - "PCI_BAR1", // VFIO_PCI_BAR1_REGION_INDEX - "PCI_BAR2", // VFIO_PCI_BAR2_REGION_INDEX - "PCI_BAR3", // VFIO_PCI_BAR3_REGION_INDEX - "PCI_BAR4", // VFIO_PCI_BAR4_REGION_INDEX - "PCI_BAR5", // VFIO_PCI_BAR5_REGION_INDEX - "PCI_ROM", // VFIO_PCI_ROM_REGION_INDEX - "PCI_CONFIG", // VFIO_PCI_CONFIG_REGION_INDEX - "PCI_VGA" // VFIO_PCI_INTX_IRQ_INDEX +static const char *vfio_pci_region_names[] = { + "PCI_BAR0", // VFIO_PCI_BAR0_REGION_INDEX + "PCI_BAR1", // VFIO_PCI_BAR1_REGION_INDEX + "PCI_BAR2", // VFIO_PCI_BAR2_REGION_INDEX + "PCI_BAR3", // VFIO_PCI_BAR3_REGION_INDEX + "PCI_BAR4", // VFIO_PCI_BAR4_REGION_INDEX + "PCI_BAR5", // VFIO_PCI_BAR5_REGION_INDEX + "PCI_ROM", // VFIO_PCI_ROM_REGION_INDEX + "PCI_CONFIG", // VFIO_PCI_CONFIG_REGION_INDEX + "PCI_VGA" // VFIO_PCI_INTX_IRQ_INDEX }; -static -const char *vfio_pci_irq_names[] = { - "PCI_INTX", // VFIO_PCI_INTX_IRQ_INDEX - "PCI_MSI", // VFIO_PCI_MSI_IRQ_INDEX - "PCI_MSIX", // VFIO_PCI_MSIX_IRQ_INDEX - "PCI_ERR", // VFIO_PCI_ERR_IRQ_INDEX - "PCI_REQ" // VFIO_PCI_REQ_IRQ_INDEX +static const char *vfio_pci_irq_names[] = { + "PCI_INTX", // VFIO_PCI_INTX_IRQ_INDEX + "PCI_MSI", // VFIO_PCI_MSI_IRQ_INDEX + "PCI_MSIX", // VFIO_PCI_MSIX_IRQ_INDEX + "PCI_ERR", // VFIO_PCI_ERR_IRQ_INDEX + "PCI_REQ" // VFIO_PCI_REQ_IRQ_INDEX }; -Device::Device(const std::string &name, int groupFileDescriptor, const kernel::pci::Device *pci_device) : - name(name), - fd(-1), - attachedToGroup(false), - groupFd(groupFileDescriptor), - info(), - irqs(), - regions(), - mappings(), - pci_device(pci_device), - log(logging.get("kernel:vfio::Device")) -{ - if (groupFileDescriptor < 0) - throw RuntimeError("Invalid group file descriptor"); +Device::Device(const std::string &name, int groupFileDescriptor, + const kernel::pci::Device *pci_device) + : name(name), fd(-1), attachedToGroup(false), groupFd(groupFileDescriptor), + info(), irqs(), regions(), mappings(), pci_device(pci_device), + log(logging.get("kernel:vfio::Device")) { + if (groupFileDescriptor < 0) + throw RuntimeError("Invalid group file descriptor"); - // Open device fd - fd = ioctl(groupFileDescriptor, VFIO_GROUP_GET_DEVICE_FD, name.c_str()); - if (fd < 0) - throw RuntimeError("Failed to open VFIO device: {}", name.c_str()); + // Open device fd + fd = ioctl(groupFileDescriptor, VFIO_GROUP_GET_DEVICE_FD, name.c_str()); + if (fd < 0) + throw RuntimeError("Failed to open VFIO device: {}", name.c_str()); - // Get device info - info.argsz = sizeof(info); + // Get device info + info.argsz = sizeof(info); - int ret = ioctl(fd, VFIO_DEVICE_GET_INFO, &info); - if (ret < 0) - throw RuntimeError("Failed to get VFIO device info for: {}", name); + int ret = ioctl(fd, VFIO_DEVICE_GET_INFO, &info); + if (ret < 0) + throw RuntimeError("Failed to get VFIO device info for: {}", name); - log->debug("device info: flags: 0x{:x}, num_regions: {}, num_irqs: {}", - info.flags, info.num_regions, info.num_irqs); + log->debug("device info: flags: 0x{:x}, num_regions: {}, num_irqs: {}", + info.flags, info.num_regions, info.num_irqs); if (pci_device != 0) { // device_info.num_region reports always 9 and includes a VGA region, which is only supported on @@ -91,372 +82,348 @@ Device::Device(const std::string &name, int groupFileDescriptor, const kernel::p info.num_regions = VFIO_PCI_CONFIG_REGION_INDEX + 1; } else { info.num_regions = 1; } - // Reserve slots already so that we can use the []-operator for access - irqs.resize(info.num_irqs); - regions.resize(info.num_regions); - mappings.resize(info.num_regions); + // Reserve slots already so that we can use the []-operator for access + irqs.resize(info.num_irqs); + regions.resize(info.num_regions); + mappings.resize(info.num_regions); // Get device regions for (size_t i = 0; i < info.num_regions; i++) { struct vfio_region_info region; memset(®ion, 0, sizeof (region)); - region.argsz = sizeof(region); - region.index = i; + region.argsz = sizeof(region); + region.index = i; - ret = ioctl(fd, VFIO_DEVICE_GET_REGION_INFO, ®ion); - if (ret < 0) - throw RuntimeError("Failed to get region {} of VFIO device: {}", i, name); + ret = ioctl(fd, VFIO_DEVICE_GET_REGION_INFO, ®ion); + if (ret < 0) + throw RuntimeError("Failed to get region {} of VFIO device: {}", i, name); log->debug("region {} info: flags: 0x{:x}, cap_offset: 0x{:x}, size: 0x{:x}, offset: 0x{:x}", region.index, region.flags, region.cap_offset, region.size, region.offset); - regions[i] = region; - } + regions[i] = region; + } - // Get device IRQs - for (size_t i = 0; i < info.num_irqs; i++) { - struct vfio_irq_info irq; - memset(&irq, 0, sizeof (irq)); + // Get device IRQs + for (size_t i = 0; i < info.num_irqs; i++) { + struct vfio_irq_info irq; + memset(&irq, 0, sizeof(irq)); - irq.argsz = sizeof(irq); - irq.index = i; + irq.argsz = sizeof(irq); + irq.index = i; - ret = ioctl(fd, VFIO_DEVICE_GET_IRQ_INFO, &irq); - if (ret < 0) - throw RuntimeError("Failed to get IRQ {} of VFIO device: {}", i, name); + ret = ioctl(fd, VFIO_DEVICE_GET_IRQ_INFO, &irq); + if (ret < 0) + throw RuntimeError("Failed to get IRQ {} of VFIO device: {}", i, name); - log->debug("irq {} info: flags: 0x{:x}, count: {}", - irq.index, irq.flags, irq.count); - - irqs[i] = irq; - } + log->debug("irq {} info: flags: 0x{:x}, count: {}", irq.index, irq.flags, + irq.count); + irqs[i] = irq; + } } -Device::~Device() -{ - log->debug("Cleaning up device {} with fd {}", this->name, this->fd); +Device::~Device() { + log->debug("Cleaning up device {} with fd {}", this->name, this->fd); - for (auto ®ion : regions) { - regionUnmap(region.index); - } - if (isVfioPciDevice()) { - pciHotReset(); - } - reset(); + for (auto ®ion : regions) { + regionUnmap(region.index); + } + if (isVfioPciDevice()) { + pciHotReset(); + } + reset(); - int ret = close(fd); - if (ret != 0) { - log->error("Closing device fd {} failed", fd); - } + int ret = close(fd); + if (ret != 0) { + log->error("Closing device fd {} failed", fd); + } } -bool Device::reset() -{ - log->debug("Resetting device."); - if (this->info.flags & VFIO_DEVICE_FLAGS_RESET) - return ioctl(this->fd, VFIO_DEVICE_RESET) == 0; - else - return false; // Not supported by this device +bool Device::reset() { + log->debug("Resetting device."); + if (this->info.flags & VFIO_DEVICE_FLAGS_RESET) + return ioctl(this->fd, VFIO_DEVICE_RESET) == 0; + else + return false; // Not supported by this device } -void * Device::regionMap(size_t index) -{ - struct vfio_region_info *r = ®ions[index]; +void *Device::regionMap(size_t index) { + struct vfio_region_info *r = ®ions[index]; - if (!(r->flags & VFIO_REGION_INFO_FLAG_MMAP)) - return MAP_FAILED; + if (!(r->flags & VFIO_REGION_INFO_FLAG_MMAP)) + return MAP_FAILED; - int flags = MAP_SHARED; + int flags = MAP_SHARED; #if !(defined(__arm__) || defined(__aarch64__)) - flags |= MAP_SHARED | MAP_32BIT; + flags |= MAP_SHARED | MAP_32BIT; #endif - log->debug("Mapping region {} of size 0x{:x} with flags 0x{:x}", index, r->size, flags); - mappings[index] = mmap(nullptr, r->size, - PROT_READ | PROT_WRITE, - flags, fd, r->offset); + log->debug("Mapping region {} of size 0x{:x} with flags 0x{:x}", index, + r->size, flags); + mappings[index] = + mmap(nullptr, r->size, PROT_READ | PROT_WRITE, flags, fd, r->offset); - return mappings[index]; + return mappings[index]; } -bool Device::regionUnmap(size_t index) -{ - int ret; - struct vfio_region_info *r = ®ions[index]; +bool Device::regionUnmap(size_t index) { + int ret; + struct vfio_region_info *r = ®ions[index]; - if (!mappings[index]) - return false; // Was not mapped + if (!mappings[index]) + return false; // Was not mapped - log->debug("Unmap region {} from device {}", index, name); + log->debug("Unmap region {} from device {}", index, name); - ret = munmap(mappings[index], r->size); - if (ret) - return false; + ret = munmap(mappings[index], r->size); + if (ret) + return false; - mappings[index] = nullptr; + mappings[index] = nullptr; - return true; + return true; } -size_t Device::regionGetSize(size_t index) -{ - if (index >= regions.size()) { - log->error("Index out of range: {} >= {}", index, regions.size()); - throw std::out_of_range("Index out of range"); - } +size_t Device::regionGetSize(size_t index) { + if (index >= regions.size()) { + log->error("Index out of range: {} >= {}", index, regions.size()); + throw std::out_of_range("Index out of range"); + } - return regions[index].size; + return regions[index].size; } -void Device::dump() -{ - log->info("Device {}: regions={}, irqs={}, flags={}", - name, - info.num_regions, - info.num_irqs, - info.flags - ); +void Device::dump() { + log->info("Device {}: regions={}, irqs={}, flags={}", name, info.num_regions, + info.num_irqs, info.flags); - for (size_t i = 0; i < info.num_regions && i < 8; i++) { - struct vfio_region_info *region = ®ions[i]; + for (size_t i = 0; i < info.num_regions && i < 8; i++) { + struct vfio_region_info *region = ®ions[i]; - if (region->size > 0) { - log->info("Region {} {}: size={}, offset={}, flags={}", - region->index, - (info.flags & VFIO_DEVICE_FLAGS_PCI) ? - vfio_pci_region_names[i] : "", - region->size, - region->offset, - region->flags - ); - } - } + if (region->size > 0) { + log->info("Region {} {}: size={}, offset={}, flags={}", region->index, + (info.flags & VFIO_DEVICE_FLAGS_PCI) ? vfio_pci_region_names[i] + : "", + region->size, region->offset, region->flags); + } + } - for (size_t i = 0; i < info.num_irqs; i++) { - struct vfio_irq_info *irq = &irqs[i]; + for (size_t i = 0; i < info.num_irqs; i++) { + struct vfio_irq_info *irq = &irqs[i]; - if (irq->count > 0) { - log->info("IRQ {} {}: count={}, flags={}", - irq->index, - (info.flags & VFIO_DEVICE_FLAGS_PCI ) ? - vfio_pci_irq_names[i] : "", - irq->count, - irq->flags - ); - } - } + if (irq->count > 0) { + log->info("IRQ {} {}: count={}, flags={}", irq->index, + (info.flags & VFIO_DEVICE_FLAGS_PCI) ? vfio_pci_irq_names[i] + : "", + irq->count, irq->flags); + } + } } -bool Device::pciEnable() -{ - int ret; - uint32_t reg; - const off64_t offset = PCI_COMMAND + - (static_cast(VFIO_PCI_CONFIG_REGION_INDEX) << 40); +bool Device::pciEnable() { + int ret; + uint32_t reg; + const off64_t offset = + PCI_COMMAND + (static_cast(VFIO_PCI_CONFIG_REGION_INDEX) << 40); - // Check if this is really a vfio-pci device - if (!(this->info.flags & VFIO_DEVICE_FLAGS_PCI)) - return false; + // Check if this is really a vfio-pci device + if (!(this->info.flags & VFIO_DEVICE_FLAGS_PCI)) + return false; - ret = pread64(this->fd, ®, sizeof(reg), offset); - if (ret != sizeof(reg)) - return false; + ret = pread64(this->fd, ®, sizeof(reg), offset); + if (ret != sizeof(reg)) + return false; - // Enable memory access and PCI bus mastering which is required for DMA - reg |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + // Enable memory access and PCI bus mastering which is required for DMA + reg |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - ret = pwrite64(this->fd, ®, sizeof(reg), offset); - if (ret != sizeof(reg)) - return false; + ret = pwrite64(this->fd, ®, sizeof(reg), offset); + if (ret != sizeof(reg)) + return false; - return true; + return true; } -int Device::pciMsiInit(int efds[]) -{ - // Check if this is really a vfio-pci device - if (not isVfioPciDevice()) - return -1; +int Device::pciMsiInit(int efds[]) { + // Check if this is really a vfio-pci device + if (not isVfioPciDevice()) + return -1; - const size_t irqCount = irqs[VFIO_PCI_MSI_IRQ_INDEX].count; - const size_t irqSetSize = sizeof(struct vfio_irq_set) + - sizeof(int) * irqCount; + const size_t irqCount = irqs[VFIO_PCI_MSI_IRQ_INDEX].count; + const size_t irqSetSize = + sizeof(struct vfio_irq_set) + sizeof(int) * irqCount; - auto *irqSetBuf = new char[irqSetSize]; - if (!irqSetBuf) - throw MemoryAllocationError(); + auto *irqSetBuf = new char[irqSetSize]; + if (!irqSetBuf) + throw MemoryAllocationError(); - auto *irqSet = reinterpret_cast(irqSetBuf); + auto *irqSet = reinterpret_cast(irqSetBuf); - irqSet->argsz = irqSetSize; - // DATA_EVENTFD binds the interrupt to the provided eventfd. - // SET_ACTION_TRIGGER enables kernel->userspace signalling. - irqSet->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER; - irqSet->index = VFIO_PCI_MSI_IRQ_INDEX; - irqSet->start = 0; - irqSet->count = irqCount; + irqSet->argsz = irqSetSize; + // DATA_EVENTFD binds the interrupt to the provided eventfd. + // SET_ACTION_TRIGGER enables kernel->userspace signalling. + irqSet->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER; + irqSet->index = VFIO_PCI_MSI_IRQ_INDEX; + irqSet->start = 0; + irqSet->count = irqCount; - // Now set the new eventfds - for (size_t i = 0; i < irqCount; i++) { - efds[i] = eventfd(0, 0); - if (efds[i] < 0) { - delete[] irqSetBuf; - return -1; - } - } + // Now set the new eventfds + for (size_t i = 0; i < irqCount; i++) { + efds[i] = eventfd(0, 0); + if (efds[i] < 0) { + delete[] irqSetBuf; + return -1; + } + } - memcpy(irqSet->data, efds, sizeof(int) * irqCount); + memcpy(irqSet->data, efds, sizeof(int) * irqCount); - if (ioctl(fd, VFIO_DEVICE_SET_IRQS, irqSet) != 0) { - delete[] irqSetBuf; - return -1; - } + if (ioctl(fd, VFIO_DEVICE_SET_IRQS, irqSet) != 0) { + delete[] irqSetBuf; + return -1; + } - delete[] irqSetBuf; + delete[] irqSetBuf; - return irqCount; + return irqCount; } -int Device::pciMsiDeinit(int efds[]) -{ - // Check if this is really a vfio-pci device - if (not isVfioPciDevice()) - return -1; +int Device::pciMsiDeinit(int efds[]) { + // Check if this is really a vfio-pci device + if (not isVfioPciDevice()) + return -1; - const size_t irqCount = irqs[VFIO_PCI_MSI_IRQ_INDEX].count; - const size_t irqSetSize = sizeof(struct vfio_irq_set) + - sizeof(int) * irqCount; + const size_t irqCount = irqs[VFIO_PCI_MSI_IRQ_INDEX].count; + const size_t irqSetSize = + sizeof(struct vfio_irq_set) + sizeof(int) * irqCount; - auto *irqSetBuf = new char[irqSetSize]; - if (!irqSetBuf) - throw MemoryAllocationError(); + auto *irqSetBuf = new char[irqSetSize]; + if (!irqSetBuf) + throw MemoryAllocationError(); - auto *irqSet = reinterpret_cast(irqSetBuf); + auto *irqSet = reinterpret_cast(irqSetBuf); - irqSet->argsz = irqSetSize; - irqSet->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER; - irqSet->index = VFIO_PCI_MSI_IRQ_INDEX; - irqSet->count = irqCount; - irqSet->start = 0; + irqSet->argsz = irqSetSize; + irqSet->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER; + irqSet->index = VFIO_PCI_MSI_IRQ_INDEX; + irqSet->count = irqCount; + irqSet->start = 0; - for (size_t i = 0; i < irqCount; i++) { - close(efds[i]); - efds[i] = -1; - } + for (size_t i = 0; i < irqCount; i++) { + close(efds[i]); + efds[i] = -1; + } - memcpy(irqSet->data, efds, sizeof(int) * irqCount); + memcpy(irqSet->data, efds, sizeof(int) * irqCount); - if (ioctl(fd, VFIO_DEVICE_SET_IRQS, irqSet) != 0) { - delete[] irqSetBuf; - return -1; - } + if (ioctl(fd, VFIO_DEVICE_SET_IRQS, irqSet) != 0) { + delete[] irqSetBuf; + return -1; + } - delete[] irqSetBuf; + delete[] irqSetBuf; - return irqCount; + return irqCount; } -bool Device::pciMsiFind(int nos[]) -{ - int ret, idx, irq; - char *end, *col, *last, line[1024], name[13]; - FILE *f; +bool Device::pciMsiFind(int nos[]) { + int ret, idx, irq; + char *end, *col, *last, line[1024], name[13]; + FILE *f; - f = fopen("/proc/interrupts", "r"); - if (!f) - return false; + f = fopen("/proc/interrupts", "r"); + if (!f) + return false; - for (int i = 0; i < 32; i++) - nos[i] = -1; + for (int i = 0; i < 32; i++) + nos[i] = -1; - // For each line in /proc/interrupts - while (fgets(line, sizeof(line), f)) { - col = strtok(line, " "); + // For each line in /proc/interrupts + while (fgets(line, sizeof(line), f)) { + col = strtok(line, " "); - // IRQ number is in first column - irq = strtol(col, &end, 10); - if (col == end) - continue; + // IRQ number is in first column + irq = strtol(col, &end, 10); + if (col == end) + continue; - // Find last column of line - do { - last = col; - } while ((col = strtok(nullptr, " "))); + // Find last column of line + do { + last = col; + } while ((col = strtok(nullptr, " "))); - ret = sscanf(last, "vfio-msi[%d](%12[0-9:])", &idx, name); - if (ret == 2) { - if (strstr(this->name.c_str(), name) == this->name.c_str()) - nos[idx] = irq; - } - } + ret = sscanf(last, "vfio-msi[%d](%12[0-9:])", &idx, name); + if (ret == 2) { + if (strstr(this->name.c_str(), name) == this->name.c_str()) + nos[idx] = irq; + } + } - fclose(f); + fclose(f); - return true; + return true; } -bool Device::isVfioPciDevice() const -{ - return info.flags & VFIO_DEVICE_FLAGS_PCI; +bool Device::isVfioPciDevice() const { + return info.flags & VFIO_DEVICE_FLAGS_PCI; } -bool Device::pciHotReset() -{ - // Check if this is really a vfio-pci device - if (!isVfioPciDevice()) - return false; +bool Device::pciHotReset() { + // Check if this is really a vfio-pci device + if (!isVfioPciDevice()) + return false; - log->debug("Performing hot reset."); - const size_t reset_info_len = sizeof(struct vfio_pci_hot_reset_info) + - sizeof(struct vfio_pci_dependent_device) * 64; + log->debug("Performing hot reset."); + const size_t reset_info_len = sizeof(struct vfio_pci_hot_reset_info) + + sizeof(struct vfio_pci_dependent_device) * 64; - auto *reset_info_buf = new char[reset_info_len]; - if (!reset_info_buf) - throw MemoryAllocationError(); + auto *reset_info_buf = new char[reset_info_len]; + if (!reset_info_buf) + throw MemoryAllocationError(); - auto *reset_info = reinterpret_cast(reset_info_buf); + auto *reset_info = + reinterpret_cast(reset_info_buf); - reset_info->argsz = reset_info_len; + reset_info->argsz = reset_info_len; - if (ioctl(fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, reset_info) != 0) { - delete[] reset_info_buf; - return false; - } + if (ioctl(fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, reset_info) != 0) { + delete[] reset_info_buf; + return false; + } - log->debug("Dependent devices for hot-reset:"); - for (size_t i = 0; i < reset_info->count; i++) { - struct vfio_pci_dependent_device *dd = &reset_info->devices[i]; - log->debug(" {:04x}:{:02x}:{:02x}.{:01x}: iommu_group={}", - dd->segment, dd->bus, - PCI_SLOT(dd->devfn), PCI_FUNC(dd->devfn), dd->group_id); - } + log->debug("Dependent devices for hot-reset:"); + for (size_t i = 0; i < reset_info->count; i++) { + struct vfio_pci_dependent_device *dd = &reset_info->devices[i]; + log->debug(" {:04x}:{:02x}:{:02x}.{:01x}: iommu_group={}", dd->segment, + dd->bus, PCI_SLOT(dd->devfn), PCI_FUNC(dd->devfn), dd->group_id); + } - delete[] reset_info_buf; + delete[] reset_info_buf; - const size_t reset_len = sizeof(struct vfio_pci_hot_reset) + - sizeof(int32_t) * 1; - auto *reset_buf = new char[reset_len]; - if (!reset_buf) - throw MemoryAllocationError(); + const size_t reset_len = + sizeof(struct vfio_pci_hot_reset) + sizeof(int32_t) * 1; + auto *reset_buf = new char[reset_len]; + if (!reset_buf) + throw MemoryAllocationError(); - auto *reset = reinterpret_cast(reset_buf); + auto *reset = reinterpret_cast(reset_buf); - reset->argsz = reset_len; - reset->count = 1; - reset->group_fds[0] = groupFd; + reset->argsz = reset_len; + reset->count = 1; + reset->group_fds[0] = groupFd; - int ret = ioctl(fd, VFIO_DEVICE_PCI_HOT_RESET, reset); - const bool success = (ret == 0); + int ret = ioctl(fd, VFIO_DEVICE_PCI_HOT_RESET, reset); + const bool success = (ret == 0); - delete[] reset_buf; + delete[] reset_buf; - if (!success) { - log->warn("PCI hot reset failed, maybe no IOMMU available?"); - return true; - } + if (!success) { + log->warn("PCI hot reset failed, maybe no IOMMU available?"); + return true; + } - return success; + return success; } diff --git a/common/lib/kernel/vfio_group.cpp b/common/lib/kernel/vfio_group.cpp index fdbdb7dd9..c3f5dca5d 100644 --- a/common/lib/kernel/vfio_group.cpp +++ b/common/lib/kernel/vfio_group.cpp @@ -10,127 +10,114 @@ #define _DEFAULT_SOURCE #if defined(__arm__) || defined(__aarch64__) - #define _LARGEFILE64_SOURCE 1 - #define _FILE_OFFSET_BITS 64 +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 #endif #include -#include -#include #include +#include +#include #include #include #include -#include #include -#include -#include #include +#include +#include +#include #include #include using namespace villas::kernel::vfio; -Group::Group(int index, bool iommuEnabled) : - fd(-1), - index(index), - attachedToContainer(false), - status(), - devices(), - log(logging.get("kernel:vfio::Group")) -{ - // Open group fd - std::stringstream groupPath; - groupPath << VFIO_PATH - << (iommuEnabled ? "" : "noiommu-") - << index; +Group::Group(int index, bool iommuEnabled) + : fd(-1), index(index), attachedToContainer(false), status(), devices(), + log(logging.get("kernel:vfio::Group")) { + // Open group fd + std::stringstream groupPath; + groupPath << VFIO_PATH << (iommuEnabled ? "" : "noiommu-") << index; - log->debug("path: {}", groupPath.str().c_str()); - fd = open(groupPath.str().c_str(), O_RDWR); - if (fd < 0) { - log->error("Failed to open VFIO group {}", index); - throw RuntimeError("Failed to open VFIO group"); - } + log->debug("path: {}", groupPath.str().c_str()); + fd = open(groupPath.str().c_str(), O_RDWR); + if (fd < 0) { + log->error("Failed to open VFIO group {}", index); + throw RuntimeError("Failed to open VFIO group"); + } - log->debug("VFIO group {} (fd {}) has path {}", - index, fd, groupPath.str()); - - checkStatus(); + log->debug("VFIO group {} (fd {}) has path {}", index, fd, groupPath.str()); + checkStatus(); } -std::shared_ptr Group::attachDevice(std::shared_ptr device) -{ - if (device->isAttachedToGroup()) - throw RuntimeError("Device is already attached to a group"); +std::shared_ptr Group::attachDevice(std::shared_ptr device) { + if (device->isAttachedToGroup()) + throw RuntimeError("Device is already attached to a group"); - devices.push_back(device); + devices.push_back(device); - device->setAttachedToGroup(); + device->setAttachedToGroup(); - return device; + return device; } -std::shared_ptr Group::attachDevice(const std::string& name, const kernel::pci::Device *pci_device) -{ - auto device = std::make_shared(name, fd, pci_device); - return attachDevice(device); +std::shared_ptr +Group::attachDevice(const std::string &name, + const kernel::pci::Device *pci_device) { + auto device = std::make_shared(name, fd, pci_device); + return attachDevice(device); } -bool Group::checkStatus() -{ - int ret; +bool Group::checkStatus() { + int ret; - // Check group viability and features - status.argsz = sizeof(status); + // Check group viability and features + status.argsz = sizeof(status); - ret = ioctl(fd, VFIO_GROUP_GET_STATUS, &status); - if (ret < 0) { - log->error("Failed to get VFIO group status"); - return false; - } + ret = ioctl(fd, VFIO_GROUP_GET_STATUS, &status); + if (ret < 0) { + log->error("Failed to get VFIO group status"); + return false; + } - if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) { - log->error("VFIO group is not available: bind all devices to the VFIO driver!"); - return false; - } - log->debug("VFIO group is {} viable", index); - return true; + if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) { + log->error( + "VFIO group is not available: bind all devices to the VFIO driver!"); + return false; + } + log->debug("VFIO group is {} viable", index); + return true; } -void Group::dump() -{ - log->info("VFIO Group {}, viable={}, container={}", - index, - (status.flags & VFIO_GROUP_FLAGS_VIABLE) > 0, - (status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET) > 0 - ); +void Group::dump() { + log->info("VFIO Group {}, viable={}, container={}", index, + (status.flags & VFIO_GROUP_FLAGS_VIABLE) > 0, + (status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET) > 0); - for (auto& device : devices) { - device->dump(); - } + for (auto &device : devices) { + device->dump(); + } } -Group::~Group() -{ - // Release memory and close fds - devices.clear(); +Group::~Group() { + // Release memory and close fds + devices.clear(); - log->debug("Cleaning up group {} with fd {}", index, fd); + log->debug("Cleaning up group {} with fd {}", index, fd); - if (fd < 0) - log->debug("Destructing group that has not been attached"); - else { - log->debug("unsetting group container"); - int ret = ioctl(fd, VFIO_GROUP_UNSET_CONTAINER); - if (ret != 0) - log->error("Cannot unset container for group fd {}", fd); + if (fd < 0) + log->debug("Destructing group that has not been attached"); + else { + log->debug("unsetting group container"); + int ret = ioctl(fd, VFIO_GROUP_UNSET_CONTAINER); + if (ret != 0) + log->error("Cannot unset container for group fd {}", fd); - ret = close(fd); - if (ret != 0) - log->error("Cannot close group fd {}", fd); - } + ret = close(fd); + if (ret != 0) + log->error("Cannot close group fd {}", fd); + } } diff --git a/common/lib/list.cpp b/common/lib/list.cpp index 6feed97e4..fbac03205 100644 --- a/common/lib/list.cpp +++ b/common/lib/list.cpp @@ -7,8 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include #include @@ -18,263 +18,248 @@ using namespace villas; -int villas::list_init(struct List *l) -{ - pthread_mutex_init(&l->lock, nullptr); +int villas::list_init(struct List *l) { + pthread_mutex_init(&l->lock, nullptr); - l->length = 0; - l->capacity = 0; - l->array = nullptr; - l->state = State::INITIALIZED; + l->length = 0; + l->capacity = 0; + l->array = nullptr; + l->state = State::INITIALIZED; - return 0; + return 0; } -int villas::list_destroy(struct List *l, dtor_cb_t destructor, bool release) -{ - pthread_mutex_lock(&l->lock); +int villas::list_destroy(struct List *l, dtor_cb_t destructor, bool release) { + pthread_mutex_lock(&l->lock); - assert(l->state != State::DESTROYED); + assert(l->state != State::DESTROYED); - for (size_t i = 0; i < list_length(l); i++) { - void *e = list_at(l, i); + for (size_t i = 0; i < list_length(l); i++) { + void *e = list_at(l, i); - if (destructor) - destructor(e); - if (release) - free(e); - } + if (destructor) + destructor(e); + if (release) + free(e); + } - free(l->array); + free(l->array); - l->length = -1; - l->capacity = 0; - l->array = nullptr; - l->state = State::DESTROYED; + l->length = -1; + l->capacity = 0; + l->array = nullptr; + l->state = State::DESTROYED; - pthread_mutex_unlock(&l->lock); - pthread_mutex_destroy(&l->lock); + pthread_mutex_unlock(&l->lock); + pthread_mutex_destroy(&l->lock); - return 0; + return 0; } -void villas::list_push(struct List *l, void *p) -{ - pthread_mutex_lock(&l->lock); +void villas::list_push(struct List *l, void *p) { + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - // Resize array if out of capacity - if (l->length >= l->capacity) { - l->capacity += LIST_CHUNKSIZE; - l->array = (void **) realloc(l->array, l->capacity * sizeof(void *)); - } + // Resize array if out of capacity + if (l->length >= l->capacity) { + l->capacity += LIST_CHUNKSIZE; + l->array = (void **)realloc(l->array, l->capacity * sizeof(void *)); + } - l->array[l->length] = p; - l->length++; + l->array[l->length] = p; + l->length++; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); } -void villas::list_clear(struct List *l) -{ - pthread_mutex_lock(&l->lock); +void villas::list_clear(struct List *l) { + pthread_mutex_lock(&l->lock); - l->length = 0; + l->length = 0; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); } -int villas::list_remove(struct List *l, size_t idx) -{ - pthread_mutex_lock(&l->lock); +int villas::list_remove(struct List *l, size_t idx) { + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - if (idx >= l->length) - return -1; + if (idx >= l->length) + return -1; - for (size_t i = idx; i < l->length - 1; i++) - l->array[i] = l->array[i+1]; + for (size_t i = idx; i < l->length - 1; i++) + l->array[i] = l->array[i + 1]; - l->length--; + l->length--; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); - return 0; + return 0; } -int villas::list_insert(struct List *l, size_t idx, void *p) -{ - size_t i; - void *t, *o; +int villas::list_insert(struct List *l, size_t idx, void *p) { + size_t i; + void *t, *o; - pthread_mutex_lock(&l->lock); + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - if (idx >= l->length) - return -1; + if (idx >= l->length) + return -1; - // Resize array if out of capacity - if (l->length + 1 > l->capacity) { - l->capacity += LIST_CHUNKSIZE; - l->array = (void **) realloc(l->array, l->capacity * sizeof(void *)); - } + // Resize array if out of capacity + if (l->length + 1 > l->capacity) { + l->capacity += LIST_CHUNKSIZE; + l->array = (void **)realloc(l->array, l->capacity * sizeof(void *)); + } - o = p; - for (i = idx; i < l->length; i++) { - t = l->array[i]; - l->array[i] = o; - o = t; - } + o = p; + for (i = idx; i < l->length; i++) { + t = l->array[i]; + l->array[i] = o; + o = t; + } - l->array[l->length] = o; - l->length++; + l->array[l->length] = o; + l->length++; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); - return 0; + return 0; } -void villas::list_remove_all(struct List *l, void *p) -{ - int removed = 0; +void villas::list_remove_all(struct List *l, void *p) { + int removed = 0; - pthread_mutex_lock(&l->lock); + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - for (size_t i = 0; i < list_length(l); i++) { - if (list_at(l, i) == p) - removed++; - else - l->array[i - removed] = list_at(l, i); - } + for (size_t i = 0; i < list_length(l); i++) { + if (list_at(l, i) == p) + removed++; + else + l->array[i - removed] = list_at(l, i); + } - l->length -= removed; + l->length -= removed; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); } -int villas::list_contains(struct List *l, void *p) -{ - return list_count(l, [](const void *a, const void *b) { - return a == b ? 0 : 1; - }, p); +int villas::list_contains(struct List *l, void *p) { + return list_count( + l, [](const void *a, const void *b) { return a == b ? 0 : 1; }, p); } -int villas::list_count(struct List *l, cmp_cb_t cmp, void *ctx) -{ - int c = 0; - void *e; +int villas::list_count(struct List *l, cmp_cb_t cmp, void *ctx) { + int c = 0; + void *e; - pthread_mutex_lock(&l->lock); + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - for (size_t i = 0; i < list_length(l); i++) { - e = list_at(l, i); - if (cmp(e, ctx) == 0) - c++; - } + for (size_t i = 0; i < list_length(l); i++) { + e = list_at(l, i); + if (cmp(e, ctx) == 0) + c++; + } - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); - return c; + return c; } -void * villas::list_search(struct List *l, cmp_cb_t cmp, const void *ctx) -{ - void *e; +void *villas::list_search(struct List *l, cmp_cb_t cmp, const void *ctx) { + void *e; - pthread_mutex_lock(&l->lock); + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - for (size_t i = 0; i < list_length(l); i++) { - e = list_at(l, i); - if (cmp(e, ctx) == 0) - goto out; - } + for (size_t i = 0; i < list_length(l); i++) { + e = list_at(l, i); + if (cmp(e, ctx) == 0) + goto out; + } - e = nullptr; // Not found + e = nullptr; // Not found -out: pthread_mutex_unlock(&l->lock); +out: + pthread_mutex_unlock(&l->lock); - return e; + return e; } -void villas::list_sort(struct List *l, cmp_cb_t cmp) -{ - pthread_mutex_lock(&l->lock); +void villas::list_sort(struct List *l, cmp_cb_t cmp) { + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - auto array = std::vector(l->array, l->array + l->length); + auto array = std::vector(l->array, l->array + l->length); - std::sort(array.begin(), array.end(), [cmp](void *&a, void *&b) -> bool { - return cmp(a, b) < 0; - }); + std::sort(array.begin(), array.end(), + [cmp](void *&a, void *&b) -> bool { return cmp(a, b) < 0; }); - std::copy(array.begin(), array.end(), l->array); + std::copy(array.begin(), array.end(), l->array); - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); } -int villas::list_set(struct List *l, unsigned index, void *value) -{ - if (index >= l->length) - return -1; +int villas::list_set(struct List *l, unsigned index, void *value) { + if (index >= l->length) + return -1; - l->array[index] = value; + l->array[index] = value; - return 0; + return 0; } -ssize_t villas::list_index(struct List *l, void *p) -{ - void *e; - ssize_t f; +ssize_t villas::list_index(struct List *l, void *p) { + void *e; + ssize_t f; - pthread_mutex_lock(&l->lock); + pthread_mutex_lock(&l->lock); - assert(l->state == State::INITIALIZED); + assert(l->state == State::INITIALIZED); - for (size_t i = 0; i < list_length(l); i++) { - e = list_at(l, i); - if (e == p) { - f = i; - goto found; - } - } + for (size_t i = 0; i < list_length(l); i++) { + e = list_at(l, i); + if (e == p) { + f = i; + goto found; + } + } - f = -1; + f = -1; -found: pthread_mutex_unlock(&l->lock); +found: + pthread_mutex_unlock(&l->lock); - return f; + return f; } -void villas::list_extend(struct List *l, size_t len, void *val) -{ - while (list_length(l) < len) - list_push(l, val); +void villas::list_extend(struct List *l, size_t len, void *val) { + while (list_length(l) < len) + list_push(l, val); } -void villas::list_filter(struct List *l, dtor_cb_t cb) -{ - size_t i, j; - pthread_mutex_lock(&l->lock); +void villas::list_filter(struct List *l, dtor_cb_t cb) { + size_t i, j; + pthread_mutex_lock(&l->lock); - for (i = 0, j = 0; i < list_length(l); i++) { - void *e = list_at(l, i); + for (i = 0, j = 0; i < list_length(l); i++) { + void *e = list_at(l, i); - if (!cb(e)) - l->array[j++] = e; - } + if (!cb(e)) + l->array[j++] = e; + } - l->length = j; + l->length = j; - pthread_mutex_unlock(&l->lock); + pthread_mutex_unlock(&l->lock); } diff --git a/common/lib/log.cpp b/common/lib/log.cpp index 4552a5c4c..708b5b83b 100644 --- a/common/lib/log.cpp +++ b/common/lib/log.cpp @@ -5,219 +5,195 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include #include -#include #include +#include +#include #include #include -#include using namespace villas; // The global log instance Log villas::logging; -static -std::map levelNames = { - { spdlog::level::trace, "trc" }, - { spdlog::level::debug, "dbg" }, - { spdlog::level::info, "info" }, - { spdlog::level::warn, "warn" }, - { spdlog::level::err, "err" }, - { spdlog::level::critical, "crit" }, - { spdlog::level::off, "off" } -}; +static std::map levelNames = { + {spdlog::level::trace, "trc"}, {spdlog::level::debug, "dbg"}, + {spdlog::level::info, "info"}, {spdlog::level::warn, "warn"}, + {spdlog::level::err, "err"}, {spdlog::level::critical, "crit"}, + {spdlog::level::off, "off"}}; class CustomLevelFlag : public spdlog::custom_flag_formatter { public: - void format(const spdlog::details::log_msg &msg, const std::tm &, spdlog::memory_buf_t &dest) override - { - auto lvl = levelNames[msg.level]; - auto lvlpad = std::string(padinfo_.width_ - lvl.size(), ' ') + lvl; - dest.append(lvlpad.data(), lvlpad.data() + lvlpad.size()); - } + void format(const spdlog::details::log_msg &msg, const std::tm &, + spdlog::memory_buf_t &dest) override { + auto lvl = levelNames[msg.level]; + auto lvlpad = std::string(padinfo_.width_ - lvl.size(), ' ') + lvl; + dest.append(lvlpad.data(), lvlpad.data() + lvlpad.size()); + } - spdlog::details::padding_info get_padding_info() - { - return padinfo_; - } + spdlog::details::padding_info get_padding_info() { return padinfo_; } - std::unique_ptr clone() const override - { - return spdlog::details::make_unique(); - } + std::unique_ptr clone() const override { + return spdlog::details::make_unique(); + } }; -Log::Log(Level lvl) : - level(lvl), - pattern("%H:%M:%S %^%-4t%$ %-16n %v") -{ - char *p = getenv("VILLAS_LOG_PREFIX"); +Log::Log(Level lvl) : level(lvl), pattern("%H:%M:%S %^%-4t%$ %-16n %v") { + char *p = getenv("VILLAS_LOG_PREFIX"); - sinks = std::make_shared(); + sinks = std::make_shared(); - setLevel(level); - setFormatter(pattern, p ? p : ""); + setLevel(level); + setFormatter(pattern, p ? p : ""); - // Default sink - sink = std::make_shared(); + // Default sink + sink = std::make_shared(); - sinks->add_sink(sink); + sinks->add_sink(sink); } -int Log::getWidth() -{ - int width = Terminal::getCols() - 50; +int Log::getWidth() { + int width = Terminal::getCols() - 50; - if (!prefix.empty()) - width -= prefix.length(); + if (!prefix.empty()) + width -= prefix.length(); - return width; + return width; } -Logger Log::get(const std::string &name) -{ - Logger logger = spdlog::get(name); +Logger Log::get(const std::string &name) { + Logger logger = spdlog::get(name); - if (not logger) { - logger = std::make_shared(name, sinks); + if (not logger) { + logger = std::make_shared(name, sinks); - logger->set_level(level); - logger->set_formatter(formatter->clone()); + logger->set_level(level); + logger->set_formatter(formatter->clone()); - for (auto &expr : expressions) { - int flags = 0; + for (auto &expr : expressions) { + int flags = 0; #ifdef FNM_EXTMATCH - // musl-libc doesnt support this flag yet - flags |= FNM_EXTMATCH; + // musl-libc doesnt support this flag yet + flags |= FNM_EXTMATCH; #endif - if (!fnmatch(expr.name.c_str(), name.c_str(), flags)) - logger->set_level(expr.level); - } + if (!fnmatch(expr.name.c_str(), name.c_str(), flags)) + logger->set_level(expr.level); + } - spdlog::register_logger(logger); - } + spdlog::register_logger(logger); + } - return logger; + return logger; } -void Log::parse(json_t *json) -{ - const char *level = nullptr; - const char *path = nullptr; - const char *pattern = nullptr; +void Log::parse(json_t *json) { + const char *level = nullptr; + const char *path = nullptr; + const char *pattern = nullptr; - int ret, syslog = 0; + int ret, syslog = 0; - json_error_t err; - json_t *json_expressions = nullptr; + json_error_t err; + json_t *json_expressions = nullptr; - ret = json_unpack_ex(json, &err, JSON_STRICT, "{ s?: s, s?: s, s?: o, s?: b, s?: s }", - "level", &level, - "file", &path, - "expressions", &json_expressions, - "syslog", &syslog, - "pattern", &pattern - ); - if (ret) - throw ConfigError(json, err, "node-config-logging"); + ret = json_unpack_ex(json, &err, JSON_STRICT, + "{ s?: s, s?: s, s?: o, s?: b, s?: s }", "level", &level, + "file", &path, "expressions", &json_expressions, + "syslog", &syslog, "pattern", &pattern); + if (ret) + throw ConfigError(json, err, "node-config-logging"); - if (level) - setLevel(level); + if (level) + setLevel(level); - if (path) { - auto sink = std::make_shared(path); + if (path) { + auto sink = std::make_shared(path); - sinks->add_sink(sink); - } + sinks->add_sink(sink); + } - if (syslog) { + if (syslog) { #if SPDLOG_VERSION >= 10400 - auto sink = std::make_shared("villas", LOG_PID, LOG_DAEMON, true); + auto sink = std::make_shared( + "villas", LOG_PID, LOG_DAEMON, true); #else - auto sink = std::make_shared("villas", LOG_PID, LOG_DAEMON); + auto sink = std::make_shared( + "villas", LOG_PID, LOG_DAEMON); #endif - sinks->add_sink(sink); - } + sinks->add_sink(sink); + } - if (json_expressions) { - if (!json_is_array(json_expressions)) - throw ConfigError(json_expressions, "node-config-logging-expressions", "The 'expressions' setting must be a list of objects."); + if (json_expressions) { + if (!json_is_array(json_expressions)) + throw ConfigError(json_expressions, "node-config-logging-expressions", + "The 'expressions' setting must be a list of objects."); - size_t i; - json_t *json_expression; + size_t i; + json_t *json_expression; - // cppcheck-suppress unknownMacro - json_array_foreach(json_expressions, i, json_expression) - expressions.emplace_back(json_expression); - } + // cppcheck-suppress unknownMacro + json_array_foreach(json_expressions, i, json_expression) + expressions.emplace_back(json_expression); + } } -void Log::setFormatter(const std::string &pat, const std::string &pfx) -{ - pattern = pat; - prefix = pfx; +void Log::setFormatter(const std::string &pat, const std::string &pfx) { + pattern = pat; + prefix = pfx; - formatter = std::make_shared(spdlog::pattern_time_type::utc); - formatter->add_flag('t'); - formatter->set_pattern(prefix + pattern); + formatter = std::make_shared( + spdlog::pattern_time_type::utc); + formatter->add_flag('t'); + formatter->set_pattern(prefix + pattern); - sinks->set_formatter(formatter->clone()); + sinks->set_formatter(formatter->clone()); } -void Log::setLevel(Level lvl) -{ - level = lvl; +void Log::setLevel(Level lvl) { + level = lvl; - sinks->set_level(lvl); + sinks->set_level(lvl); } -void Log::setLevel(const std::string &lvl) -{ - auto l = SPDLOG_LEVEL_NAMES; +void Log::setLevel(const std::string &lvl) { + auto l = SPDLOG_LEVEL_NAMES; - auto it = std::find(l.begin(), l.end(), lvl); - if (it == l.end()) - throw RuntimeError("Invalid log level {}", lvl); + auto it = std::find(l.begin(), l.end(), lvl); + if (it == l.end()) + throw RuntimeError("Invalid log level {}", lvl); - setLevel(spdlog::level::from_str(lvl)); + setLevel(spdlog::level::from_str(lvl)); } -Log::Level Log::getLevel() const -{ - return level; +Log::Level Log::getLevel() const { return level; } + +std::string Log::getLevelName() const { + auto sv = spdlog::level::to_string_view(level); + + return std::string(sv.data()); } -std::string Log::getLevelName() const -{ - auto sv = spdlog::level::to_string_view(level); +Log::Expression::Expression(json_t *json) { + int ret; - return std::string(sv.data()); -} - -Log::Expression::Expression(json_t *json) -{ - int ret; - - const char *nme; - const char *lvl; - - json_error_t err; - - ret = json_unpack_ex(json, &err, JSON_STRICT, "{ s: s, s: s }", - "name", &nme, - "level", &lvl - ); - if (ret) - throw ConfigError(json, err, "node-config-logging-expressions"); - - level = spdlog::level::from_str(lvl); - name = nme; + const char *nme; + const char *lvl; + + json_error_t err; + + ret = json_unpack_ex(json, &err, JSON_STRICT, "{ s: s, s: s }", "name", &nme, + "level", &lvl); + if (ret) + throw ConfigError(json, err, "node-config-logging-expressions"); + + level = spdlog::level::from_str(lvl); + name = nme; } diff --git a/common/lib/memory.cpp b/common/lib/memory.cpp index c7a4bece9..7fba6281d 100644 --- a/common/lib/memory.cpp +++ b/common/lib/memory.cpp @@ -10,276 +10,260 @@ #include #include -#include #include +#include #include namespace villas { std::unique_ptr -HostRam::HostRamAllocator::allocateBlock(size_t size) -{ - // Align to next bigger page size chunk - if (size & size_t(0xFFF)) { - size += size_t(0x1000); - size &= size_t(~0xFFF); - } +HostRam::HostRamAllocator::allocateBlock(size_t size) { + // Align to next bigger page size chunk + if (size & size_t(0xFFF)) { + size += size_t(0x1000); + size &= size_t(~0xFFF); + } #if defined(__linux__) && !(defined(__arm__) || defined(__aarch64__)) - const int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT; + const int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT; #else - const int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS; + const int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS; #endif - const int mmap_protection = PROT_READ | PROT_WRITE; + const int mmap_protection = PROT_READ | PROT_WRITE; - const void* addr = mmap(nullptr, size, mmap_protection, mmap_flags, 0, 0); - if (addr == nullptr) { - throw std::bad_alloc(); - } + const void *addr = mmap(nullptr, size, mmap_protection, mmap_flags, 0, 0); + if (addr == nullptr) { + throw std::bad_alloc(); + } - auto &mm = MemoryManager::get(); + auto &mm = MemoryManager::get(); - // Assemble name for this block - std::stringstream name; - name << std::showbase << std::hex << reinterpret_cast(addr); + // Assemble name for this block + std::stringstream name; + name << std::showbase << std::hex << reinterpret_cast(addr); - auto blockAddrSpaceId = mm.getProcessAddressSpaceMemoryBlock(name.str()); + auto blockAddrSpaceId = mm.getProcessAddressSpaceMemoryBlock(name.str()); - const auto localAddr = reinterpret_cast(addr); - std::unique_ptr - mem(new MemoryBlock(localAddr, size, blockAddrSpaceId), this->free); + const auto localAddr = reinterpret_cast(addr); + std::unique_ptr mem( + new MemoryBlock(localAddr, size, blockAddrSpaceId), this->free); - insertMemoryBlock(*mem); + insertMemoryBlock(*mem); - return mem; + return mem; } // cppcheck-suppress passedByValue -LinearAllocator::LinearAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId, - size_t memorySize, - size_t internalOffset) : - BaseAllocator(memoryAddrSpaceId), - nextFreeAddress(0), - memorySize(memorySize), - internalOffset(internalOffset), - allocationCount(0) -{ - // Make sure to start at aligned offset, reduce size in case we need padding - if (const size_t paddingBytes = getAlignmentPadding(internalOffset)) { - assert(paddingBytes < memorySize); +LinearAllocator::LinearAllocator( + MemoryManager::AddressSpaceId memoryAddrSpaceId, size_t memorySize, + size_t internalOffset) + : BaseAllocator(memoryAddrSpaceId), nextFreeAddress(0), + memorySize(memorySize), internalOffset(internalOffset), + allocationCount(0) { + // Make sure to start at aligned offset, reduce size in case we need padding + if (const size_t paddingBytes = getAlignmentPadding(internalOffset)) { + assert(paddingBytes < memorySize); - internalOffset += paddingBytes; - memorySize -= paddingBytes; - } + internalOffset += paddingBytes; + memorySize -= paddingBytes; + } - // Deallocation callback - free = [&](MemoryBlock* mem) { - logger->debug("Deallocating memory block at local addr {:#x} (addr space {})", - mem->getOffset(), mem->getAddrSpaceId()); + // Deallocation callback + free = [&](MemoryBlock *mem) { + logger->debug( + "Deallocating memory block at local addr {:#x} (addr space {})", + mem->getOffset(), mem->getAddrSpaceId()); - removeMemoryBlock(*mem); + removeMemoryBlock(*mem); - allocationCount--; - if (allocationCount == 0) { - logger->debug("All allocations are deallocated now, freeing memory"); + allocationCount--; + if (allocationCount == 0) { + logger->debug("All allocations are deallocated now, freeing memory"); - // All allocations have been deallocated, free all memory - nextFreeAddress = 0; - } + // All allocations have been deallocated, free all memory + nextFreeAddress = 0; + } - logger->debug("Available memory: {:#x} bytes", getAvailableMemory()); - }; + logger->debug("Available memory: {:#x} bytes", getAvailableMemory()); + }; } -std::string -LinearAllocator::getName() const -{ - std::stringstream name; - name << "LinearAlloc" << getAddrSpaceId(); - if (internalOffset != 0) { - name << "@0x" << std::hex << internalOffset; - } +std::string LinearAllocator::getName() const { + std::stringstream name; + name << "LinearAlloc" << getAddrSpaceId(); + if (internalOffset != 0) { + name << "@0x" << std::hex << internalOffset; + } - return name.str(); + return name.str(); } std::unique_ptr -LinearAllocator::allocateBlock(size_t size) -{ - if (size > getAvailableMemory()) { - throw std::bad_alloc(); - } +LinearAllocator::allocateBlock(size_t size) { + if (size > getAvailableMemory()) { + throw std::bad_alloc(); + } - // Assign address - const uintptr_t localAddr = nextFreeAddress + internalOffset; + // Assign address + const uintptr_t localAddr = nextFreeAddress + internalOffset; - // Reserve memory - nextFreeAddress += size; + // Reserve memory + nextFreeAddress += size; - // Make sure it is aligned - if (const size_t paddingBytes = getAlignmentPadding(nextFreeAddress)) { - nextFreeAddress += paddingBytes; + // Make sure it is aligned + if (const size_t paddingBytes = getAlignmentPadding(nextFreeAddress)) { + nextFreeAddress += paddingBytes; - // If next free address is outside this block due to padding, cap it - nextFreeAddress = std::min(nextFreeAddress, memorySize); - } + // If next free address is outside this block due to padding, cap it + nextFreeAddress = std::min(nextFreeAddress, memorySize); + } - auto &mm = MemoryManager::get(); + auto &mm = MemoryManager::get(); - // Assemble name for this block - std::stringstream blockName; - blockName << std::showbase << std::hex << localAddr; + // Assemble name for this block + std::stringstream blockName; + blockName << std::showbase << std::hex << localAddr; - // Create address space - auto addrSpaceName = mm.getSlaveAddrSpaceName(getName(), blockName.str()); - auto addrSpaceId = mm.getOrCreateAddressSpace(addrSpaceName); + // Create address space + auto addrSpaceName = mm.getSlaveAddrSpaceName(getName(), blockName.str()); + auto addrSpaceId = mm.getOrCreateAddressSpace(addrSpaceName); - logger->debug("Allocated {:#x} bytes for {}, {:#x} bytes remaining", - size, addrSpaceId, getAvailableMemory()); + logger->debug("Allocated {:#x} bytes for {}, {:#x} bytes remaining", size, + addrSpaceId, getAvailableMemory()); - std::unique_ptr - mem(new MemoryBlock(localAddr, size, addrSpaceId), this->free); + std::unique_ptr mem( + new MemoryBlock(localAddr, size, addrSpaceId), this->free); - // Mount block into the memory graph - insertMemoryBlock(*mem); + // Mount block into the memory graph + insertMemoryBlock(*mem); - // Increase the allocation count - allocationCount++; + // Increase the allocation count + allocationCount++; - return mem; + return mem; } -HostRam::HostRamAllocator -HostRam::allocator; +HostRam::HostRamAllocator HostRam::allocator; -HostRam::HostRamAllocator::HostRamAllocator() : - BaseAllocator(MemoryManager::get().getProcessAddressSpace()) -{ - free = [&](MemoryBlock* mem) { - if (::munmap(reinterpret_cast(mem->getOffset()), mem->getSize()) != 0) { - logger->warn("munmap() failed for {:#x} of size {:#x}", - mem->getOffset(), mem->getSize()); - } +HostRam::HostRamAllocator::HostRamAllocator() + : BaseAllocator(MemoryManager::get().getProcessAddressSpace()) { + free = [&](MemoryBlock *mem) { + if (::munmap(reinterpret_cast(mem->getOffset()), mem->getSize()) != + 0) { + logger->warn("munmap() failed for {:#x} of size {:#x}", mem->getOffset(), + mem->getSize()); + } - removeMemoryBlock(*mem); - }; + removeMemoryBlock(*mem); + }; } std::map> -HostDmaRam::allocators; + HostDmaRam::allocators; -HostDmaRam::HostDmaRamAllocator::HostDmaRamAllocator(int num) : - LinearAllocator(MemoryManager::get().getOrCreateAddressSpace(getUdmaBufName(num)), getUdmaBufBufSize(num)), - num(num) -{ - auto &mm = MemoryManager::get(); - logger = logging.get(getName()); +HostDmaRam::HostDmaRamAllocator::HostDmaRamAllocator(int num) + : LinearAllocator( + MemoryManager::get().getOrCreateAddressSpace(getUdmaBufName(num)), + getUdmaBufBufSize(num)), + num(num) { + auto &mm = MemoryManager::get(); + logger = logging.get(getName()); - if (getSize() == 0) { - logger->error("Zero-sized DMA buffer not supported, is the kernel module loaded?"); - throw std::bad_alloc(); - } + if (getSize() == 0) { + logger->error( + "Zero-sized DMA buffer not supported, is the kernel module loaded?"); + throw std::bad_alloc(); + } - const uintptr_t base = getUdmaBufPhysAddr(num); + const uintptr_t base = getUdmaBufPhysAddr(num); - mm.createMapping(base, 0, getSize(), getName() + "-PCI", - mm.getPciAddressSpace(), getAddrSpaceId()); + mm.createMapping(base, 0, getSize(), getName() + "-PCI", + mm.getPciAddressSpace(), getAddrSpaceId()); - const auto bufPath = std::string("/dev/") + getUdmaBufName(num); - const int bufFd = open(bufPath.c_str(), O_RDWR | O_SYNC); - if (bufFd != -1) { - void* buf = mmap(nullptr, getSize(), PROT_READ|PROT_WRITE, MAP_SHARED, bufFd, 0); - close(bufFd); + const auto bufPath = std::string("/dev/") + getUdmaBufName(num); + const int bufFd = open(bufPath.c_str(), O_RDWR | O_SYNC); + if (bufFd != -1) { + void *buf = + mmap(nullptr, getSize(), PROT_READ | PROT_WRITE, MAP_SHARED, bufFd, 0); + close(bufFd); - if (buf != MAP_FAILED) - mm.createMapping(reinterpret_cast(buf), 0, getSize(), - getName() + "-VA", - mm.getProcessAddressSpace(), getAddrSpaceId()); - else - logger->warn("Cannot map {}", bufPath); - } - else - logger->warn("Cannot open {}", bufPath); + if (buf != MAP_FAILED) + mm.createMapping(reinterpret_cast(buf), 0, getSize(), + getName() + "-VA", mm.getProcessAddressSpace(), + getAddrSpaceId()); + else + logger->warn("Cannot map {}", bufPath); + } else + logger->warn("Cannot open {}", bufPath); - logger->info("Mapped {} of size {} bytes", bufPath, getSize()); + logger->info("Mapped {} of size {} bytes", bufPath, getSize()); } -HostDmaRam::HostDmaRamAllocator::~HostDmaRamAllocator() -{ - auto &mm = MemoryManager::get(); +HostDmaRam::HostDmaRamAllocator::~HostDmaRamAllocator() { + auto &mm = MemoryManager::get(); - void* baseVirt; - try { - auto translation = mm.getTranslationFromProcess(getAddrSpaceId()); - baseVirt = reinterpret_cast(translation.getLocalAddr(0)); - } catch (const std::out_of_range&) { - // Not mapped, nothing to do - return; - } + void *baseVirt; + try { + auto translation = mm.getTranslationFromProcess(getAddrSpaceId()); + baseVirt = reinterpret_cast(translation.getLocalAddr(0)); + } catch (const std::out_of_range &) { + // Not mapped, nothing to do + return; + } - logger->debug("Unmapping {}", getName()); + logger->debug("Unmapping {}", getName()); - // Try to unmap it - if (::munmap(baseVirt, getSize()) != 0) { - logger->warn("munmap() failed for {:p} of size {:#x}", - baseVirt, getSize()); - } + // Try to unmap it + if (::munmap(baseVirt, getSize()) != 0) { + logger->warn("munmap() failed for {:p} of size {:#x}", baseVirt, getSize()); + } } -std::string -HostDmaRam::getUdmaBufName(int num) -{ - std::stringstream name; - name << "udmabuf" << num; +std::string HostDmaRam::getUdmaBufName(int num) { + std::stringstream name; + name << "udmabuf" << num; - return name.str(); + return name.str(); } -std::string -HostDmaRam::getUdmaBufBasePath(int num) -{ - std::stringstream path; - path << "/sys/class/udmabuf/udmabuf" << num << "/"; - return path.str(); +std::string HostDmaRam::getUdmaBufBasePath(int num) { + std::stringstream path; + path << "/sys/class/udmabuf/udmabuf" << num << "/"; + return path.str(); } -size_t -HostDmaRam::getUdmaBufBufSize(int num) -{ - std::fstream s(getUdmaBufBasePath(num) + "size", s.in); - if (s.is_open()) { - std::string line; - if (std::getline(s, line)) { - return std::strtoul(line.c_str(), nullptr, 10); - } - } +size_t HostDmaRam::getUdmaBufBufSize(int num) { + std::fstream s(getUdmaBufBasePath(num) + "size", s.in); + if (s.is_open()) { + std::string line; + if (std::getline(s, line)) { + return std::strtoul(line.c_str(), nullptr, 10); + } + } - return 0; + return 0; } -uintptr_t -HostDmaRam::getUdmaBufPhysAddr(int num) -{ - std::fstream s(getUdmaBufBasePath(num) + "phys_addr", s.in); - if (s.is_open()) { - std::string line; - if (std::getline(s, line)) { - return std::strtoul(line.c_str(), nullptr, 16); - } - } +uintptr_t HostDmaRam::getUdmaBufPhysAddr(int num) { + std::fstream s(getUdmaBufBasePath(num) + "phys_addr", s.in); + if (s.is_open()) { + std::string line; + if (std::getline(s, line)) { + return std::strtoul(line.c_str(), nullptr, 16); + } + } - return UINTPTR_MAX; + return UINTPTR_MAX; } -HostDmaRam::HostDmaRamAllocator&HostDmaRam::getAllocator(int num) -{ - auto &allocator = allocators[num]; - if (not allocator) { - allocator = std::make_unique(num); - } +HostDmaRam::HostDmaRamAllocator &HostDmaRam::getAllocator(int num) { + auto &allocator = allocators[num]; + if (not allocator) { + allocator = std::make_unique(num); + } - return *allocator; + return *allocator; } } // namespace villas diff --git a/common/lib/memory_manager.cpp b/common/lib/memory_manager.cpp index 20006aeac..286c2ee50 100644 --- a/common/lib/memory_manager.cpp +++ b/common/lib/memory_manager.cpp @@ -5,241 +5,226 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include +#include +#include #include -#include #include +#include using namespace villas; using namespace villas::utils; namespace villas { -MemoryManager* -MemoryManager::instance = nullptr; +MemoryManager *MemoryManager::instance = nullptr; -MemoryManager& -MemoryManager::get() -{ - if (instance == nullptr) { - instance = new MemoryManager; - if (!instance) - throw MemoryAllocationError(); - } +MemoryManager &MemoryManager::get() { + if (instance == nullptr) { + instance = new MemoryManager; + if (!instance) + throw MemoryAllocationError(); + } - return *instance; + return *instance; } MemoryManager::AddressSpaceId -MemoryManager::getOrCreateAddressSpace(std::string name) -{ - try { - // Try fast lookup - return addrSpaceLookup.at(name); - } catch (const std::out_of_range&) { - // Does not yet exist, create - std::shared_ptr addrSpace(new AddressSpace); - addrSpace->name = name; +MemoryManager::getOrCreateAddressSpace(std::string name) { + try { + // Try fast lookup + return addrSpaceLookup.at(name); + } catch (const std::out_of_range &) { + // Does not yet exist, create + std::shared_ptr addrSpace(new AddressSpace); + addrSpace->name = name; - // Cache it for the next access - addrSpaceLookup[name] = memoryGraph.addVertex(addrSpace); + // Cache it for the next access + addrSpaceLookup[name] = memoryGraph.addVertex(addrSpace); - return addrSpaceLookup[name]; - } + return addrSpaceLookup[name]; + } } MemoryManager::MappingId MemoryManager::createMapping(uintptr_t src, uintptr_t dest, size_t size, const std::string &name, MemoryManager::AddressSpaceId fromAddrSpace, - MemoryManager::AddressSpaceId toAddrSpace) -{ - std::shared_ptr mapping(new Mapping); + MemoryManager::AddressSpaceId toAddrSpace) { + std::shared_ptr mapping(new Mapping); - mapping->name = name; - mapping->src = src; - mapping->dest = dest; - mapping->size = size; + mapping->name = name; + mapping->src = src; + mapping->dest = dest; + mapping->size = size; - return addMapping(mapping, fromAddrSpace, toAddrSpace); + return addMapping(mapping, fromAddrSpace, toAddrSpace); } MemoryManager::MappingId MemoryManager::addMapping(std::shared_ptr mapping, MemoryManager::AddressSpaceId fromAddrSpace, - MemoryManager::AddressSpaceId toAddrSpace) -{ - return memoryGraph.addEdge(mapping, fromAddrSpace, toAddrSpace); + MemoryManager::AddressSpaceId toAddrSpace) { + return memoryGraph.addEdge(mapping, fromAddrSpace, toAddrSpace); } MemoryManager::AddressSpaceId -MemoryManager::findAddressSpace(const std::string &name) -{ - return memoryGraph.findVertex( - [&](const std::shared_ptr& v) { - return v->name == name; - }); +MemoryManager::findAddressSpace(const std::string &name) { + return memoryGraph.findVertex( + [&](const std::shared_ptr &v) { return v->name == name; }); } std::list MemoryManager::findPath(const MemoryManager::AddressSpaceId &fromAddrSpaceId, - const MemoryManager::AddressSpaceId &toAddrSpaceId) -{ - std::list path; + const MemoryManager::AddressSpaceId &toAddrSpaceId) { + std::list path; - auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); - auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); + auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); + auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); - // Find a path through the memory graph - MemoryGraph::Path pathGraph; - if (not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, pathGraph, pathCheckFunc)) { + // Find a path through the memory graph + MemoryGraph::Path pathGraph; + if (not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, pathGraph, + pathCheckFunc)) { - logger->debug("No translation found from ({}) to ({})", - fromAddrSpace->toString(), toAddrSpace->toString()); + logger->debug("No translation found from ({}) to ({})", + fromAddrSpace->toString(), toAddrSpace->toString()); - throw std::out_of_range("no translation found"); - } + throw std::out_of_range("no translation found"); + } - for (auto &mappingId : pathGraph) { - auto mapping = memoryGraph.getEdge(mappingId); - path.push_back(mapping->getVertexTo()); - } + for (auto &mappingId : pathGraph) { + auto mapping = memoryGraph.getEdge(mappingId); + path.push_back(mapping->getVertexTo()); + } - return path; + return path; } -MemoryTranslation -MemoryManager::getTranslation(const MemoryManager::AddressSpaceId &fromAddrSpaceId, - const MemoryManager::AddressSpaceId &toAddrSpaceId) -{ - // Find a path through the memory graph - MemoryGraph::Path path; - if (not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, path, pathCheckFunc)) { +MemoryTranslation MemoryManager::getTranslation( + const MemoryManager::AddressSpaceId &fromAddrSpaceId, + const MemoryManager::AddressSpaceId &toAddrSpaceId) { + // Find a path through the memory graph + MemoryGraph::Path path; + if (not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, path, + pathCheckFunc)) { - auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); - auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); - logger->debug("No translation found from ({}) to ({})", - fromAddrSpace->toString(), toAddrSpace->toString()); + auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); + auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); + logger->debug("No translation found from ({}) to ({})", + fromAddrSpace->toString(), toAddrSpace->toString()); - throw std::out_of_range("no translation found"); - } + throw std::out_of_range("no translation found"); + } - // Start with an identity mapping - MemoryTranslation translation(0, 0, SIZE_MAX); + // Start with an identity mapping + MemoryTranslation translation(0, 0, SIZE_MAX); - // Iterate through path and merge all mappings into a single translation - for (auto &mappingId : path) { - auto mapping = memoryGraph.getEdge(mappingId); - translation += getTranslationFromMapping(*mapping); - } + // Iterate through path and merge all mappings into a single translation + for (auto &mappingId : path) { + auto mapping = memoryGraph.getEdge(mappingId); + translation += getTranslationFromMapping(*mapping); + } - return translation; + return translation; } -bool -MemoryManager::pathCheck(const MemoryGraph::Path &path) -{ - // Start with an identity mapping - MemoryTranslation translation(0, 0, SIZE_MAX); +bool MemoryManager::pathCheck(const MemoryGraph::Path &path) { + // Start with an identity mapping + MemoryTranslation translation(0, 0, SIZE_MAX); - // Try to add all mappings together to a common translation. If this fails - // there is a non-overlapping window. - for (auto &mappingId : path) { - auto mapping = memoryGraph.getEdge(mappingId); - try { - translation += getTranslationFromMapping(*mapping); - } catch (const InvalidTranslation&) { - return false; - } - } + // Try to add all mappings together to a common translation. If this fails + // there is a non-overlapping window. + for (auto &mappingId : path) { + auto mapping = memoryGraph.getEdge(mappingId); + try { + translation += getTranslationFromMapping(*mapping); + } catch (const InvalidTranslation &) { + return false; + } + } - return true; + return true; } uintptr_t -MemoryTranslation::getLocalAddr(uintptr_t addrInForeignAddrSpace) const -{ - assert(addrInForeignAddrSpace >= dst); - assert(addrInForeignAddrSpace < (dst + size)); - return src + addrInForeignAddrSpace - dst; +MemoryTranslation::getLocalAddr(uintptr_t addrInForeignAddrSpace) const { + assert(addrInForeignAddrSpace >= dst); + assert(addrInForeignAddrSpace < (dst + size)); + return src + addrInForeignAddrSpace - dst; } uintptr_t -MemoryTranslation::getForeignAddr(uintptr_t addrInLocalAddrSpace) const -{ - assert(addrInLocalAddrSpace >= src); - assert(addrInLocalAddrSpace < (src + size)); - return dst + addrInLocalAddrSpace - src; +MemoryTranslation::getForeignAddr(uintptr_t addrInLocalAddrSpace) const { + assert(addrInLocalAddrSpace >= src); + assert(addrInLocalAddrSpace < (src + size)); + return dst + addrInLocalAddrSpace - src; } -MemoryTranslation& -MemoryTranslation::operator+=(const MemoryTranslation &other) -{ - Logger logger = logging.get("MemoryTranslation"); +MemoryTranslation & +MemoryTranslation::operator+=(const MemoryTranslation &other) { + Logger logger = logging.get("MemoryTranslation"); - // Set level to debug to enable debug output - logger->set_level(spdlog::level::info); + // Set level to debug to enable debug output + logger->set_level(spdlog::level::info); - const uintptr_t this_dst_high = this->dst + this->size; - const uintptr_t other_src_high = other.src + other.size; + const uintptr_t this_dst_high = this->dst + this->size; + const uintptr_t other_src_high = other.src + other.size; - logger->debug("this->src: {:#x}", this->src); - logger->debug("this->dst: {:#x}", this->dst); - logger->debug("this->size: {:#x}", this->size); - logger->debug("other.src: {:#x}", other.src); - logger->debug("other.dst: {:#x}", other.dst); - logger->debug("other.size: {:#x}", other.size); - logger->debug("this_dst_high: {:#x}", this_dst_high); - logger->debug("other_src_high: {:#x}", other_src_high); + logger->debug("this->src: {:#x}", this->src); + logger->debug("this->dst: {:#x}", this->dst); + logger->debug("this->size: {:#x}", this->size); + logger->debug("other.src: {:#x}", other.src); + logger->debug("other.dst: {:#x}", other.dst); + logger->debug("other.size: {:#x}", other.size); + logger->debug("this_dst_high: {:#x}", this_dst_high); + logger->debug("other_src_high: {:#x}", other_src_high); - // Make sure there is a common memory area - assertExcept(other.src < this_dst_high, MemoryManager::InvalidTranslation()); - assertExcept(this->dst < other_src_high, MemoryManager::InvalidTranslation()); + // Make sure there is a common memory area + assertExcept(other.src < this_dst_high, MemoryManager::InvalidTranslation()); + assertExcept(this->dst < other_src_high, MemoryManager::InvalidTranslation()); - const uintptr_t hi = std::max(this_dst_high, other_src_high); - const uintptr_t lo = std::min(this->dst, other.src); + const uintptr_t hi = std::max(this_dst_high, other_src_high); + const uintptr_t lo = std::min(this->dst, other.src); - const uintptr_t diff_hi = (this_dst_high > other_src_high) - ? (this_dst_high - other_src_high) - : (other_src_high - this_dst_high); + const uintptr_t diff_hi = (this_dst_high > other_src_high) + ? (this_dst_high - other_src_high) + : (other_src_high - this_dst_high); - const bool otherSrcIsSmaller = this->dst > other.src; - const uintptr_t diff_lo = (otherSrcIsSmaller) - ? (this->dst - other.src) - : (other.src - this->dst); + const bool otherSrcIsSmaller = this->dst > other.src; + const uintptr_t diff_lo = + (otherSrcIsSmaller) ? (this->dst - other.src) : (other.src - this->dst); - logger->debug("hi: {:#x}", hi); - logger->debug("lo: {:#x}", lo); - logger->debug("diff_hi: {:#x}", diff_hi); - logger->debug("diff_lo: {:#x}", diff_lo); + logger->debug("hi: {:#x}", hi); + logger->debug("lo: {:#x}", lo); + logger->debug("diff_hi: {:#x}", diff_hi); + logger->debug("diff_lo: {:#x}", diff_lo); - // New size of aperture, can only stay or shrink - this->size = (hi - lo) - diff_hi - diff_lo; + // New size of aperture, can only stay or shrink + this->size = (hi - lo) - diff_hi - diff_lo; - // New translation will come out other's destination (by default) - this->dst = other.dst; + // New translation will come out other's destination (by default) + this->dst = other.dst; - // The source stays the same and can only increase with merged translations - //this->src = this->src; + // The source stays the same and can only increase with merged translations + //this->src = this->src; - if (otherSrcIsSmaller) - // Other mapping starts at lower addresses, so we actually arrive at - // higher addresses - this->dst += diff_lo; - else - // Other mapping starts at higher addresses than this, so we have to - // increase the start - // NOTE: for addresses equality, this just adds 0 - this->src += diff_lo; + if (otherSrcIsSmaller) + // Other mapping starts at lower addresses, so we actually arrive at + // higher addresses + this->dst += diff_lo; + else + // Other mapping starts at higher addresses than this, so we have to + // increase the start + // NOTE: for addresses equality, this just adds 0 + this->src += diff_lo; - logger->debug("result src: {:#x}", this->src); - logger->debug("result dst: {:#x}", this->dst); - logger->debug("result size: {:#x}", this->size); + logger->debug("result src: {:#x}", this->src); + logger->debug("result dst: {:#x}", this->dst); + logger->debug("result size: {:#x}", this->size); - return *this; + return *this; } } // namespace villas diff --git a/common/lib/plugin.cpp b/common/lib/plugin.cpp index 4c35042cd..ee8c84aa0 100644 --- a/common/lib/plugin.cpp +++ b/common/lib/plugin.cpp @@ -5,33 +5,28 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include #include +#include +#include +#include +#include #include using namespace villas::plugin; -Registry * villas::plugin::registry = nullptr; +Registry *villas::plugin::registry = nullptr; -Plugin::Plugin() -{ - if (registry == nullptr) - registry = new Registry(); +Plugin::Plugin() { + if (registry == nullptr) + registry = new Registry(); - registry->add(this); + registry->add(this); } -Plugin::~Plugin() -{ - registry->remove(this); -} +Plugin::~Plugin() { registry->remove(this); } -void -Plugin::dump() -{ - getLogger()->info("Name: '{}' Description: '{}'", getName(), getDescription()); +void Plugin::dump() { + getLogger()->info("Name: '{}' Description: '{}'", getName(), + getDescription()); } diff --git a/common/lib/popen.cpp b/common/lib/popen.cpp index 82ced080b..b205b3dcb 100644 --- a/common/lib/popen.cpp +++ b/common/lib/popen.cpp @@ -5,203 +5,179 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include -#include #include #include #include +#include #include #include -#include #include #include +#include namespace villas { namespace utils { -Popen::Popen(const std::string &cmd, - const arg_list &args, - const env_map &env, - const std::string &wd, - bool sh) : - command(cmd), - working_dir(wd), - arguments(args), - environment(env), - shell(sh) -{ - open(); +Popen::Popen(const std::string &cmd, const arg_list &args, const env_map &env, + const std::string &wd, bool sh) + : command(cmd), working_dir(wd), arguments(args), environment(env), + shell(sh) { + open(); } -Popen::~Popen() -{ - close(); -} +Popen::~Popen() { close(); } -void Popen::kill(int signal) -{ - ::kill(pid, signal); -} +void Popen::kill(int signal) { ::kill(pid, signal); } -void Popen::open() -{ - std::vector argv, envp; +void Popen::open() { + std::vector argv, envp; - const int READ = 0; - const int WRITE = 1; + const int READ = 0; + const int WRITE = 1; - int ret; - int inpipe[2]; - int outpipe[2]; + int ret; + int inpipe[2]; + int outpipe[2]; - ret = pipe(inpipe); - if (ret) - goto error_out; + ret = pipe(inpipe); + if (ret) + goto error_out; - ret = pipe(outpipe); - if (ret) - goto clean_inpipe_out; + ret = pipe(outpipe); + if (ret) + goto clean_inpipe_out; - fd_in = outpipe[READ]; - fd_out = inpipe[WRITE]; + fd_in = outpipe[READ]; + fd_out = inpipe[WRITE]; - pid = fork(); - if (pid == -1) - goto clean_outpipe_out; + pid = fork(); + if (pid == -1) + goto clean_outpipe_out; - if (pid == 0) { - // Prepare arguments - if (shell) { - argv.push_back((char *) "sh"); - argv.push_back((char *) "-c"); - argv.push_back((char *) command.c_str()); - } - else { - for (auto arg: arguments) { - auto s = strdup(arg.c_str()); + if (pid == 0) { + // Prepare arguments + if (shell) { + argv.push_back((char *)"sh"); + argv.push_back((char *)"-c"); + argv.push_back((char *)command.c_str()); + } else { + for (auto arg : arguments) { + auto s = strdup(arg.c_str()); - argv.push_back(s); - } - } + argv.push_back(s); + } + } - // Prepare environment - for (char **p = environ; *p; p++) - envp.push_back(*p); + // Prepare environment + for (char **p = environ; *p; p++) + envp.push_back(*p); - for (auto env: environment) { - auto e = fmt::format("{}={}", env.first, env.second); - auto s = strdup(e.c_str()); + for (auto env : environment) { + auto e = fmt::format("{}={}", env.first, env.second); + auto s = strdup(e.c_str()); - envp.push_back(s); - } + envp.push_back(s); + } - argv.push_back(nullptr); - envp.push_back(nullptr); + argv.push_back(nullptr); + envp.push_back(nullptr); - // Redirect IO - ::close(outpipe[READ]); - ::close(inpipe[WRITE]); + // Redirect IO + ::close(outpipe[READ]); + ::close(inpipe[WRITE]); - if (inpipe[READ] != STDIN_FILENO) { - dup2(inpipe[READ], STDIN_FILENO); - ::close(inpipe[READ]); - } + if (inpipe[READ] != STDIN_FILENO) { + dup2(inpipe[READ], STDIN_FILENO); + ::close(inpipe[READ]); + } - if (outpipe[WRITE] != STDOUT_FILENO) { - dup2(outpipe[WRITE], STDOUT_FILENO); - ::close(outpipe[WRITE]); - } + if (outpipe[WRITE] != STDOUT_FILENO) { + dup2(outpipe[WRITE], STDOUT_FILENO); + ::close(outpipe[WRITE]); + } - // Change working directory - if (!working_dir.empty()) { - int ret; + // Change working directory + if (!working_dir.empty()) { + int ret; - ret = chdir(working_dir.c_str()); - if (ret) - exit(127); - } + ret = chdir(working_dir.c_str()); + if (ret) + exit(127); + } - execvpe(shell ? _PATH_BSHELL : command.c_str(), (char * const *) argv.data(), (char * const *) envp.data()); - exit(127); - } + execvpe(shell ? _PATH_BSHELL : command.c_str(), (char *const *)argv.data(), + (char *const *)envp.data()); + exit(127); + } - ::close(outpipe[WRITE]); - ::close(inpipe[READ]); + ::close(outpipe[WRITE]); + ::close(inpipe[READ]); - return; + return; clean_outpipe_out: - ::close(outpipe[READ]); - ::close(outpipe[WRITE]); + ::close(outpipe[READ]); + ::close(outpipe[WRITE]); clean_inpipe_out: - ::close(inpipe[READ]); - ::close(inpipe[WRITE]); + ::close(inpipe[READ]); + ::close(inpipe[WRITE]); error_out: - throw SystemError("Failed to start subprocess"); + throw SystemError("Failed to start subprocess"); } -int Popen::close() -{ - int pstat; +int Popen::close() { + int pstat; - if (pid != -1) { - do { - pid = waitpid(pid, &pstat, 0); - } while (pid == -1 && errno == EINTR); - } + if (pid != -1) { + do { + pid = waitpid(pid, &pstat, 0); + } while (pid == -1 && errno == EINTR); + } - return pid == -1 ? -1 : pstat; + return pid == -1 ? -1 : pstat; } -PopenStream::PopenStream(const std::string &cmd, - const arg_list &args, - const env_map &env, - const std::string &wd, - bool sh) : - Popen(cmd, args, env, wd, sh) -{ - open(); +PopenStream::PopenStream(const std::string &cmd, const arg_list &args, + const env_map &env, const std::string &wd, bool sh) + : Popen(cmd, args, env, wd, sh) { + open(); } -PopenStream::~PopenStream() -{ - close(); +PopenStream::~PopenStream() { close(); } + +void PopenStream::open() { + Popen::open(); + + input.buffer = std::make_unique(fd_in, std::ios_base::in); + output.buffer = std::make_unique(fd_out, std::ios_base::out); + + input.stream = std::make_unique(input.buffer.get()); + output.stream = std::make_unique(output.buffer.get()); } -void PopenStream::open() -{ - Popen::open(); +int PopenStream::close() { + int ret = Popen::close(); - input.buffer = std::make_unique(fd_in, std::ios_base::in); - output.buffer = std::make_unique(fd_out, std::ios_base::out); + input.stream.reset(); + output.stream.reset(); - input.stream = std::make_unique(input.buffer.get()); - output.stream = std::make_unique(output.buffer.get()); -} + input.buffer.reset(); + output.buffer.reset(); -int PopenStream::close() -{ - int ret = Popen::close(); - - input.stream.reset(); - output.stream.reset(); - - input.buffer.reset(); - output.buffer.reset(); - - return ret; + return ret; } } // namespace utils diff --git a/common/lib/table.cpp b/common/lib/table.cpp index cb3b9ca57..dd4d6dcac 100644 --- a/common/lib/table.cpp +++ b/common/lib/table.cpp @@ -8,138 +8,135 @@ #include #include -#include -#include -#include -#include #include +#include +#include #include +#include +#include using namespace villas; using namespace villas::utils; #if !defined(LOG_COLOR_DISABLE) - #define ANSI_RESET "\e[0m" +#define ANSI_RESET "\e[0m" #else - #define ANSI_RESET +#define ANSI_RESET #endif -int Table::resize(int w) -{ - int norm, flex, fixed, total; +int Table::resize(int w) { + int norm, flex, fixed, total; - width = w; + width = w; - norm = 0; - flex = 0; - fixed = 0; - total = width - columns.size() * 2; + norm = 0; + flex = 0; + fixed = 0; + total = width - columns.size() * 2; - // Normalize width - for (unsigned i = 0; i < columns.size(); i++) { - if (columns[i].width > 0) - norm += columns[i].width; - if (columns[i].width == 0) - flex++; - if (columns[i].width < 0) - fixed += -1 * columns[i].width; - } + // Normalize width + for (unsigned i = 0; i < columns.size(); i++) { + if (columns[i].width > 0) + norm += columns[i].width; + if (columns[i].width == 0) + flex++; + if (columns[i].width < 0) + fixed += -1 * columns[i].width; + } - for (unsigned i = 0; i < columns.size(); i++) { - if (columns[i].width > 0) - columns[i]._width = columns[i].width * (float) (total - fixed) / norm; - if (columns[i].width == 0) - columns[i]._width = (float) (total - fixed) / flex; - if (columns[i].width < 0) - columns[i]._width = -1 * columns[i].width; - } + for (unsigned i = 0; i < columns.size(); i++) { + if (columns[i].width > 0) + columns[i]._width = columns[i].width * (float)(total - fixed) / norm; + if (columns[i].width == 0) + columns[i]._width = (float)(total - fixed) / flex; + if (columns[i].width < 0) + columns[i]._width = -1 * columns[i].width; + } - return 0; + return 0; } -void Table::header() -{ - if (width != logging.getWidth()) - resize(logging.getWidth()); +void Table::header() { + if (width != logging.getWidth()) + resize(logging.getWidth()); - char *line1 = nullptr; - char *line2 = nullptr; - char *line3 = nullptr; + char *line1 = nullptr; + char *line2 = nullptr; + char *line3 = nullptr; - for (unsigned i = 0; i < columns.size(); i++) { - int w, u; - char *col, *unit; + for (unsigned i = 0; i < columns.size(); i++) { + int w, u; + char *col, *unit; - col = strf(CLR_BLD("%s"), columns[i].title.c_str()); - unit = columns[i].unit.size() ? strf(CLR_YEL("%s"), columns[i].unit.c_str()) : strf(""); + col = strf(CLR_BLD("%s"), columns[i].title.c_str()); + unit = columns[i].unit.size() ? strf(CLR_YEL("%s"), columns[i].unit.c_str()) + : strf(""); - w = columns[i]._width + strlen(col) - strlenp(col); - u = columns[i]._width + strlen(unit) - strlenp(unit); + w = columns[i]._width + strlen(col) - strlenp(col); + u = columns[i]._width + strlen(unit) - strlenp(unit); - if (columns[i].align == TableColumn::Alignment::LEFT) { - strcatf(&line1, " %-*.*s" ANSI_RESET, w, w, col); - strcatf(&line2, " %-*.*s" ANSI_RESET, u, u, unit); - } - else { - strcatf(&line1, " %*.*s" ANSI_RESET, w, w, col); - strcatf(&line2, " %*.*s" ANSI_RESET, u, u, unit); - } + if (columns[i].align == TableColumn::Alignment::LEFT) { + strcatf(&line1, " %-*.*s" ANSI_RESET, w, w, col); + strcatf(&line2, " %-*.*s" ANSI_RESET, u, u, unit); + } else { + strcatf(&line1, " %*.*s" ANSI_RESET, w, w, col); + strcatf(&line2, " %*.*s" ANSI_RESET, u, u, unit); + } - for (int j = 0; j < columns[i]._width + 2; j++) { - strcatf(&line3, "%s", BOX_LR); - } + for (int j = 0; j < columns[i]._width + 2; j++) { + strcatf(&line3, "%s", BOX_LR); + } - if (i != columns.size() - 1) { - strcatf(&line1, " %s", BOX_UD); - strcatf(&line2, " %s", BOX_UD); - strcatf(&line3, "%s", BOX_UDLR); - } + if (i != columns.size() - 1) { + strcatf(&line1, " %s", BOX_UD); + strcatf(&line2, " %s", BOX_UD); + strcatf(&line3, "%s", BOX_UDLR); + } - free(col); - free(unit); - } + free(col); + free(unit); + } - logger->info("{}", line1); - logger->info("{}", line2); - logger->info("{}", line3); + logger->info("{}", line1); + logger->info("{}", line2); + logger->info("{}", line3); - free(line1); - free(line2); - free(line3); + free(line1); + free(line2); + free(line3); } -void Table::row(int count, ...) -{ - if (width != logging.getWidth()) { - resize(logging.getWidth()); - header(); - } +void Table::row(int count, ...) { + if (width != logging.getWidth()) { + resize(logging.getWidth()); + header(); + } - va_list args; - va_start(args, count); + va_list args; + va_start(args, count); - char *line = nullptr; + char *line = nullptr; - for (unsigned i = 0; i < columns.size(); ++i) { - char *col = vstrf(columns[i].format.c_str(), args); + for (unsigned i = 0; i < columns.size(); ++i) { + char *col = vstrf(columns[i].format.c_str(), args); - int l = strlenp(col); - int r = strlen(col); - int w = columns[i]._width + r - l; + int l = strlenp(col); + int r = strlen(col); + int w = columns[i]._width + r - l; - if (columns[i].align == TableColumn::Alignment::LEFT) - strcatf(&line, " %-*.*s " ANSI_RESET, w, w, col); - else - strcatf(&line, " %*.*s " ANSI_RESET, w, w, col); + if (columns[i].align == TableColumn::Alignment::LEFT) + strcatf(&line, " %-*.*s " ANSI_RESET, w, w, col); + else + strcatf(&line, " %*.*s " ANSI_RESET, w, w, col); - if (i != columns.size() - 1) - strcatf(&line, BOX_UD); + if (i != columns.size() - 1) + strcatf(&line, BOX_UD); - free(col); - } + free(col); + } - va_end(args); + va_end(args); - logger->info("{}", line); - free(line); + logger->info("{}", line); + free(line); } diff --git a/common/lib/task.cpp b/common/lib/task.cpp index 100b086e5..ebdfc8e28 100644 --- a/common/lib/task.cpp +++ b/common/lib/task.cpp @@ -5,183 +5,167 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include +#include +#include -#include +#include #include #include -#include +#include using namespace villas; #if PERIODIC_TASK_IMPL == TIMERFD - #include +#include #endif // PERIODIC_TASK_IMPL -Task::Task(int clk) : - clock(clk) -{ +Task::Task(int clk) : clock(clk) { #if PERIODIC_TASK_IMPL == TIMERFD - fd = timerfd_create(clock, 0); - if (fd < 0) - throw SystemError("Failed to create timerfd"); + fd = timerfd_create(clock, 0); + if (fd < 0) + throw SystemError("Failed to create timerfd"); #elif PERIODIC_TASK_IMPL == RDTSC - int ret = tsc_init(&tsc); - if (ret) - return ret; + int ret = tsc_init(&tsc); + if (ret) + return ret; #endif // PERIODIC_TASK_IMPL } -void Task::setTimeout(double to) -{ - struct timespec now; +void Task::setTimeout(double to) { + struct timespec now; - clock_gettime(clock, &now); + clock_gettime(clock, &now); - struct timespec timeout = time_from_double(to); - struct timespec next = time_add(&now, &timeout); + struct timespec timeout = time_from_double(to); + struct timespec next = time_add(&now, &timeout); - setNext(&next); + setNext(&next); } -void Task::setNext(const struct timespec *nxt) -{ +void Task::setNext(const struct timespec *nxt) { #if PERIODIC_TASK_IMPL != RDTSC - next = *nxt; + next = *nxt; - #if PERIODIC_TASK_IMPL == TIMERFD - int ret; - struct itimerspec its = { - .it_interval = (struct timespec) { 0, 0 }, - .it_value = next - }; +#if PERIODIC_TASK_IMPL == TIMERFD + int ret; + struct itimerspec its = {.it_interval = (struct timespec){0, 0}, + .it_value = next}; - ret = timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, nullptr); - if (ret) - throw SystemError("Failed to set timerfd"); - #endif // PERIODIC_TASK_IMPL == TIMERFD + ret = timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, nullptr); + if (ret) + throw SystemError("Failed to set timerfd"); +#endif // PERIODIC_TASK_IMPL == TIMERFD #endif // PERIODIC_TASK_IMPL != RDTSC } -void Task::setRate(double rate) -{ +void Task::setRate(double rate) { #if PERIODIC_TASK_IMPL == RDTSC - period = tsc_rate_to_cycles(&tsc, rate); - next = tsc_now(&tsc) + period; + period = tsc_rate_to_cycles(&tsc, rate); + next = tsc_now(&tsc) + period; #else - // A rate of 0 will disarm the timer - period = rate ? time_from_double(1.0 / rate) : (struct timespec) { 0, 0 }; + // A rate of 0 will disarm the timer + period = rate ? time_from_double(1.0 / rate) : (struct timespec){0, 0}; - #if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP - struct timespec now, next; +#if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP + struct timespec now, next; - clock_gettime(clock, &now); + clock_gettime(clock, &now); - next = time_add(&now, &period); + next = time_add(&now, &period); - return setNext(&next); - #elif PERIODIC_TASK_IMPL == TIMERFD - int ret; - struct itimerspec its = { - .it_interval = period, - .it_value = period - }; + return setNext(&next); +#elif PERIODIC_TASK_IMPL == TIMERFD + int ret; + struct itimerspec its = {.it_interval = period, .it_value = period}; - ret = timerfd_settime(fd, 0, &its, nullptr); - if (ret) - throw SystemError("Failed to set timerfd"); - #endif // PERIODIC_TASK_IMPL + ret = timerfd_settime(fd, 0, &its, nullptr); + if (ret) + throw SystemError("Failed to set timerfd"); +#endif // PERIODIC_TASK_IMPL #endif // PERIODIC_TASK_IMPL == RDTSC } -Task::~Task() -{ +Task::~Task() { #if PERIODIC_TASK_IMPL == TIMERFD - close(fd); + close(fd); #endif } -uint64_t Task::wait() -{ - uint64_t runs; +uint64_t Task::wait() { + uint64_t runs; #if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP - int ret; - struct timespec now; + int ret; + struct timespec now; - ret = clock_gettime(clock, &now); - if (ret) - return ret; + ret = clock_gettime(clock, &now); + if (ret) + return ret; - for (runs = 0; time_cmp(&next, &now) < 0; runs++) - next = time_add(&next, &period); + for (runs = 0; time_cmp(&next, &now) < 0; runs++) + next = time_add(&next, &period); - #if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP - do { - ret = clock_nanosleep(clock, TIMER_ABSTIME, &next, nullptr); - } while (ret == EINTR); - #elif PERIODIC_TASK_IMPL == NANOSLEEP - struct timespec req, rem = time_diff(&now, &next); +#if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP + do { + ret = clock_nanosleep(clock, TIMER_ABSTIME, &next, nullptr); + } while (ret == EINTR); +#elif PERIODIC_TASK_IMPL == NANOSLEEP + struct timespec req, rem = time_diff(&now, &next); - do { - req = rem; - ret = nanosleep(&req, &rem); - } while (ret < 0 && errno == EINTR); - #endif - if (ret) - return 0; + do { + req = rem; + ret = nanosleep(&req, &rem); + } while (ret < 0 && errno == EINTR); +#endif + if (ret) + return 0; - ret = clock_gettime(clock, &now); - if (ret) - return ret; + ret = clock_gettime(clock, &now); + if (ret) + return ret; - for (; time_cmp(&next, &now) < 0; runs++) - next = time_add(&next, &period); + for (; time_cmp(&next, &now) < 0; runs++) + next = time_add(&next, &period); #elif PERIODIC_TASK_IMPL == TIMERFD - int ret; + int ret; - ret = read(fd, &runs, sizeof(runs)); - if (ret < 0) - return 0; + ret = read(fd, &runs, sizeof(runs)); + if (ret < 0) + return 0; #elif PERIODIC_TASK_IMPL == RDTSC - uint64_t now; + uint64_t now; - do { - now = tsc_now(&tsc); - } while (now < next); + do { + now = tsc_now(&tsc); + } while (now < next); - for (runs = 0; next < now; runs++) - next += period; + for (runs = 0; next < now; runs++) + next += period; #else - #error "Invalid period task implementation" +#error "Invalid period task implementation" #endif - return runs; + return runs; } -void Task::stop() -{ +void Task::stop() { #if PERIODIC_TASK_IMPL == TIMERFD - int ret; - struct itimerspec its = { - .it_interval = (struct timespec) { 0, 0 }, - .it_value = (struct timespec) { 0, 0 } - }; + int ret; + struct itimerspec its = {.it_interval = (struct timespec){0, 0}, + .it_value = (struct timespec){0, 0}}; - ret = timerfd_settime(fd, 0, &its, nullptr); - if (ret) - throw SystemError("Failed to disarm timerfd"); + ret = timerfd_settime(fd, 0, &its, nullptr); + if (ret) + throw SystemError("Failed to disarm timerfd"); #endif // PERIODIC_TASK_IMPL == TIMERFD } -int Task::getFD() const -{ +int Task::getFD() const { #if PERIODIC_TASK_IMPL == TIMERFD - return fd; + return fd; #else - return -1; + return -1; #endif } diff --git a/common/lib/terminal.cpp b/common/lib/terminal.cpp index b812c4ee0..4ab4ce244 100644 --- a/common/lib/terminal.cpp +++ b/common/lib/terminal.cpp @@ -7,64 +7,64 @@ #include -#include #include #include +#include using namespace villas; -class Terminal * Terminal::current = nullptr; +class Terminal *Terminal::current = nullptr; -Terminal::Terminal() -{ - int ret; +Terminal::Terminal() { + int ret; - window.ws_row = 0; - window.ws_col = 0; + window.ws_row = 0; + window.ws_col = 0; - isTty = isatty(STDERR_FILENO); + isTty = isatty(STDERR_FILENO); - Logger logger = logging.get("terminal"); + Logger logger = logging.get("terminal"); - if (isTty) { - struct sigaction sa_resize; - sa_resize.sa_flags = SA_SIGINFO; - sa_resize.sa_sigaction = resize; + if (isTty) { + struct sigaction sa_resize; + sa_resize.sa_flags = SA_SIGINFO; + sa_resize.sa_sigaction = resize; - sigemptyset(&sa_resize.sa_mask); + sigemptyset(&sa_resize.sa_mask); - ret = sigaction(SIGWINCH, &sa_resize, nullptr); - if (ret) - throw SystemError("Failed to register signal handler"); + ret = sigaction(SIGWINCH, &sa_resize, nullptr); + if (ret) + throw SystemError("Failed to register signal handler"); - // Try to get initial terminal dimensions - ret = ioctl(STDERR_FILENO, TIOCGWINSZ, &window); - if (ret) - logger->warn("Failed to get terminal dimensions"); - } else { - logger->info("stderr is not associated with a terminal! Using fallback values for window size..."); - } + // Try to get initial terminal dimensions + ret = ioctl(STDERR_FILENO, TIOCGWINSZ, &window); + if (ret) + logger->warn("Failed to get terminal dimensions"); + } else { + logger->info("stderr is not associated with a terminal! Using fallback " + "values for window size..."); + } - // Fallback if for some reason we can not determine a prober window size - if (window.ws_col == 0) - window.ws_col = 150; + // Fallback if for some reason we can not determine a prober window size + if (window.ws_col == 0) + window.ws_col = 150; - if (window.ws_row == 0) - window.ws_row = 50; + if (window.ws_row == 0) + window.ws_row = 50; } -void Terminal::resize(int, siginfo_t *, void *) -{ - if (!current) - current = new Terminal(); +void Terminal::resize(int, siginfo_t *, void *) { + if (!current) + current = new Terminal(); - Logger logger = logging.get("terminal"); + Logger logger = logging.get("terminal"); - int ret; + int ret; - ret = ioctl(STDERR_FILENO, TIOCGWINSZ, ¤t->window); - if (ret) - throw SystemError("Failed to get terminal dimensions"); + ret = ioctl(STDERR_FILENO, TIOCGWINSZ, ¤t->window); + if (ret) + throw SystemError("Failed to get terminal dimensions"); - logger->debug("New terminal size: {}x{}", current->window.ws_row, current->window.ws_col); + logger->debug("New terminal size: {}x{}", current->window.ws_row, + current->window.ws_col); }; diff --git a/common/lib/timing.cpp b/common/lib/timing.cpp index 2a627e1c9..acbc7e1ea 100644 --- a/common/lib/timing.cpp +++ b/common/lib/timing.cpp @@ -9,71 +9,62 @@ #include -struct timespec time_now() -{ - struct timespec ts; +struct timespec time_now() { + struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); + clock_gettime(CLOCK_REALTIME, &ts); - return ts; + return ts; } -struct timespec time_add(const struct timespec *start, const struct timespec *end) -{ - struct timespec sum = { - .tv_sec = end->tv_sec + start->tv_sec, - .tv_nsec = end->tv_nsec + start->tv_nsec - }; +struct timespec time_add(const struct timespec *start, + const struct timespec *end) { + struct timespec sum = {.tv_sec = end->tv_sec + start->tv_sec, + .tv_nsec = end->tv_nsec + start->tv_nsec}; - if (sum.tv_nsec >= 1000000000) { - sum.tv_sec += 1; - sum.tv_nsec -= 1000000000; - } + if (sum.tv_nsec >= 1000000000) { + sum.tv_sec += 1; + sum.tv_nsec -= 1000000000; + } - return sum; + return sum; } -struct timespec time_diff(const struct timespec *start, const struct timespec *end) -{ - struct timespec diff = { - .tv_sec = end->tv_sec - start->tv_sec, - .tv_nsec = end->tv_nsec - start->tv_nsec - }; +struct timespec time_diff(const struct timespec *start, + const struct timespec *end) { + struct timespec diff = {.tv_sec = end->tv_sec - start->tv_sec, + .tv_nsec = end->tv_nsec - start->tv_nsec}; - if (diff.tv_nsec < 0) { - diff.tv_sec -= 1; - diff.tv_nsec += 1000000000; - } + if (diff.tv_nsec < 0) { + diff.tv_sec -= 1; + diff.tv_nsec += 1000000000; + } - return diff; + return diff; } -struct timespec time_from_double(double secs) -{ - struct timespec ts; +struct timespec time_from_double(double secs) { + struct timespec ts; - ts.tv_sec = secs; - ts.tv_nsec = 1.0e9 * (secs - ts.tv_sec); + ts.tv_sec = secs; + ts.tv_nsec = 1.0e9 * (secs - ts.tv_sec); - return ts; + return ts; } -double time_to_double(const struct timespec *ts) -{ - return ts->tv_sec + ts->tv_nsec * 1e-9; +double time_to_double(const struct timespec *ts) { + return ts->tv_sec + ts->tv_nsec * 1e-9; } -double time_delta(const struct timespec *start, const struct timespec *end) -{ - struct timespec diff = time_diff(start, end); +double time_delta(const struct timespec *start, const struct timespec *end) { + struct timespec diff = time_diff(start, end); - return time_to_double(&diff); + return time_to_double(&diff); } -ssize_t time_cmp(const struct timespec *a, const struct timespec *b) -{ - ssize_t sd = a->tv_sec - b->tv_sec; - ssize_t nsd = a->tv_nsec - b->tv_nsec; +ssize_t time_cmp(const struct timespec *a, const struct timespec *b) { + ssize_t sd = a->tv_sec - b->tv_sec; + ssize_t nsd = a->tv_nsec - b->tv_nsec; - return sd != 0 ? sd : nsd; + return sd != 0 ? sd : nsd; } diff --git a/common/lib/tool.cpp b/common/lib/tool.cpp index baa72f4a4..adb21e553 100644 --- a/common/lib/tool.cpp +++ b/common/lib/tool.cpp @@ -11,63 +11,57 @@ using namespace villas; -void Tool::staticHandler(int signal, siginfo_t *sinfo, void *ctx) -{ - if (current_tool) - current_tool->handler(signal, sinfo, ctx); +void Tool::staticHandler(int signal, siginfo_t *sinfo, void *ctx) { + if (current_tool) + current_tool->handler(signal, sinfo, ctx); } -void Tool::printCopyright() -{ - std::cout << PROJECT_NAME " " << CLR_BLU(PROJECT_BUILD_ID) - << " (built on " CLR_MAG(__DATE__) " " CLR_MAG(__TIME__) ")" << std::endl - << " Copyright 2014-2021, Institute for Automation of Complex Power Systems, RWTH Aachen University" << std::endl - << " Steffen Vogel " << std::endl; +void Tool::printCopyright() { + std::cout << PROJECT_NAME " " << CLR_BLU(PROJECT_BUILD_ID) + << " (built on " CLR_MAG(__DATE__) " " CLR_MAG(__TIME__) ")" + << std::endl + << " Copyright 2014-2021, Institute for Automation of Complex " + "Power Systems, RWTH Aachen University" + << std::endl + << " Steffen Vogel " << std::endl; } -void Tool::printVersion() -{ - std::cout << PROJECT_BUILD_ID << std::endl; +void Tool::printVersion() { std::cout << PROJECT_BUILD_ID << std::endl; } + +Tool::Tool(int ac, char *av[], const std::string &nme, + const std::list &sigs) + : argc(ac), argv(av), name(nme), handlerSignals(sigs) { + current_tool = this; + + logger = logging.get(name); } -Tool::Tool(int ac, char *av[], const std::string &nme, const std::list &sigs) : - argc(ac), - argv(av), - name(nme), - handlerSignals(sigs) -{ - current_tool = this; +int Tool::run() { + try { + int ret; - logger = logging.get(name); -} + logger->info("This is VILLASnode {} (built on {}, {})", + CLR_BLD(CLR_YEL(PROJECT_BUILD_ID)), CLR_BLD(CLR_MAG(__DATE__)), + CLR_BLD(CLR_MAG(__TIME__))); -int Tool::run() -{ - try { - int ret; + ret = utils::signalsInit(staticHandler, handlerSignals); + if (ret) + throw RuntimeError("Failed to initialize signal subsystem"); - logger->info("This is VILLASnode {} (built on {}, {})", - CLR_BLD(CLR_YEL(PROJECT_BUILD_ID)), - CLR_BLD(CLR_MAG(__DATE__)), CLR_BLD(CLR_MAG(__TIME__))); + // Parse command line arguments + parse(); - ret = utils::signalsInit(staticHandler, handlerSignals); - if (ret) - throw RuntimeError("Failed to initialize signal subsystem"); + // Run tool + ret = main(); - // Parse command line arguments - parse(); + logger->info(CLR_GRN("Goodbye!")); - // Run tool - ret = main(); + return ret; + } catch (const std::runtime_error &e) { + logger->error("{}", e.what()); - logger->info(CLR_GRN("Goodbye!")); - - return ret; - } catch (const std::runtime_error &e) { - logger->error("{}", e.what()); - - return -1; - } + return -1; + } } Tool *Tool::current_tool = nullptr; diff --git a/common/lib/tsc.cpp b/common/lib/tsc.cpp index 0cf16a5a6..c132caeff 100644 --- a/common/lib/tsc.cpp +++ b/common/lib/tsc.cpp @@ -9,42 +9,40 @@ using namespace villas; -int tsc_init(struct Tsc *t) -{ - uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; +int tsc_init(struct Tsc *t) { + uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; - // Check if TSC is supported - __get_cpuid(0x1, &eax, &ebx, &ecx, &edx); - if (!(edx & bit_TSC)) - return -2; + // Check if TSC is supported + __get_cpuid(0x1, &eax, &ebx, &ecx, &edx); + if (!(edx & bit_TSC)) + return -2; - // Check if RDTSCP instruction is supported - __get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx); - t->rdtscp_supported = edx & bit_RDTSCP; + // Check if RDTSCP instruction is supported + __get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + t->rdtscp_supported = edx & bit_RDTSCP; - // Check if TSC is invariant - __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); - t->is_invariant = edx & bit_TSC_INVARIANT; + // Check if TSC is invariant + __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + t->is_invariant = edx & bit_TSC_INVARIANT; - // Intel SDM Vol 3, Section 18.7.3: - // Nominal TSC frequency = CPUID.15H.ECX[31:0] * CPUID.15H.EBX[31:0] ) ÷ CPUID.15H.EAX[31:0] - __get_cpuid(0x15, &eax, &ebx, &ecx, &edx); + // Intel SDM Vol 3, Section 18.7.3: + // Nominal TSC frequency = CPUID.15H.ECX[31:0] * CPUID.15H.EBX[31:0] ) ÷ CPUID.15H.EAX[31:0] + __get_cpuid(0x15, &eax, &ebx, &ecx, &edx); - if (ecx != 0) - t->frequency = ecx * ebx / eax; - else { - int ret; + if (ecx != 0) + t->frequency = ecx * ebx / eax; + else { + int ret; #ifdef __linux__ - ret = kernel::get_cpu_frequency(&t->frequency); - if (ret) - return ret; + ret = kernel::get_cpu_frequency(&t->frequency); + if (ret) + return ret; #endif - } + } - return 0; + return 0; } -uint64_t tsc_rate_to_cycles(struct Tsc *t, double rate) -{ - return t->frequency / rate; +uint64_t tsc_rate_to_cycles(struct Tsc *t, double rate) { + return t->frequency / rate; } diff --git a/common/lib/utils.cpp b/common/lib/utils.cpp index f755dc07c..87e148f8c 100644 --- a/common/lib/utils.cpp +++ b/common/lib/utils.cpp @@ -6,374 +6,349 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include -#include -#include -#include #include +#include #include #include +#include -static -pthread_t main_thread; +static pthread_t main_thread; namespace villas { namespace utils { -std::vector tokenize(std::string s, const std::string &delimiter) -{ - std::vector tokens; +std::vector tokenize(std::string s, const std::string &delimiter) { + std::vector tokens; - size_t lastPos = 0; - size_t curentPos; + size_t lastPos = 0; + size_t curentPos; - while ((curentPos = s.find(delimiter, lastPos)) != std::string::npos) { - const size_t tokenLength = curentPos - lastPos; - tokens.push_back(s.substr(lastPos, tokenLength)); + while ((curentPos = s.find(delimiter, lastPos)) != std::string::npos) { + const size_t tokenLength = curentPos - lastPos; + tokens.push_back(s.substr(lastPos, tokenLength)); - // Advance in string - lastPos = curentPos + delimiter.length(); - } + // Advance in string + lastPos = curentPos + delimiter.length(); + } - // Check if there's a last token behind the last delimiter. - if (lastPos != s.length()) { - const size_t lastTokenLength = s.length() - lastPos; - tokens.push_back(s.substr(lastPos, lastTokenLength)); - } + // Check if there's a last token behind the last delimiter. + if (lastPos != s.length()) { + const size_t lastTokenLength = s.length() - lastPos; + tokens.push_back(s.substr(lastPos, lastTokenLength)); + } - return tokens; + return tokens; } -ssize_t readRandom(char *buf, size_t len) -{ - int fd; - ssize_t bytes = -1; +ssize_t readRandom(char *buf, size_t len) { + int fd; + ssize_t bytes = -1; - fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) - return -1; + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) + return -1; - while (len) { - bytes = read(fd, buf, len); - if (bytes < 0) - break; + while (len) { + bytes = read(fd, buf, len); + if (bytes < 0) + break; - len -= bytes; - buf += bytes; - } + len -= bytes; + buf += bytes; + } - close(fd); + close(fd); - return bytes; + return bytes; } // Setup exit handler -int signalsInit(void (*cb)(int signal, siginfo_t *sinfo, void *ctx), std::list cbSignals, std::list ignoreSignals) -{ - int ret; +int signalsInit(void (*cb)(int signal, siginfo_t *sinfo, void *ctx), + std::list cbSignals, std::list ignoreSignals) { + int ret; - Logger logger = logging.get("signals"); + Logger logger = logging.get("signals"); - logger->info("Initialize subsystem"); + logger->info("Initialize subsystem"); - struct sigaction sa_cb; - sa_cb.sa_flags = SA_SIGINFO | SA_NODEFER; - sa_cb.sa_sigaction = cb; + struct sigaction sa_cb; + sa_cb.sa_flags = SA_SIGINFO | SA_NODEFER; + sa_cb.sa_sigaction = cb; - struct sigaction sa_ign; - sa_ign.sa_flags = 0; - sa_ign.sa_handler = SIG_IGN; + struct sigaction sa_ign; + sa_ign.sa_flags = 0; + sa_ign.sa_handler = SIG_IGN; - main_thread = pthread_self(); + main_thread = pthread_self(); - sigemptyset(&sa_cb.sa_mask); - sigemptyset(&sa_ign.sa_mask); + sigemptyset(&sa_cb.sa_mask); + sigemptyset(&sa_ign.sa_mask); - cbSignals.insert(cbSignals.begin(), { SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGALRM }); - cbSignals.sort(); - cbSignals.unique(); + cbSignals.insert(cbSignals.begin(), + {SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGALRM}); + cbSignals.sort(); + cbSignals.unique(); - for (auto signal : cbSignals) { - ret = sigaction(signal, &sa_cb, nullptr); - if (ret) - return ret; - } + for (auto signal : cbSignals) { + ret = sigaction(signal, &sa_cb, nullptr); + if (ret) + return ret; + } - for (auto signal : ignoreSignals) { - ret = sigaction(signal, &sa_ign, nullptr); - if (ret) - return ret; - } + for (auto signal : ignoreSignals) { + ret = sigaction(signal, &sa_ign, nullptr); + if (ret) + return ret; + } - return 0; + return 0; } -char * decolor(char *str) -{ - char *p, *q; - bool inseq = false; +char *decolor(char *str) { + char *p, *q; + bool inseq = false; - for (p = q = str; *p; p++) { - switch (*p) { - case 0x1b: - if (*(++p) == '[') { - inseq = true; - continue; - } - break; + for (p = q = str; *p; p++) { + switch (*p) { + case 0x1b: + if (*(++p) == '[') { + inseq = true; + continue; + } + break; - case 'm': - if (inseq) { - inseq = false; - continue; - } - break; - } + case 'm': + if (inseq) { + inseq = false; + continue; + } + break; + } - if (!inseq) { - *q = *p; - q++; - } - } + if (!inseq) { + *q = *p; + q++; + } + } - *q = '\0'; + *q = '\0'; - return str; + return str; } -void killme(int sig) -{ - // Send only to main thread in case the ID was initilized by signalsInit() - if (main_thread) - pthread_kill(main_thread, sig); - else - kill(0, sig); +void killme(int sig) { + // Send only to main thread in case the ID was initilized by signalsInit() + if (main_thread) + pthread_kill(main_thread, sig); + else + kill(0, sig); } -double boxMuller(float m, float s) -{ - double x1, x2, y1; - static - double y2; - static - int use_last = 0; +double boxMuller(float m, float s) { + double x1, x2, y1; + static double y2; + static int use_last = 0; - if (use_last) { // Use value from previous call - y1 = y2; - use_last = 0; - } - else { - double w; - do { - x1 = 2.0 * randf() - 1.0; - x2 = 2.0 * randf() - 1.0; - w = x1*x1 + x2*x2; - } while (w >= 1.0); + if (use_last) { // Use value from previous call + y1 = y2; + use_last = 0; + } else { + double w; + do { + x1 = 2.0 * randf() - 1.0; + x2 = 2.0 * randf() - 1.0; + w = x1 * x1 + x2 * x2; + } while (w >= 1.0); - w = sqrt(-2.0 * log(w) / w); - y1 = x1 * w; - y2 = x2 * w; - use_last = 1; - } + w = sqrt(-2.0 * log(w) / w); + y1 = x1 * w; + y2 = x2 * w; + use_last = 1; + } - return m + y1 * s; + return m + y1 * s; } -double randf() -{ - return (double) random() / RAND_MAX; +double randf() { return (double)random() / RAND_MAX; } + +char *vstrcatf(char **dest, const char *fmt, va_list ap) { + char *tmp; + int n = *dest ? strlen(*dest) : 0; + int i = vasprintf(&tmp, fmt, ap); + + *dest = (char *)(realloc(*dest, n + i + 1)); + if (*dest != nullptr) + strncpy(*dest + n, tmp, i + 1); + + free(tmp); + + return *dest; } -char * vstrcatf(char **dest, const char *fmt, va_list ap) -{ - char *tmp; - int n = *dest ? strlen(*dest) : 0; - int i = vasprintf(&tmp, fmt, ap); +char *strcatf(char **dest, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vstrcatf(dest, fmt, ap); + va_end(ap); - *dest = (char *)(realloc(*dest, n + i + 1)); - if (*dest != nullptr) - strncpy(*dest+n, tmp, i + 1); - - free(tmp); - - return *dest; + return *dest; } -char * strcatf(char **dest, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vstrcatf(dest, fmt, ap); - va_end(ap); +char *strf(const char *fmt, ...) { + char *buf = nullptr; - return *dest; + va_list ap; + va_start(ap, fmt); + vstrcatf(&buf, fmt, ap); + va_end(ap); + + return buf; } -char * strf(const char *fmt, ...) -{ - char *buf = nullptr; +char *vstrf(const char *fmt, va_list va) { + char *buf = nullptr; - va_list ap; - va_start(ap, fmt); - vstrcatf(&buf, fmt, ap); - va_end(ap); + vstrcatf(&buf, fmt, va); - return buf; + return buf; } -char * vstrf(const char *fmt, va_list va) -{ - char *buf = nullptr; +void *memdup(const void *src, size_t bytes) { + void *dst = new char[bytes]; + if (!dst) + throw MemoryAllocationError(); - vstrcatf(&buf, fmt, va); + memcpy(dst, src, bytes); - return buf; + return dst; } -void * memdup(const void *src, size_t bytes) -{ - void *dst = new char[bytes]; - if (!dst) - throw MemoryAllocationError(); +pid_t spawn(const char *name, char *const argv[]) { + pid_t pid; - memcpy(dst, src, bytes); + pid = fork(); + switch (pid) { + case -1: + return -1; + case 0: + return execvp(name, (char *const *)argv); + } - return dst; + return pid; } -pid_t spawn(const char* name, char *const argv[]) -{ - pid_t pid; +size_t strlenp(const char *str) { + size_t sz = 0; - pid = fork(); - switch (pid) { - case -1: return -1; - case 0: return execvp(name, (char * const*) argv); - } + for (const char *d = str; *d; d++) { + const unsigned char *c = (const unsigned char *)d; - return pid; -} + if (isprint(*c)) + sz++; + else if (c[0] == '\b') + sz--; + else if (c[0] == '\t') + sz += 4; // Tab width == 4 + // CSI sequence + else if (c[0] == '\e' && c[1] == '[') { + c += 2; + while (*c && *c != 'm') + c++; + } + // UTF-8 + else if (c[0] >= 0xc2 && c[0] <= 0xdf) { + sz++; + c += 1; + } else if (c[0] >= 0xe0 && c[0] <= 0xef) { + sz++; + c += 2; + } else if (c[0] >= 0xf0 && c[0] <= 0xf4) { + sz++; + c += 3; + } -size_t strlenp(const char *str) -{ - size_t sz = 0; + d = (const char *)c; + } - for (const char *d = str; *d; d++) { - const unsigned char *c = (const unsigned char *) d; - - if (isprint(*c)) - sz++; - else if (c[0] == '\b') - sz--; - else if (c[0] == '\t') - sz += 4; // Tab width == 4 - // CSI sequence - else if (c[0] == '\e' && c[1] == '[') { - c += 2; - while (*c && *c != 'm') - c++; - } - // UTF-8 - else if (c[0] >= 0xc2 && c[0] <= 0xdf) { - sz++; - c += 1; - } - else if (c[0] >= 0xe0 && c[0] <= 0xef) { - sz++; - c += 2; - } - else if (c[0] >= 0xf0 && c[0] <= 0xf4) { - sz++; - c += 3; - } - - d = (const char *) c; - } - - return sz; + return sz; } int log2i(long long x) { - if (x == 0) - return 1; + if (x == 0) + return 1; - return sizeof(x) * 8 - __builtin_clzll(x) - 1; + return sizeof(x) * 8 - __builtin_clzll(x) - 1; } -int sha1sum(FILE *f, unsigned char *sha1) -{ - int ret; - char buf[512]; - ssize_t bytes; - long seek; +int sha1sum(FILE *f, unsigned char *sha1) { + int ret; + char buf[512]; + ssize_t bytes; + long seek; - seek = ftell(f); - fseek(f, 0, SEEK_SET); + seek = ftell(f); + fseek(f, 0, SEEK_SET); - EVP_MD_CTX *c = EVP_MD_CTX_new(); + EVP_MD_CTX *c = EVP_MD_CTX_new(); - ret = EVP_DigestInit(c, EVP_sha1()); - if (!ret) - return -1; + ret = EVP_DigestInit(c, EVP_sha1()); + if (!ret) + return -1; - bytes = fread(buf, 1, 512, f); - while (bytes > 0) { - EVP_DigestUpdate(c, buf, bytes); - bytes = fread(buf, 1, 512, f); - } + bytes = fread(buf, 1, 512, f); + while (bytes > 0) { + EVP_DigestUpdate(c, buf, bytes); + bytes = fread(buf, 1, 512, f); + } - EVP_DigestFinal(c, sha1, nullptr); + EVP_DigestFinal(c, sha1, nullptr); - fseek(f, seek, SEEK_SET); + fseek(f, seek, SEEK_SET); - EVP_MD_CTX_free(c); + EVP_MD_CTX_free(c); - return 0; + return 0; } -bool isDocker() -{ - return access("/.dockerenv", F_OK) != -1; +bool isDocker() { return access("/.dockerenv", F_OK) != -1; } + +bool isKubernetes() { + return access("/var/run/secrets/kubernetes.io", F_OK) != -1 || + getenv("KUBERNETES_SERVICE_HOST") != nullptr; } -bool isKubernetes() -{ - return access("/var/run/secrets/kubernetes.io", F_OK) != -1 || - getenv("KUBERNETES_SERVICE_HOST") != nullptr; -} - -bool isContainer() { - return isDocker() || isKubernetes(); -} +bool isContainer() { return isDocker() || isKubernetes(); } bool isPrivileged() { - // TODO: a cleaner way would be to use libcap here and check for the - // SYS_ADMIN capability. - auto *f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w"); - if (!f) - return false; + // TODO: a cleaner way would be to use libcap here and check for the + // SYS_ADMIN capability. + auto *f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w"); + if (!f) + return false; - fclose(f); + fclose(f); - return true; + return true; } } // namespace utils diff --git a/common/lib/uuid.cpp b/common/lib/uuid.cpp index e19d3f2f1..6c7e5c17b 100644 --- a/common/lib/uuid.cpp +++ b/common/lib/uuid.cpp @@ -11,76 +11,74 @@ using namespace villas::uuid; -std::string villas::uuid::toString(const uuid_t in) -{ - uuid_string_t str; - uuid_unparse_lower(in, str); - return str; +std::string villas::uuid::toString(const uuid_t in) { + uuid_string_t str; + uuid_unparse_lower(in, str); + return str; } -int villas::uuid::generateFromString(uuid_t out, const std::string &data, const std::string &ns) -{ - int ret; - EVP_MD_CTX *c = EVP_MD_CTX_new(); +int villas::uuid::generateFromString(uuid_t out, const std::string &data, + const std::string &ns) { + int ret; + EVP_MD_CTX *c = EVP_MD_CTX_new(); - ret = EVP_DigestInit(c, EVP_md5()); - if (!ret) - return -1; + ret = EVP_DigestInit(c, EVP_md5()); + if (!ret) + return -1; - // Namespace - ret = EVP_DigestUpdate(c, (unsigned char *) ns.c_str(), ns.size()); - if (!ret) - return -1; + // Namespace + ret = EVP_DigestUpdate(c, (unsigned char *)ns.c_str(), ns.size()); + if (!ret) + return -1; - // Data - ret = EVP_DigestUpdate(c, (unsigned char *) data.c_str(), data.size()); - if (!ret) - return -1; + // Data + ret = EVP_DigestUpdate(c, (unsigned char *)data.c_str(), data.size()); + if (!ret) + return -1; - ret = EVP_DigestFinal(c, (unsigned char *) out, nullptr); - if (!ret) - return -1; + ret = EVP_DigestFinal(c, (unsigned char *)out, nullptr); + if (!ret) + return -1; - EVP_MD_CTX_free(c); + EVP_MD_CTX_free(c); - return 0; + return 0; } -int villas::uuid::generateFromString(uuid_t out, const std::string &data, const uuid_t ns) -{ - int ret; - EVP_MD_CTX *c = EVP_MD_CTX_new(); +int villas::uuid::generateFromString(uuid_t out, const std::string &data, + const uuid_t ns) { + int ret; + EVP_MD_CTX *c = EVP_MD_CTX_new(); - ret = EVP_DigestInit(c, EVP_md5()); - if (!ret) - return -1; + ret = EVP_DigestInit(c, EVP_md5()); + if (!ret) + return -1; - // Namespace - ret = EVP_DigestUpdate(c, (unsigned char *) ns, 16); - if (!ret) - return -1; + // Namespace + ret = EVP_DigestUpdate(c, (unsigned char *)ns, 16); + if (!ret) + return -1; - // Data - ret = EVP_DigestUpdate(c, (unsigned char *) data.c_str(), data.size()); - if (!ret) - return -1; + // Data + ret = EVP_DigestUpdate(c, (unsigned char *)data.c_str(), data.size()); + if (!ret) + return -1; - ret = EVP_DigestFinal(c, (unsigned char *) out, nullptr); - if (!ret) - return -1; + ret = EVP_DigestFinal(c, (unsigned char *)out, nullptr); + if (!ret) + return -1; - EVP_MD_CTX_free(c); + EVP_MD_CTX_free(c); - return 0; + return 0; } -int villas::uuid::generateFromJson(uuid_t out, json_t *json, const uuid_t ns) -{ - char *str = json_dumps(json, JSON_COMPACT | JSON_SORT_KEYS); +int villas::uuid::generateFromJson(uuid_t out, json_t *json, const uuid_t ns) { + char *str = json_dumps(json, JSON_COMPACT | JSON_SORT_KEYS); - int ret = generateFromString(out, str, ns); + int ret = generateFromString(out, str, ns); - free(str); + free(str); - return ret; + return ret; } diff --git a/common/lib/version.cpp b/common/lib/version.cpp index 6d28aeaf4..6d5bf0ca6 100644 --- a/common/lib/version.cpp +++ b/common/lib/version.cpp @@ -14,42 +14,35 @@ using namespace villas::utils; -Version::Version(const std::string &str) -{ - size_t endpos; +Version::Version(const std::string &str) { + size_t endpos; - auto comp = tokenize(str, "."); + auto comp = tokenize(str, "."); - if (comp.size() > 3) - throw std::invalid_argument("Not a valid version string"); + if (comp.size() > 3) + throw std::invalid_argument("Not a valid version string"); - for (unsigned i = 0; i < 3; i++) { - if (i < comp.size()) { - components[i] = std::stoi(comp[i], &endpos, 10); + for (unsigned i = 0; i < 3; i++) { + if (i < comp.size()) { + components[i] = std::stoi(comp[i], &endpos, 10); - if (comp[i].begin() + endpos != comp[i].end()) - throw std::invalid_argument("Not a valid version string"); - } - else - components[i] = 0; - } + if (comp[i].begin() + endpos != comp[i].end()) + throw std::invalid_argument("Not a valid version string"); + } else + components[i] = 0; + } } -Version::Version(int maj, int min, int pat) : - components{maj, min, pat} -{ +Version::Version(int maj, int min, int pat) : components{maj, min, pat} {} -} - -int Version::cmp(const Version &lhs, const Version &rhs) -{ - int d; - - for (int i = 0; i < 3; i++) { - d = lhs.components[i] - rhs.components[i]; - if (d) - return d; - } - - return 0; +int Version::cmp(const Version &lhs, const Version &rhs) { + int d; + + for (int i = 0; i < 3; i++) { + d = lhs.components[i] - rhs.components[i]; + if (d) + return d; + } + + return 0; } diff --git a/common/tests/unit/base64.cpp b/common/tests/unit/base64.cpp index 807dde9bd..305c0afc5 100644 --- a/common/tests/unit/base64.cpp +++ b/common/tests/unit/base64.cpp @@ -16,18 +16,16 @@ using namespace villas::utils::base64; // cppcheck-suppress unknownMacro TestSuite(base64, .description = "Base64 En/decoder"); -static -std::vector vec(const char *str) -{ - return std::vector((byte *) str, (byte *) str + strlen(str)); +static std::vector vec(const char *str) { + return std::vector((byte *)str, (byte *)str + strlen(str)); } -Test(base64, encoding) -{ - cr_assert(encode(vec("pohy0Aiy1ZaVa5aik2yaiy3ifoh3oole")) == "cG9oeTBBaXkxWmFWYTVhaWsyeWFpeTNpZm9oM29vbGU="); +Test(base64, encoding) { + cr_assert(encode(vec("pohy0Aiy1ZaVa5aik2yaiy3ifoh3oole")) == + "cG9oeTBBaXkxWmFWYTVhaWsyeWFpeTNpZm9oM29vbGU="); } -Test(base64, decoding) -{ - cr_assert(decode("cG9oeTBBaXkxWmFWYTVhaWsyeWFpeTNpZm9oM29vbGU=") == vec("pohy0Aiy1ZaVa5aik2yaiy3ifoh3oole")); +Test(base64, decoding) { + cr_assert(decode("cG9oeTBBaXkxWmFWYTVhaWsyeWFpeTNpZm9oM29vbGU=") == + vec("pohy0Aiy1ZaVa5aik2yaiy3ifoh3oole")); } diff --git a/common/tests/unit/buffer.cpp b/common/tests/unit/buffer.cpp index 4c9d729f3..7f3f22958 100644 --- a/common/tests/unit/buffer.cpp +++ b/common/tests/unit/buffer.cpp @@ -18,97 +18,93 @@ using namespace villas; // cppcheck-suppress unknownMacro TestSuite(buffer, .description = "Buffer datastructure"); -Test(buffer, decode) -{ - Buffer buf; - json_t *j; - json_t *k; +Test(buffer, decode) { + Buffer buf; + json_t *j; + json_t *k; - const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; - size_t len = strlen(e); + const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; + size_t len = strlen(e); - buf.insert(buf.begin(), e, e+len); + buf.insert(buf.begin(), e, e + len); - k = json_loads(e, 0, nullptr); - cr_assert_not_null(k); + k = json_loads(e, 0, nullptr); + cr_assert_not_null(k); - j = buf.decode(); - cr_assert_not_null(j); - cr_assert(json_equal(j, k)); + j = buf.decode(); + cr_assert_not_null(j); + cr_assert(json_equal(j, k)); } -Test(buffer, encode) -{ - int ret; - Buffer buf; - json_t *k; +Test(buffer, encode) { + int ret; + Buffer buf; + json_t *k; - const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; + const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; - k = json_loads(e, 0, nullptr); - cr_assert_not_null(k); + k = json_loads(e, 0, nullptr); + cr_assert_not_null(k); - ret = buf.encode(k); - cr_assert_eq(ret, 0); + ret = buf.encode(k); + cr_assert_eq(ret, 0); - char *f = buf.data(); - cr_assert_not_null(f); + char *f = buf.data(); + cr_assert_not_null(f); - cr_assert_str_eq(e, f); + cr_assert_str_eq(e, f); - json_decref(k); + json_decref(k); } -Test(buffer, encode_decode) -{ - int ret; - Buffer buf; - json_t *k; - json_t *j; +Test(buffer, encode_decode) { + int ret; + Buffer buf; + json_t *k; + json_t *j; - const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; + const char *e = "{\"id\": \"5a786626-fbc6-4c04-98c2-48027e68c2fa\"}"; - k = json_loads(e, 0, nullptr); - cr_assert_not_null(k); + k = json_loads(e, 0, nullptr); + cr_assert_not_null(k); - ret = buf.encode(k); - cr_assert_eq(ret, 0); + ret = buf.encode(k); + cr_assert_eq(ret, 0); - j = buf.decode(); - cr_assert_not_null(j); + j = buf.decode(); + cr_assert_not_null(j); - cr_assert(json_equal(j, k)); + cr_assert(json_equal(j, k)); - json_decref(j); - json_decref(k); + json_decref(j); + json_decref(k); } -Test(buffer, multiple) -{ - int ret; - const int N = 100; +Test(buffer, multiple) { + int ret; + const int N = 100; - Buffer buf; - json_t *k[N]; - json_t *j[N]; + Buffer buf; + json_t *k[N]; + json_t *j[N]; - std::srand(std::time(nullptr)); + std::srand(std::time(nullptr)); - for (int i = 0; i < N; i++) { - k[i] = json_pack("{ s: i }", "id", std::rand()); - cr_assert_not_null(k[i]); + for (int i = 0; i < N; i++) { + k[i] = json_pack("{ s: i }", "id", std::rand()); + cr_assert_not_null(k[i]); - ret = buf.encode(k[i]); - cr_assert_eq(ret, 0); - } + ret = buf.encode(k[i]); + cr_assert_eq(ret, 0); + } - for (int i = 0; i < N; i++) { - j[i] = buf.decode(); - cr_assert_not_null(j[i]); + for (int i = 0; i < N; i++) { + j[i] = buf.decode(); + cr_assert_not_null(j[i]); - cr_assert(json_equal(k[i], j[i])); + cr_assert(json_equal(k[i], j[i])); - json_decref(k[i]); - json_decref(j[i]); - } + json_decref(k[i]); + json_decref(j[i]); + } } diff --git a/common/tests/unit/graph.cpp b/common/tests/unit/graph.cpp index 69ffa9e69..4c27c772e 100644 --- a/common/tests/unit/graph.cpp +++ b/common/tests/unit/graph.cpp @@ -17,114 +17,111 @@ using namespace villas; // cppcheck-suppress unknownMacro TestSuite(graph, .description = "Graph library"); -Test(graph, basic, .description = "DirectedGraph") -{ - Logger logger = logging.get("test:graph:basic"); - villas::graph::DirectedGraph<> g("test:graph:basic"); +Test(graph, basic, .description = "DirectedGraph") { + Logger logger = logging.get("test:graph:basic"); + villas::graph::DirectedGraph<> g("test:graph:basic"); - logger->info("Testing basic graph construction and modification"); + logger->info("Testing basic graph construction and modification"); - std::shared_ptr v1(new villas::graph::Vertex); - std::shared_ptr v2(new villas::graph::Vertex); - std::shared_ptr v3(new villas::graph::Vertex); + std::shared_ptr v1(new villas::graph::Vertex); + std::shared_ptr v2(new villas::graph::Vertex); + std::shared_ptr v3(new villas::graph::Vertex); - auto v1id = g.addVertex(v1); - auto v2id = g.addVertex(v2); - auto v3id = g.addVertex(v3); - cr_assert(g.getVertexCount() == 3); + auto v1id = g.addVertex(v1); + auto v2id = g.addVertex(v2); + auto v3id = g.addVertex(v3); + cr_assert(g.getVertexCount() == 3); - g.addDefaultEdge(v1id, v2id); - g.addDefaultEdge(v3id, v2id); - g.addDefaultEdge(v1id, v3id); - g.addDefaultEdge(v2id, v1id); - cr_assert(g.getEdgeCount() == 4); - cr_assert(g.vertexGetEdges(v1id).size() == 2); - cr_assert(g.vertexGetEdges(v2id).size() == 1); - cr_assert(g.vertexGetEdges(v3id).size() == 1); + g.addDefaultEdge(v1id, v2id); + g.addDefaultEdge(v3id, v2id); + g.addDefaultEdge(v1id, v3id); + g.addDefaultEdge(v2id, v1id); + cr_assert(g.getEdgeCount() == 4); + cr_assert(g.vertexGetEdges(v1id).size() == 2); + cr_assert(g.vertexGetEdges(v2id).size() == 1); + cr_assert(g.vertexGetEdges(v3id).size() == 1); - g.removeVertex(v1id); - g.dump(); - cr_assert(g.getVertexCount() == 2); - cr_assert(g.vertexGetEdges(v2id).size() == 0); + g.removeVertex(v1id); + g.dump(); + cr_assert(g.getVertexCount() == 2); + cr_assert(g.vertexGetEdges(v2id).size() == 0); } -Test(graph, path, .description = "Find path") -{ - Logger logger = logging.get("test:graph:path"); - logger->info("Testing path finding algorithm"); +Test(graph, path, .description = "Find path") { + Logger logger = logging.get("test:graph:path"); + logger->info("Testing path finding algorithm"); - using Graph = villas::graph::DirectedGraph<>; - Graph g("test:graph:path"); + using Graph = villas::graph::DirectedGraph<>; + Graph g("test:graph:path"); - std::shared_ptr v1(new villas::graph::Vertex); - std::shared_ptr v2(new villas::graph::Vertex); - std::shared_ptr v3(new villas::graph::Vertex); - std::shared_ptr v4(new villas::graph::Vertex); - std::shared_ptr v5(new villas::graph::Vertex); - std::shared_ptr v6(new villas::graph::Vertex); + std::shared_ptr v1(new villas::graph::Vertex); + std::shared_ptr v2(new villas::graph::Vertex); + std::shared_ptr v3(new villas::graph::Vertex); + std::shared_ptr v4(new villas::graph::Vertex); + std::shared_ptr v5(new villas::graph::Vertex); + std::shared_ptr v6(new villas::graph::Vertex); - auto v1id = g.addVertex(v1); - auto v2id = g.addVertex(v2); - auto v3id = g.addVertex(v3); + auto v1id = g.addVertex(v1); + auto v2id = g.addVertex(v2); + auto v3id = g.addVertex(v3); - auto v4id = g.addVertex(v4); - auto v5id = g.addVertex(v5); - auto v6id = g.addVertex(v6); + auto v4id = g.addVertex(v4); + auto v5id = g.addVertex(v5); + auto v6id = g.addVertex(v6); - g.addDefaultEdge(v1id, v2id); - g.addDefaultEdge(v2id, v3id); + g.addDefaultEdge(v1id, v2id); + g.addDefaultEdge(v2id, v3id); - // Create circular subgraph - g.addDefaultEdge(v4id, v5id); - g.addDefaultEdge(v5id, v4id); - g.addDefaultEdge(v5id, v6id); + // Create circular subgraph + g.addDefaultEdge(v4id, v5id); + g.addDefaultEdge(v5id, v4id); + g.addDefaultEdge(v5id, v6id); - g.dump(); + g.dump(); - logger->info("Find simple path via two edges"); - std::list path1; - cr_assert(g.getPath(v1id, v3id, path1)); + logger->info("Find simple path via two edges"); + std::list path1; + cr_assert(g.getPath(v1id, v3id, path1)); - logger->info(" Path from {} to {} via:", v1id, v3id); - for(auto &edge : path1) { - logger->info(" -> edge {}", edge); - } + logger->info(" Path from {} to {} via:", v1id, v3id); + for (auto &edge : path1) { + logger->info(" -> edge {}", edge); + } - logger->info("Find path between two unconnected sub-graphs"); - std::list path2; - cr_assert(not g.getPath(v1id, v4id, path2)); - logger->info(" no path found -> ok"); + logger->info("Find path between two unconnected sub-graphs"); + std::list path2; + cr_assert(not g.getPath(v1id, v4id, path2)); + logger->info(" no path found -> ok"); - logger->info("Find non-existing path in circular sub-graph"); - std::list path3; - cr_assert(not g.getPath(v4id, v2id, path3)); - logger->info(" no path found -> ok"); + logger->info("Find non-existing path in circular sub-graph"); + std::list path3; + cr_assert(not g.getPath(v4id, v2id, path3)); + logger->info(" no path found -> ok"); - logger->info("Find path in circular graph"); - std::list path4; - cr_assert(g.getPath(v4id, v6id, path4)); + logger->info("Find path in circular graph"); + std::list path4; + cr_assert(g.getPath(v4id, v6id, path4)); - logger->info(" Path from {} to {} via:", v4id, v6id); - for(auto &edge : path4) { - logger->info(" -> edge {}", edge); - } + logger->info(" Path from {} to {} via:", v4id, v6id); + for (auto &edge : path4) { + logger->info(" -> edge {}", edge); + } } -Test(graph, memory_manager, .description = "Global Memory Manager") -{ - Logger logger = logging.get("test:graph:mm"); - auto &mm = villas::MemoryManager::get(); +Test(graph, memory_manager, .description = "Global Memory Manager") { + Logger logger = logging.get("test:graph:mm"); + auto &mm = villas::MemoryManager::get(); - logger->info("Create address spaces"); - auto dmaRegs = mm.getOrCreateAddressSpace("DMA Registers"); - auto pcieBridge = mm.getOrCreateAddressSpace("PCIe Bridge"); + logger->info("Create address spaces"); + auto dmaRegs = mm.getOrCreateAddressSpace("DMA Registers"); + auto pcieBridge = mm.getOrCreateAddressSpace("PCIe Bridge"); - logger->info("Create a mapping"); - mm.createMapping(0x1000, 0, 0x1000, "Testmapping", dmaRegs, pcieBridge); + logger->info("Create a mapping"); + mm.createMapping(0x1000, 0, 0x1000, "Testmapping", dmaRegs, pcieBridge); - logger->info("Find address space by name"); - auto vertex = mm.findAddressSpace("PCIe Bridge"); - logger->info(" found: {}", vertex); + logger->info("Find address space by name"); + auto vertex = mm.findAddressSpace("PCIe Bridge"); + logger->info(" found: {}", vertex); - mm.getGraph().dump(); + mm.getGraph().dump(); } diff --git a/common/tests/unit/hist.cpp b/common/tests/unit/hist.cpp index 6ab621fbd..f50fcba1b 100644 --- a/common/tests/unit/hist.cpp +++ b/common/tests/unit/hist.cpp @@ -21,12 +21,12 @@ TestSuite(hist, .description = "Histogram"); Test(hist, simple) { - Hist h(10,2); + Hist h(10, 2); - for (auto td : test_data) - h.put(td); + for (auto td : test_data) + h.put(td); - cr_assert_float_eq(h.getMean(), 5.5, 1e-6, "Mean is %lf", h.getMean()); - cr_assert_float_eq(h.getVar(), 9.1666, 1e-3); - cr_assert_float_eq(h.getStddev(), 3.027650, 1e-6); + cr_assert_float_eq(h.getMean(), 5.5, 1e-6, "Mean is %lf", h.getMean()); + cr_assert_float_eq(h.getVar(), 9.1666, 1e-3); + cr_assert_float_eq(h.getStddev(), 3.027650, 1e-6); } diff --git a/common/tests/unit/kernel.cpp b/common/tests/unit/kernel.cpp index f3968a5ed..118b35bd9 100644 --- a/common/tests/unit/kernel.cpp +++ b/common/tests/unit/kernel.cpp @@ -15,83 +15,78 @@ using namespace villas::kernel; TestSuite(kernel, .description = "Kernel features"); #if defined(__x86_64__) || defined(__i386__) - #define PAGESIZE (1 << 12) - #define CACHELINESIZE 64 +#define PAGESIZE (1 << 12) +#define CACHELINESIZE 64 - #if defined(__x86_64__) - #define HUGEPAGESIZE (1 << 21) - #elif defined(__i386__) - #define HUGEPAGESIZE (1 << 22) - #endif +#if defined(__x86_64__) +#define HUGEPAGESIZE (1 << 21) +#elif defined(__i386__) +#define HUGEPAGESIZE (1 << 22) +#endif #else - #error "Unsupported architecture" +#error "Unsupported architecture" #endif // This test is not portable, but we currently support x86 only -Test(kernel, sizes) -{ - int sz; +Test(kernel, sizes) { + int sz; - sz = getPageSize(); - cr_assert_eq(sz, PAGESIZE); + sz = getPageSize(); + cr_assert_eq(sz, PAGESIZE); - sz = getHugePageSize(); - cr_assert(sz == HUGEPAGESIZE); + sz = getHugePageSize(); + cr_assert(sz == HUGEPAGESIZE); - sz = getCachelineSize(); - cr_assert_eq(sz, CACHELINESIZE); + sz = getCachelineSize(); + cr_assert_eq(sz, CACHELINESIZE); } #ifdef __linux__ -Test(kernel, hugepages) -{ - int ret; +Test(kernel, hugepages) { + int ret; - ret = setNrHugepages(25); - cr_assert_eq(ret, 0); + ret = setNrHugepages(25); + cr_assert_eq(ret, 0); - ret = getNrHugepages(); - cr_assert_eq(ret, 25); + ret = getNrHugepages(); + cr_assert_eq(ret, 25); - ret = setNrHugepages(10); - cr_assert_eq(ret, 0); + ret = setNrHugepages(10); + cr_assert_eq(ret, 0); - ret = getNrHugepages(); - cr_assert_eq(ret, 10); + ret = getNrHugepages(); + cr_assert_eq(ret, 10); } -Test(kernel, version) -{ - using villas::utils::Version; +Test(kernel, version) { + using villas::utils::Version; - Version ver = villas::kernel::getVersion(); - Version ver1 = { 100, 5 }; - Version ver2 = { 2, 6 }; + Version ver = villas::kernel::getVersion(); + Version ver1 = {100, 5}; + Version ver2 = {2, 6}; - cr_assert_lt(ver, ver1); - cr_assert_gt(ver, ver2); + cr_assert_lt(ver, ver1); + cr_assert_gt(ver, ver2); } -Test(kernel, module, .disabled = true) -{ - int ret; +Test(kernel, module, .disabled = true) { + int ret; - ret = isModuleLoaded("nf_nat"); - cr_assert_eq(ret, 0); + ret = isModuleLoaded("nf_nat"); + cr_assert_eq(ret, 0); - ret = isModuleLoaded("does_not_exist"); - cr_assert_neq(ret, 0); + ret = isModuleLoaded("does_not_exist"); + cr_assert_neq(ret, 0); } -Test(kernel, frequency) -{ - int ret; - uint64_t freq; +Test(kernel, frequency) { + int ret; + uint64_t freq; - ret = get_cpu_frequency(&freq); - cr_assert_eq(ret, 0); + ret = get_cpu_frequency(&freq); + cr_assert_eq(ret, 0); - // Check for plausability only - cr_assert(freq > 1e9 && freq < 5e9); + // Check for plausability only + cr_assert(freq > 1e9 && freq < 5e9); } #endif diff --git a/common/tests/unit/list.cpp b/common/tests/unit/list.cpp index a8f3ca445..98b6c34d3 100644 --- a/common/tests/unit/list.cpp +++ b/common/tests/unit/list.cpp @@ -5,154 +5,155 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include -#include #include -#include #include +#include using namespace villas; -static -const char *nouns[] = { "time", "person", "year", "way", "day", "thing", "man", "world", "life", "hand", "part", "child", "eye", "woman", "place", "work", "week", "case", "point", "government", "company", "number", "group", "problem", "fact" }; +static const char *nouns[] = { + "time", "person", "year", "way", "day", "thing", "man", + "world", "life", "hand", "part", "child", "eye", "woman", + "place", "work", "week", "case", "point", "government", "company", + "number", "group", "problem", "fact"}; struct data { - const char *name; - int data; + const char *name; + int data; }; // cppcheck-suppress unknownMacro TestSuite(list, .description = "List datastructure"); -Test(list, list_search) -{ - int ret; - struct List l; +Test(list, list_search) { + int ret; + struct List l; - ret = list_init(&l); - cr_assert_eq(ret, 0); + ret = list_init(&l); + cr_assert_eq(ret, 0); - // Fill list - for (unsigned i = 0; i < ARRAY_LEN(nouns); i++) - list_push(&l, (void *) nouns[i]); + // Fill list + for (unsigned i = 0; i < ARRAY_LEN(nouns); i++) + list_push(&l, (void *)nouns[i]); - cr_assert_eq(list_length(&l), ARRAY_LEN(nouns)); + cr_assert_eq(list_length(&l), ARRAY_LEN(nouns)); - // Declare on stack! - char positive[] = "woman"; - char negative[] = "dinosaurrier"; + // Declare on stack! + char positive[] = "woman"; + char negative[] = "dinosaurrier"; - char *found = (char *) list_search(&l, (cmp_cb_t) strcmp, positive); - cr_assert_not_null(found); - cr_assert_eq(found, nouns[13], "found = %p, nouns[13] = %p", found, nouns[13]); - cr_assert_str_eq(found, positive); + char *found = (char *)list_search(&l, (cmp_cb_t)strcmp, positive); + cr_assert_not_null(found); + cr_assert_eq(found, nouns[13], "found = %p, nouns[13] = %p", found, + nouns[13]); + cr_assert_str_eq(found, positive); - char *not_found = (char *) list_search(&l, (cmp_cb_t) strcmp, negative); - cr_assert_null(not_found); + char *not_found = (char *)list_search(&l, (cmp_cb_t)strcmp, negative); + cr_assert_null(not_found); - ret = list_destroy(&l, nullptr, false); - cr_assert_eq(ret, 0); + ret = list_destroy(&l, nullptr, false); + cr_assert_eq(ret, 0); } struct content { - int destroyed; + int destroyed; }; -static -int dtor(void *ptr) -{ - struct content *elm = (struct content *) ptr; +static int dtor(void *ptr) { + struct content *elm = (struct content *)ptr; - elm->destroyed = 1; + elm->destroyed = 1; - return 0; + return 0; } -Test(list, destructor) -{ - int ret; - struct List l; +Test(list, destructor) { + int ret; + struct List l; - struct content elm; - elm.destroyed = 0; + struct content elm; + elm.destroyed = 0; - ret = list_init(&l); - cr_assert_eq(ret, 0); + ret = list_init(&l); + cr_assert_eq(ret, 0); - list_push(&l, &elm); + list_push(&l, &elm); - cr_assert_eq(list_length(&l), 1); + cr_assert_eq(list_length(&l), 1); - ret = list_destroy(&l, dtor, false); - cr_assert_eq(ret, 0); + ret = list_destroy(&l, dtor, false); + cr_assert_eq(ret, 0); - cr_assert_eq(elm.destroyed, 1); + cr_assert_eq(elm.destroyed, 1); } -Test(list, basics) -{ - uintptr_t i; - int ret; - struct List l; +Test(list, basics) { + uintptr_t i; + int ret; + struct List l; - ret = list_init(&l); - cr_assert_eq(ret, 0); + ret = list_init(&l); + cr_assert_eq(ret, 0); - for (i = 0; i < 100; i++) { - cr_assert_eq(list_length(&l), i); + for (i = 0; i < 100; i++) { + cr_assert_eq(list_length(&l), i); - list_push(&l, (void *) i); - } + list_push(&l, (void *)i); + } - cr_assert_eq(list_at_safe(&l, 555), nullptr); - cr_assert_eq(list_last(&l), (void *) 99); - cr_assert_eq(list_first(&l), (void *) 0); + cr_assert_eq(list_at_safe(&l, 555), nullptr); + cr_assert_eq(list_last(&l), (void *)99); + cr_assert_eq(list_first(&l), (void *)0); - for (size_t j = 0, i = 0; j < list_length(&l); j++) { - void *k = list_at(&l, j); + for (size_t j = 0, i = 0; j < list_length(&l); j++) { + void *k = list_at(&l, j); - cr_assert_eq(k, (void *) i++); - } + cr_assert_eq(k, (void *)i++); + } - list_sort(&l, (cmp_cb_t) [](const void *a, const void *b) -> int { - return (intptr_t) b - (intptr_t) a; - }); + list_sort( + &l, (cmp_cb_t)[](const void *a, const void *b)->int { + return (intptr_t)b - (intptr_t)a; + }); - for (size_t j = 0, i = 99; j <= 99; j++, i--) { - uintptr_t k = (uintptr_t) list_at(&l, j); - cr_assert_eq(k, i, "Is %zu, expected %zu", k, i); - } + for (size_t j = 0, i = 99; j <= 99; j++, i--) { + uintptr_t k = (uintptr_t)list_at(&l, j); + cr_assert_eq(k, i, "Is %zu, expected %zu", k, i); + } - ret = list_contains(&l, (void *) 55); - cr_assert(ret); + ret = list_contains(&l, (void *)55); + cr_assert(ret); - void *before_ptr = list_at(&l, 12); + void *before_ptr = list_at(&l, 12); - ret = list_insert(&l, 12, (void *) 123); - cr_assert_eq(ret, 0); - cr_assert_eq(list_at(&l, 12), (void *) 123, "Is: %p", list_at(&l, 12)); + ret = list_insert(&l, 12, (void *)123); + cr_assert_eq(ret, 0); + cr_assert_eq(list_at(&l, 12), (void *)123, "Is: %p", list_at(&l, 12)); - ret = list_remove(&l, 12); - cr_assert_eq(ret, 0); - cr_assert_eq(list_at(&l, 12), before_ptr); + ret = list_remove(&l, 12); + cr_assert_eq(ret, 0); + cr_assert_eq(list_at(&l, 12), before_ptr); - int counts, before_len; + int counts, before_len; - before_len = list_length(&l); - counts = list_contains(&l, (void *) 55); - cr_assert_gt(counts, 0); + before_len = list_length(&l); + counts = list_contains(&l, (void *)55); + cr_assert_gt(counts, 0); - list_remove_all(&l, (void *) 55); - cr_assert_eq(list_length(&l), (size_t) (before_len - counts)); + list_remove_all(&l, (void *)55); + cr_assert_eq(list_length(&l), (size_t)(before_len - counts)); - ret = list_contains(&l, (void *) 55); - cr_assert(!ret); + ret = list_contains(&l, (void *)55); + cr_assert(!ret); - ret = list_destroy(&l, nullptr, false); - cr_assert(!ret); + ret = list_destroy(&l, nullptr, false); + cr_assert(!ret); - ret = list_length(&l); - cr_assert_eq(ret, -1, "List not properly destroyed: l.length = %zd", l.length); + ret = list_length(&l); + cr_assert_eq(ret, -1, "List not properly destroyed: l.length = %zd", + l.length); } diff --git a/common/tests/unit/popen.cpp b/common/tests/unit/popen.cpp index d3f29c515..6fe4dd700 100644 --- a/common/tests/unit/popen.cpp +++ b/common/tests/unit/popen.cpp @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include @@ -15,65 +15,62 @@ using namespace villas::utils; // cppcheck-suppress unknownMacro TestSuite(popen, .description = "Bi-directional popen"); -Test(popen, no_shell) -{ - PopenStream proc("/usr/bin/tee", {"tee", "test"}); +Test(popen, no_shell) { + PopenStream proc("/usr/bin/tee", {"tee", "test"}); - proc.cout() << "Hello World" << std::endl; - proc.cout().flush(); + proc.cout() << "Hello World" << std::endl; + proc.cout().flush(); - std::string str, str2; + std::string str, str2; - proc.cin() >> str >> str2; + proc.cin() >> str >> str2; - std::cout << str << str2 << std::endl; + std::cout << str << str2 << std::endl; - cr_assert_eq(str, "Hello"); - cr_assert_eq(str2, "World"); + cr_assert_eq(str, "Hello"); + cr_assert_eq(str2, "World"); - proc.kill(); - proc.close(); + proc.kill(); + proc.close(); } -Test(popen, shell) -{ - PopenStream proc("echo \"Hello World\"", {}, {}, std::string(), true); +Test(popen, shell) { + PopenStream proc("echo \"Hello World\"", {}, {}, std::string(), true); - std::string str, str2; + std::string str, str2; - proc.cin() >> str >> str2; + proc.cin() >> str >> str2; - cr_assert_eq(str, "Hello"); - cr_assert_eq(str2, "World"); + cr_assert_eq(str, "Hello"); + cr_assert_eq(str2, "World"); - proc.kill(); - proc.close(); + proc.kill(); + proc.close(); } -Test(popen, wd) -{ - PopenStream proc("/usr/bin/pwd", {"pwd"}, {}, "/usr/lib"); +Test(popen, wd) { + PopenStream proc("/usr/bin/pwd", {"pwd"}, {}, "/usr/lib"); - std::string wd; + std::string wd; - proc.cin() >> wd; + proc.cin() >> wd; - cr_assert_eq(wd, "/usr/lib"); + cr_assert_eq(wd, "/usr/lib"); - proc.kill(); - proc.close(); + proc.kill(); + proc.close(); } -Test(popen, env) -{ - PopenStream proc("echo $MYVAR", {}, {{"MYVAR", "TESTVAL"}}, std::string(), true); +Test(popen, env) { + PopenStream proc("echo $MYVAR", {}, {{"MYVAR", "TESTVAL"}}, std::string(), + true); - std::string var; + std::string var; - proc.cin() >> var; + proc.cin() >> var; - cr_assert_eq(var, "TESTVAL"); + cr_assert_eq(var, "TESTVAL"); - proc.kill(); - proc.close(); + proc.kill(); + proc.close(); } diff --git a/common/tests/unit/task.cpp b/common/tests/unit/task.cpp index d85cbe8bb..13f53099c 100644 --- a/common/tests/unit/task.cpp +++ b/common/tests/unit/task.cpp @@ -15,55 +15,56 @@ // cppcheck-suppress unknownMacro TestSuite(task, .description = "Periodic timer tasks"); -Test(task, rate, .timeout = 10) -{ - int runs = 10; - double rate = 5, waited; - struct timespec start, end; - Task task(CLOCK_MONOTONIC); +Test(task, rate, .timeout = 10) { + int runs = 10; + double rate = 5, waited; + struct timespec start, end; + Task task(CLOCK_MONOTONIC); - task.setRate(rate); + task.setRate(rate); - int i; - for (i = 0; i < runs; i++) { - clock_gettime(CLOCK_MONOTONIC, &start); + int i; + for (i = 0; i < runs; i++) { + clock_gettime(CLOCK_MONOTONIC, &start); - task.wait(); + task.wait(); - clock_gettime(CLOCK_MONOTONIC, &end); + clock_gettime(CLOCK_MONOTONIC, &end); - waited = time_delta(&start, &end); + waited = time_delta(&start, &end); - if (fabs(waited - 1.0 / rate) > 10e-3) - break; - } + if (fabs(waited - 1.0 / rate) > 10e-3) + break; + } - if (i < runs) - cr_assert_float_eq(waited, 1.0 / rate, 1e-2, "We slept for %f instead of %f secs in round %d", waited, 1.0 / rate, i); + if (i < runs) + cr_assert_float_eq(waited, 1.0 / rate, 1e-2, + "We slept for %f instead of %f secs in round %d", waited, + 1.0 / rate, i); } -Test(task, wait_until, .timeout = 5) -{ - int ret; - struct timespec start, end, diff, future; +Test(task, wait_until, .timeout = 5) { + int ret; + struct timespec start, end, diff, future; - Task task(CLOCK_REALTIME); + Task task(CLOCK_REALTIME); - double waitfor = 3.423456789; + double waitfor = 3.423456789; - start = time_now(); - diff = time_from_double(waitfor); - future = time_add(&start, &diff); + start = time_now(); + diff = time_from_double(waitfor); + future = time_add(&start, &diff); - task.setNext(&future); + task.setNext(&future); - ret = task.wait(); + ret = task.wait(); - end = time_now(); + end = time_now(); - cr_assert_eq(ret, 1); + cr_assert_eq(ret, 1); - double waited = time_delta(&start, &end); + double waited = time_delta(&start, &end); - cr_assert_float_eq(waited, waitfor, 1e-2, "We slept for %f instead of %f secs", waited, waitfor); + cr_assert_float_eq(waited, waitfor, 1e-2, + "We slept for %f instead of %f secs", waited, waitfor); } diff --git a/common/tests/unit/timing.cpp b/common/tests/unit/timing.cpp index ff706fb46..a7409c3f1 100644 --- a/common/tests/unit/timing.cpp +++ b/common/tests/unit/timing.cpp @@ -5,73 +5,71 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include +#include +#include #include // cppcheck-suppress unknownMacro TestSuite(timing, .description = "Time measurements"); -Test(timing, time_now) -{ - struct timespec now1 = time_now(); - struct timespec now2 = time_now(); +Test(timing, time_now) { + struct timespec now1 = time_now(); + struct timespec now2 = time_now(); - cr_assert(time_cmp(&now1, &now2) <= 0, "time_now() was reordered!"); + cr_assert(time_cmp(&now1, &now2) <= 0, "time_now() was reordered!"); } -Test(timing, time_diff) -{ - struct timespec ts1 = { .tv_sec = 0, .tv_nsec = 1}; // Value doesnt matter - struct timespec ts2 = { .tv_sec = 1, .tv_nsec = 0}; // Overflow in nano seconds! +Test(timing, time_diff) { + struct timespec ts1 = {.tv_sec = 0, .tv_nsec = 1}; // Value doesnt matter + struct timespec ts2 = {.tv_sec = 1, + .tv_nsec = 0}; // Overflow in nano seconds! - struct timespec ts3 = time_diff(&ts1, &ts2); + struct timespec ts3 = time_diff(&ts1, &ts2); - // ts4 == ts2? - cr_assert_eq(ts3.tv_sec, 0); - cr_assert_eq(ts3.tv_nsec, 999999999); + // ts4 == ts2? + cr_assert_eq(ts3.tv_sec, 0); + cr_assert_eq(ts3.tv_nsec, 999999999); } -Test(timing, time_add) -{ - struct timespec ts1 = { .tv_sec = 1, .tv_nsec = 999999999}; // Value doesnt matter - struct timespec ts2 = { .tv_sec = 1, .tv_nsec = 1}; // Overflow in nano seconds! +Test(timing, time_add) { + struct timespec ts1 = {.tv_sec = 1, + .tv_nsec = 999999999}; // Value doesnt matter + struct timespec ts2 = {.tv_sec = 1, + .tv_nsec = 1}; // Overflow in nano seconds! - struct timespec ts3 = time_add(&ts1, &ts2); + struct timespec ts3 = time_add(&ts1, &ts2); - // ts4 == ts2? - cr_assert_eq(ts3.tv_sec, 3); - cr_assert_eq(ts3.tv_nsec, 0); + // ts4 == ts2? + cr_assert_eq(ts3.tv_sec, 3); + cr_assert_eq(ts3.tv_nsec, 0); } -Test(timing, time_delta) -{ - struct timespec ts1 = { .tv_sec = 1, .tv_nsec = 123}; // Value doesnt matter - struct timespec ts2 = { .tv_sec = 5, .tv_nsec = 246}; // Overflow in nano seconds! +Test(timing, time_delta) { + struct timespec ts1 = {.tv_sec = 1, .tv_nsec = 123}; // Value doesnt matter + struct timespec ts2 = {.tv_sec = 5, + .tv_nsec = 246}; // Overflow in nano seconds! - double delta = time_delta(&ts1, &ts2); + double delta = time_delta(&ts1, &ts2); - cr_assert_float_eq(delta, 4 + 123e-9, 1e-9); + cr_assert_float_eq(delta, 4 + 123e-9, 1e-9); } -Test(timing, time_from_double) -{ - double ref = 1234.56789; +Test(timing, time_from_double) { + double ref = 1234.56789; - struct timespec ts = time_from_double(ref); + struct timespec ts = time_from_double(ref); - cr_assert_eq(ts.tv_sec, 1234); - cr_assert_eq(ts.tv_nsec, 567890000); + cr_assert_eq(ts.tv_sec, 1234); + cr_assert_eq(ts.tv_nsec, 567890000); } -Test(timing, time_to_from_double) -{ - double ref = 1234.56789; +Test(timing, time_to_from_double) { + double ref = 1234.56789; - struct timespec ts = time_from_double(ref); - double dbl = time_to_double(&ts); + struct timespec ts = time_from_double(ref); + double dbl = time_to_double(&ts); - cr_assert_float_eq(dbl, ref, 1e-9); + cr_assert_float_eq(dbl, ref, 1e-9); } diff --git a/common/tests/unit/tsc.cpp b/common/tests/unit/tsc.cpp index c0b44da00..6e73dc04a 100644 --- a/common/tests/unit/tsc.cpp +++ b/common/tests/unit/tsc.cpp @@ -7,56 +7,56 @@ #include -#include -#include #include +#include +#include #define CNT (1 << 18) // cppcheck-suppress unknownMacro TestSuite(tsc, .description = "Timestamp counters"); -Test(tsc, increasing) -{ - int ret; - struct Tsc tsc; - uint64_t *cntrs; +Test(tsc, increasing) { + int ret; + struct Tsc tsc; + uint64_t *cntrs; - ret = tsc_init(&tsc); - cr_assert_eq(ret, 0); + ret = tsc_init(&tsc); + cr_assert_eq(ret, 0); - cntrs = new uint64_t[CNT]; - cr_assert_not_null(cntrs); + cntrs = new uint64_t[CNT]; + cr_assert_not_null(cntrs); - for (unsigned i = 0; i < CNT; i++) - cntrs[i] = tsc_now(&tsc); + for (unsigned i = 0; i < CNT; i++) + cntrs[i] = tsc_now(&tsc); - for (unsigned i = 1; i < CNT; i++) - cr_assert_lt(cntrs[i-1], cntrs[i]); + for (unsigned i = 1; i < CNT; i++) + cr_assert_lt(cntrs[i - 1], cntrs[i]); - delete cntrs; + delete cntrs; } -Test(tsc, sleep) -{ - int ret; - double delta, duration = 1; - struct timespec start, stop; - struct Tsc tsc; - uint64_t start_cycles, end_cycles; +Test(tsc, sleep) { + int ret; + double delta, duration = 1; + struct timespec start, stop; + struct Tsc tsc; + uint64_t start_cycles, end_cycles; - ret = tsc_init(&tsc); - cr_assert_eq(ret, 0); + ret = tsc_init(&tsc); + cr_assert_eq(ret, 0); - clock_gettime(CLOCK_MONOTONIC, &start); + clock_gettime(CLOCK_MONOTONIC, &start); - start_cycles = tsc_now(&tsc); - end_cycles = start_cycles + duration * tsc.frequency; + start_cycles = tsc_now(&tsc); + end_cycles = start_cycles + duration * tsc.frequency; - while (tsc_now(&tsc) < end_cycles); + while (tsc_now(&tsc) < end_cycles) + ; - clock_gettime(CLOCK_MONOTONIC, &stop); - delta = time_delta(&start, &stop); + clock_gettime(CLOCK_MONOTONIC, &stop); + delta = time_delta(&start, &stop); - cr_assert_float_eq(delta, duration, 1e-4, "Error: %f, Delta: %lf, Freq: %llu", delta - duration, delta, tsc.frequency); + cr_assert_float_eq(delta, duration, 1e-4, "Error: %f, Delta: %lf, Freq: %llu", + delta - duration, delta, tsc.frequency); } diff --git a/common/tests/unit/utils.cpp b/common/tests/unit/utils.cpp index d22f3e3a9..003c6d5f5 100644 --- a/common/tests/unit/utils.cpp +++ b/common/tests/unit/utils.cpp @@ -8,10 +8,10 @@ #include #include -#include -#include #include #include +#include +#include using namespace villas::utils; @@ -19,19 +19,21 @@ using namespace villas::utils; TestSuite(utils, .description = "Utilities"); // Simple normality test for 1,2,3s intervals -Test(utils, box_muller) -{ - double n; - unsigned sigma[3] = { 0 }; - unsigned iter = 1000000; +Test(utils, box_muller) { + double n; + unsigned sigma[3] = {0}; + unsigned iter = 1000000; - for (unsigned i = 0; i < iter; i++) { - n = boxMuller(0, 1); + for (unsigned i = 0; i < iter; i++) { + n = boxMuller(0, 1); - if (n > 2 || n < -2) sigma[2]++; - else if (n > 1 || n < -1) sigma[1]++; - else sigma[0]++; - } + if (n > 2 || n < -2) + sigma[2]++; + else if (n > 1 || n < -1) + sigma[1]++; + else + sigma[0]++; + } #if 0 printf("%f %f %f\n", @@ -40,179 +42,173 @@ Test(utils, box_muller) (double) sigma[0] / iter); #endif - // The random variable generated by the Box Muller transform is - // not an ideal normal distributed variable. - // The numbers from below are empirically measured. - cr_assert_float_eq((double) sigma[2] / iter, 0.045527, 1e-2); - cr_assert_float_eq((double) sigma[1] / iter, 0.271644, 1e-2); - cr_assert_float_eq((double) sigma[0] / iter, 0.682829, 1e-2); + // The random variable generated by the Box Muller transform is + // not an ideal normal distributed variable. + // The numbers from below are empirically measured. + cr_assert_float_eq((double)sigma[2] / iter, 0.045527, 1e-2); + cr_assert_float_eq((double)sigma[1] / iter, 0.271644, 1e-2); + cr_assert_float_eq((double)sigma[0] / iter, 0.682829, 1e-2); } #ifdef __linux__ -Test(utils, cpuset) -{ - using villas::utils::CpuSet; +Test(utils, cpuset) { + using villas::utils::CpuSet; - uintmax_t int1 = 0x1234567890ABCDEFULL; + uintmax_t int1 = 0x1234567890ABCDEFULL; - CpuSet cset1(int1); + CpuSet cset1(int1); - std::string cset1_str = cset1; + std::string cset1_str = cset1; - CpuSet cset2(cset1_str); + CpuSet cset2(cset1_str); - cr_assert_eq(cset1, cset2); + cr_assert_eq(cset1, cset2); - uintmax_t int2 = cset2; + uintmax_t int2 = cset2; - cr_assert_eq(int1, int2); + cr_assert_eq(int1, int2); - CpuSet cset3("1-5"); - CpuSet cset4("1,2,3,4,5"); + CpuSet cset3("1-5"); + CpuSet cset4("1,2,3,4,5"); - cr_assert_eq(cset3, cset4); - cr_assert_eq(cset3.count(), 5); + cr_assert_eq(cset3, cset4); + cr_assert_eq(cset3.count(), 5); - cr_assert(cset3.isSet(3)); - cr_assert_not(cset3.isSet(6)); + cr_assert(cset3.isSet(3)); + cr_assert_not(cset3.isSet(6)); - cr_assert(cset3[3]); - cr_assert_not(cset3[6]); + cr_assert(cset3[3]); + cr_assert_not(cset3[6]); - cset4.set(6); - cr_assert(cset4[6]); + cset4.set(6); + cr_assert(cset4[6]); - cset4.clear(6); - cr_assert_not(cset4[6]); + cset4.clear(6); + cr_assert_not(cset4[6]); - cr_assert_str_eq(static_cast(cset4).c_str(), "1-5"); + cr_assert_str_eq(static_cast(cset4).c_str(), "1-5"); - cr_assert_any_throw(CpuSet cset5("0-")); + cr_assert_any_throw(CpuSet cset5("0-")); - CpuSet cset6; - cr_assert(cset6.empty()); - cr_assert_eq(cset6.count(), 0); + CpuSet cset6; + cr_assert(cset6.empty()); + cr_assert_eq(cset6.count(), 0); - cr_assert((~cset6).full()); - cr_assert((cset1 | ~cset1).full()); - cr_assert((cset1 ^ cset1).empty()); - cr_assert((cset1 & cset6).empty()); + cr_assert((~cset6).full()); + cr_assert((cset1 | ~cset1).full()); + cr_assert((cset1 ^ cset1).empty()); + cr_assert((cset1 & cset6).empty()); - cset1.zero(); - cr_assert(cset1.empty()); + cset1.zero(); + cr_assert(cset1.empty()); } #endif // __linux__ -Test(utils, memdup) -{ - char orig[1024], *copy; - size_t len; +Test(utils, memdup) { + char orig[1024], *copy; + size_t len; - len = readRandom(orig, sizeof(orig)); - cr_assert_eq(len, sizeof(orig)); + len = readRandom(orig, sizeof(orig)); + cr_assert_eq(len, sizeof(orig)); - copy = (char *) memdup(orig, sizeof(orig)); - cr_assert_not_null(copy); - cr_assert_arr_eq(copy, orig, sizeof(orig)); + copy = (char *)memdup(orig, sizeof(orig)); + cr_assert_not_null(copy); + cr_assert_arr_eq(copy, orig, sizeof(orig)); - free(copy); + free(copy); } -Test(utils, is_aligned) -{ - // Positive - cr_assert(IS_ALIGNED(1, 1)); - cr_assert(IS_ALIGNED(128, 64)); +Test(utils, is_aligned) { + // Positive + cr_assert(IS_ALIGNED(1, 1)); + cr_assert(IS_ALIGNED(128, 64)); - // Negative - cr_assert(!IS_ALIGNED(55, 16)); - cr_assert(!IS_ALIGNED(55, 55)); - cr_assert(!IS_ALIGNED(1128, 256)); + // Negative + cr_assert(!IS_ALIGNED(55, 16)); + cr_assert(!IS_ALIGNED(55, 55)); + cr_assert(!IS_ALIGNED(1128, 256)); } -Test(utils, ceil) -{ - cr_assert_eq(CEIL(10, 3), 4); - cr_assert_eq(CEIL(10, 5), 2); - cr_assert_eq(CEIL(4, 3), 2); +Test(utils, ceil) { + cr_assert_eq(CEIL(10, 3), 4); + cr_assert_eq(CEIL(10, 5), 2); + cr_assert_eq(CEIL(4, 3), 2); } -Test(utils, is_pow2) -{ - // Positive - cr_assert(IS_POW2(1)); - cr_assert(IS_POW2(2)); - cr_assert(IS_POW2(64)); +Test(utils, is_pow2) { + // Positive + cr_assert(IS_POW2(1)); + cr_assert(IS_POW2(2)); + cr_assert(IS_POW2(64)); - // Negative - cr_assert(!IS_POW2(0)); - cr_assert(!IS_POW2(3)); - cr_assert(!IS_POW2(11111)); - cr_assert(!IS_POW2(-1)); + // Negative + cr_assert(!IS_POW2(0)); + cr_assert(!IS_POW2(3)); + cr_assert(!IS_POW2(11111)); + cr_assert(!IS_POW2(-1)); } -Test(utils, strf) -{ - char *buf = nullptr; +Test(utils, strf) { + char *buf = nullptr; - buf = strcatf(&buf, "Hallo %s", "Steffen."); - cr_assert_str_eq(buf, "Hallo Steffen."); + buf = strcatf(&buf, "Hallo %s", "Steffen."); + cr_assert_str_eq(buf, "Hallo Steffen."); - strcatf(&buf, " Its Monday %uth %s %u.", 13, "August", 2018); - cr_assert_str_eq(buf, "Hallo Steffen. Its Monday 13th August 2018."); + strcatf(&buf, " Its Monday %uth %s %u.", 13, "August", 2018); + cr_assert_str_eq(buf, "Hallo Steffen. Its Monday 13th August 2018."); - free(buf); + free(buf); } -Test(utils, version) -{ - using villas::utils::Version; +Test(utils, version) { + using villas::utils::Version; - Version v1 = Version("1.2"); - Version v2 = Version("1.3"); - Version v3 = Version("55"); - Version v4 = Version("66"); - Version v5 = Version(66); - Version v6 = Version(1, 2, 5); - Version v7 = Version("1.2.5"); + Version v1 = Version("1.2"); + Version v2 = Version("1.3"); + Version v3 = Version("55"); + Version v4 = Version("66"); + Version v5 = Version(66); + Version v6 = Version(1, 2, 5); + Version v7 = Version("1.2.5"); - cr_assert_lt(v1, v2); - cr_assert_eq(v1, v1); - cr_assert_gt(v2, v1); - cr_assert_lt(v3, v4); - cr_assert_eq(v4, v5); - cr_assert_eq(v6, v7); + cr_assert_lt(v1, v2); + cr_assert_eq(v1, v1); + cr_assert_gt(v2, v1); + cr_assert_lt(v3, v4); + cr_assert_eq(v4, v5); + cr_assert_eq(v6, v7); } -Test(utils, sha1sum) -{ - int ret; - FILE *f = tmpfile(); +Test(utils, sha1sum) { + int ret; + FILE *f = tmpfile(); - unsigned char hash[SHA_DIGEST_LENGTH]; - unsigned char expected[SHA_DIGEST_LENGTH] = { 0x69, 0xdf, 0x29, 0xdf, 0x1f, 0xf2, 0xd2, 0x5d, 0xb8, 0x68, 0x6c, 0x02, 0x8d, 0xdf, 0x40, 0xaf, 0xb3, 0xc1, 0xc9, 0x4d }; + unsigned char hash[SHA_DIGEST_LENGTH]; + unsigned char expected[SHA_DIGEST_LENGTH] = { + 0x69, 0xdf, 0x29, 0xdf, 0x1f, 0xf2, 0xd2, 0x5d, 0xb8, 0x68, + 0x6c, 0x02, 0x8d, 0xdf, 0x40, 0xaf, 0xb3, 0xc1, 0xc9, 0x4d}; - // Write the first 512 fibonaccia numbers to the file - for (int i = 0, a = 0, b = 1, c; i < 512; i++, a = b, b = c) { - c = a + b; + // Write the first 512 fibonaccia numbers to the file + for (int i = 0, a = 0, b = 1, c; i < 512; i++, a = b, b = c) { + c = a + b; - fwrite((void *) &c, sizeof(c), 1, f); - } + fwrite((void *)&c, sizeof(c), 1, f); + } - ret = sha1sum(f, hash); + ret = sha1sum(f, hash); - cr_assert_eq(ret, 0); - cr_assert_arr_eq(hash, expected, SHA_DIGEST_LENGTH); + cr_assert_eq(ret, 0); + cr_assert_arr_eq(hash, expected, SHA_DIGEST_LENGTH); - fclose(f); + fclose(f); } -Test(utils, decolor) -{ - char str[] = "This " CLR_RED("is") " a " CLR_BLU("colored") " " CLR_BLD("text!"); - char expect[] = "This is a colored text!"; +Test(utils, decolor) { + char str[] = + "This " CLR_RED("is") " a " CLR_BLU("colored") " " CLR_BLD("text!"); + char expect[] = "This is a colored text!"; - decolor(str); + decolor(str); - cr_assert_str_eq(str, expect); + cr_assert_str_eq(str, expect); }