/** * Copyright 2013-2022 Software Radio Systems Limited * * This file is part of srsRAN. * * srsRAN is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * srsRAN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * A copy of the GNU Affero General Public License can be found in * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * */ #ifndef SRSRAN_TIME_PROF_H #define SRSRAN_TIME_PROF_H #include "srsran/srslog/srslog.h" #include #include #ifdef ENABLE_TIMEPROF #define TPROF_ENABLE_DEFAULT true #else #define TPROF_ENABLE_DEFAULT false #endif namespace srsran { // individual time interval measure class tprof_measure { public: using tpoint = std::chrono::time_point; tprof_measure() = default; void start() { t1 = std::chrono::high_resolution_clock::now(); } std::chrono::nanoseconds stop() { auto t2 = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast(t2 - t1); } private: tpoint t1; }; template class tprof { public: template explicit tprof(Args&&... args) : prof(std::forward(args)...) {} void start() { meas.start(); } std::chrono::nanoseconds stop() { auto d = meas.stop(); prof(d); return d; } tprof_measure meas; Prof prof; }; // specialization for when the tprof is disabled template class tprof { public: template explicit tprof(Args&&... args) {} void start() {} std::chrono::nanoseconds stop() { return std::chrono::nanoseconds{0}; } }; template struct mutexed_tprof { struct measure { public: explicit measure(mutexed_tprof* h_) : h(h_) { meas.start(); } ~measure() { if (deferred) { stop(); } } std::chrono::nanoseconds stop() { auto d = meas.stop(); std::lock_guard lock(h->mutex); h->prof(d); return d; } void defer_stop() { deferred = true; } tprof_measure meas; mutexed_tprof* h; bool deferred = false; }; template explicit mutexed_tprof(Args&&... args) : prof(std::forward(args)...) {} measure start() { return measure{this}; } Prof prof; private: std::mutex mutex; }; template struct mutexed_tprof { struct measure { public: std::chrono::nanoseconds stop() { return std::chrono::nanoseconds{0}; } void defer_stop() {} }; template explicit mutexed_tprof(Args&&... args) {} measure start() { return measure{}; } }; struct avg_time_stats { avg_time_stats(const char* name_, const char* logname, size_t print_period_); void operator()(std::chrono::nanoseconds duration); srslog::basic_logger& logger; std::string name; double avg_val = 1; long count = 0, max_val = 0, min_val = std::numeric_limits::max(); long print_period = 0; }; template class sliding_window_stats { public: sliding_window_stats(const char* name_, const char* logname, size_t print_period_ = 10); void operator()(std::chrono::nanoseconds duration); srslog::basic_logger& logger; std::string name; std::vector sliding_window; size_t window_idx = 0; }; using sliding_window_stats_ms = sliding_window_stats; } // namespace srsran #endif // SRSRAN_TIME_PROF_H