From a474a0f2935257ccfa46dc483ca5a48953a9ab36 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 13 Apr 2021 14:01:55 +0200 Subject: [PATCH] SRSLOG: Avoid calling unordered_map::emplace if element already exists since it will allocate even if the insertion is not going to take place. --- lib/include/srsran/srslog/srslog.h | 3 + lib/src/srslog/srslog.cpp | 179 ++++++++++++++--------------- 2 files changed, 88 insertions(+), 94 deletions(-) diff --git a/lib/include/srsran/srslog/srslog.h b/lib/include/srsran/srslog/srslog.h index 6dd9ec077..299c52b26 100644 --- a/lib/include/srsran/srslog/srslog.h +++ b/lib/include/srsran/srslog/srslog.h @@ -98,6 +98,9 @@ template inline T& fetch_logger(const std::string& id, Args&&... args) { static_assert(detail::is_logger::value, "T should be a logger type"); + if (auto *logger = find_logger(id)) { + return *logger; + } auto logger = detail::make_any(id, std::forward(args)...); detail::any* p = detail::fetch_logger(id, std::move(logger)); diff --git a/lib/src/srslog/srslog.cpp b/lib/src/srslog/srslog.cpp index c349c0318..a53dc92db 100644 --- a/lib/src/srslog/srslog.cpp +++ b/lib/src/srslog/srslog.cpp @@ -28,13 +28,10 @@ static std::string remove_sharp_chars(const std::string& s) /// Generic argument function that fetches a log channel from the repository. template -static log_channel& fetch_log_channel_helper(const std::string& id, - Args&&... args) +static log_channel& fetch_log_channel_helper(const std::string& id, Args&&... args) { return srslog_instance::get().get_channel_repo().emplace( - std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(id, std::forward(args)...)); + std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(id, std::forward(args)...)); } /// @@ -51,21 +48,27 @@ log_channel& srslog::fetch_log_channel(const std::string& id) assert(!id.empty() && "Empty id string"); std::string clean_id = remove_sharp_chars(id); + + if (auto* c = find_log_channel(clean_id)) { + return *c; + } + srslog_instance& instance = srslog_instance::get(); - return fetch_log_channel_helper( - clean_id, instance.get_default_sink(), instance.get_backend()); + return fetch_log_channel_helper(clean_id, instance.get_default_sink(), instance.get_backend()); } -log_channel& srslog::fetch_log_channel(const std::string& id, - sink& s, - log_channel_config config) +log_channel& srslog::fetch_log_channel(const std::string& id, sink& s, log_channel_config config) { assert(!id.empty() && "Empty id string"); std::string clean_id = remove_sharp_chars(id); + + if (auto* c = find_log_channel(clean_id)) { + return *c; + } + srslog_instance& instance = srslog_instance::get(); - return fetch_log_channel_helper( - clean_id, s, instance.get_backend(), std::move(config)); + return fetch_log_channel_helper(clean_id, s, instance.get_backend(), std::move(config)); } /// @@ -112,40 +115,46 @@ sink* srslog::find_sink(const std::string& id) return (ptr) ? ptr->get() : nullptr; } -sink& srslog::fetch_stdout_sink(const std::string& id, - std::unique_ptr f) +sink& srslog::fetch_stdout_sink(const std::string& id, std::unique_ptr f) { assert(!id.empty() && "Empty id string"); + if (auto* s = find_sink(id)) { + return *s; + } + auto& s = srslog_instance::get().get_sink_repo().emplace( std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple( - new stream_sink(sink_stream_type::stdout, std::move(f)))); + std::forward_as_tuple(new stream_sink(sink_stream_type::stdout, std::move(f)))); return *s; } -sink& srslog::fetch_stderr_sink(const std::string& id, - std::unique_ptr f) +sink& srslog::fetch_stderr_sink(const std::string& id, std::unique_ptr f) { assert(!id.empty() && "Empty id string"); + if (auto* s = find_sink(id)) { + return *s; + } + auto& s = srslog_instance::get().get_sink_repo().emplace( std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple( - new stream_sink(sink_stream_type::stderr, std::move(f)))); + std::forward_as_tuple(new stream_sink(sink_stream_type::stderr, std::move(f)))); return *s; } -sink& srslog::fetch_file_sink(const std::string& path, - size_t max_size, - std::unique_ptr f) +sink& srslog::fetch_file_sink(const std::string& path, size_t max_size, std::unique_ptr f) { assert(!path.empty() && "Empty path string"); + if (auto* s = find_sink(path)) { + return *s; + } + //:TODO: GCC5 or lower versions emits an error if we use the new() expression // directly, use redundant piecewise_construct instead. auto& s = srslog_instance::get().get_sink_repo().emplace( @@ -160,9 +169,8 @@ bool srslog::install_custom_sink(const std::string& id, std::unique_ptr s) { assert(!id.empty() && "Empty path string"); - sink* input_sink = s.get(); - sink* returned_sink = - srslog_instance::get().get_sink_repo().emplace(id, std::move(s)).get(); + sink* input_sink = s.get(); + sink* returned_sink = srslog_instance::get().get_sink_repo().emplace(id, std::move(s)).get(); // Successful insertion occurs when the returned object is the same one as the // input object. @@ -190,7 +198,7 @@ void srslog::flush() // The backend will set this shared variable when done. detail::shared_variable completion_flag(false); - auto sink_ptrs = instance.get_sink_repo().contents(); + auto sink_ptrs = instance.get_sink_repo().contents(); std::vector sinks; sinks.reserve(sink_ptrs.size()); for (const auto& s : sink_ptrs) { @@ -199,8 +207,8 @@ void srslog::flush() detail::log_entry cmd; cmd.metadata.store = nullptr; - cmd.flush_cmd = std::unique_ptr( - new detail::flush_backend_cmd{completion_flag, std::move(sinks)}); + cmd.flush_cmd = + std::unique_ptr(new detail::flush_backend_cmd{completion_flag, std::move(sinks)}); // Make sure the flush command gets into the backend, otherwise we will be // stuck waiting forever for the command to succeed. @@ -227,12 +235,10 @@ detail::any* srslog::detail::find_logger(const std::string& id) return srslog_instance::get().get_logger_repo().find(id); } -detail::any* srslog::detail::fetch_logger(const std::string& id, - detail::any&& logger) +detail::any* srslog::detail::fetch_logger(const std::string& id, detail::any&& logger) { assert(!id.empty() && "Empty id string"); - return &srslog_instance::get().get_logger_repo().emplace(id, - std::move(logger)); + return &srslog_instance::get().get_logger_repo().emplace(id, std::move(logger)); } /// Builds a logger name out of the id and tag. @@ -242,9 +248,7 @@ static std::string build_logger_name(const std::string& id, char tag) } /// Fetches a logger with all its log channels. -static basic_logger& fetch_basic_logger_helper(const std::string& id, - sink& s, - bool should_print_context) +static basic_logger& fetch_basic_logger_helper(const std::string& id, sink& s, bool should_print_context) { static constexpr char basic_logger_chan_tags[] = {'E', 'W', 'I', 'D'}; @@ -253,43 +257,48 @@ static basic_logger& fetch_basic_logger_helper(const std::string& id, // User created log channels cannot have ids with a # character, encode the // ids here with a # to ensure all channels are unique. - log_channel& error = fetch_log_channel_helper( - build_logger_name(id, basic_logger_chan_tags[0]), - s, - instance.get_backend(), - log_channel_config{id, basic_logger_chan_tags[0], should_print_context}); - log_channel& warning = fetch_log_channel_helper( - build_logger_name(id, basic_logger_chan_tags[1]), - s, - instance.get_backend(), - log_channel_config{id, basic_logger_chan_tags[1], should_print_context}); - log_channel& info = fetch_log_channel_helper( - build_logger_name(id, basic_logger_chan_tags[2]), - s, - instance.get_backend(), - log_channel_config{id, basic_logger_chan_tags[2], should_print_context}); - log_channel& debug = fetch_log_channel_helper( - build_logger_name(id, basic_logger_chan_tags[3]), - s, - instance.get_backend(), - log_channel_config{id, basic_logger_chan_tags[3], should_print_context}); + log_channel& error = + fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[0]), + s, + instance.get_backend(), + log_channel_config{id, basic_logger_chan_tags[0], should_print_context}); + log_channel& warning = + fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[1]), + s, + instance.get_backend(), + log_channel_config{id, basic_logger_chan_tags[1], should_print_context}); + log_channel& info = fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[2]), + s, + instance.get_backend(), + log_channel_config{id, basic_logger_chan_tags[2], should_print_context}); + log_channel& debug = + fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[3]), + s, + instance.get_backend(), + log_channel_config{id, basic_logger_chan_tags[3], should_print_context}); return fetch_logger(id, error, warning, info, debug); } -basic_logger& srslog::fetch_basic_logger(const std::string& id, - bool should_print_context) +basic_logger& srslog::fetch_basic_logger(const std::string& id, bool should_print_context) { assert(!id.empty() && "Empty id string"); - return fetch_basic_logger_helper( - id, srslog_instance::get().get_default_sink(), should_print_context); + + if (auto* logger = find_logger(id)) { + return *logger; + } + + return fetch_basic_logger_helper(id, srslog_instance::get().get_default_sink(), should_print_context); } -basic_logger& srslog::fetch_basic_logger(const std::string& id, - sink& s, - bool should_print_context) +basic_logger& srslog::fetch_basic_logger(const std::string& id, sink& s, bool should_print_context) { assert(!id.empty() && "Empty id string"); + + if (auto* logger = find_logger(id)) { + return *logger; + } + return fetch_basic_logger_helper(id, s, should_print_context); } @@ -299,33 +308,28 @@ basic_logger& srslog::fetch_basic_logger(const std::string& id, /// Creates and registers a log channel. Returns a pointer to the newly created /// channel on success, otherwise nullptr. -static log_channel* create_and_register_log_channel(const std::string& id, - sink& s) +static log_channel* create_and_register_log_channel(const std::string& id, sink& s) { assert(!id.empty() && "Empty id string"); srslog_instance& instance = srslog_instance::get(); auto& p = instance.get_channel_repo().emplace( - std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(id, s, instance.get_backend())); + std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(id, s, instance.get_backend())); return &p; } -static log_channel* create_and_register_log_channel(const std::string& id, - log_channel_config config, - sink& s) +static log_channel* create_and_register_log_channel(const std::string& id, log_channel_config config, sink& s) { assert(!id.empty() && "Empty id string"); srslog_instance& instance = srslog_instance::get(); - auto& p = instance.get_channel_repo().emplace( - std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(id, s, instance.get_backend(), std::move(config))); + auto& p = + instance.get_channel_repo().emplace(std::piecewise_construct, + std::forward_as_tuple(id), + std::forward_as_tuple(id, s, instance.get_backend(), std::move(config))); return &p; } @@ -364,16 +368,11 @@ sink* srslog::create_file_sink(const std::string& path, size_t max_size) .get_sink_repo() .emplace(std::piecewise_construct, std::forward_as_tuple(path), - std::forward_as_tuple(new file_sink( - path, - max_size, - std::unique_ptr(new text_formatter)))) + std::forward_as_tuple(new file_sink(path, max_size, std::unique_ptr(new text_formatter)))) .get(); } -basic_logger* srslog::create_basic_logger(const std::string& id, - sink& s, - bool should_print_context) +basic_logger* srslog::create_basic_logger(const std::string& id, sink& s, bool should_print_context) { assert(!id.empty() && "Empty id string"); @@ -391,24 +390,16 @@ basic_logger* srslog::create_basic_logger(const std::string& id, // without any id clashes. log_channel* error = create_and_register_log_channel( - build_logger_name(id, basic_logger_chan_tags[0]), - {id, basic_logger_chan_tags[0], should_print_context}, - s); + build_logger_name(id, basic_logger_chan_tags[0]), {id, basic_logger_chan_tags[0], should_print_context}, s); assert(error && "Could not create channel"); log_channel* warning = create_and_register_log_channel( - build_logger_name(id, basic_logger_chan_tags[1]), - {id, basic_logger_chan_tags[1], should_print_context}, - s); + build_logger_name(id, basic_logger_chan_tags[1]), {id, basic_logger_chan_tags[1], should_print_context}, s); assert(warning && "Could not create channel"); log_channel* info = create_and_register_log_channel( - build_logger_name(id, basic_logger_chan_tags[2]), - {id, basic_logger_chan_tags[2], should_print_context}, - s); + build_logger_name(id, basic_logger_chan_tags[2]), {id, basic_logger_chan_tags[2], should_print_context}, s); assert(info && "Could not create channel"); log_channel* debug = create_and_register_log_channel( - build_logger_name(id, basic_logger_chan_tags[3]), - {id, basic_logger_chan_tags[3], should_print_context}, - s); + build_logger_name(id, basic_logger_chan_tags[3]), {id, basic_logger_chan_tags[3], should_print_context}, s); assert(debug && "Could not create channel"); return create_logger(id, *error, *warning, *info, *debug);