diff --git a/core/trace.cc b/core/trace.cc index 68b843738a9a90e4712da16ef43baacaedebefc8..0d1987360264ca586b79a44733224a93b7aceb78 100644 --- a/core/trace.cc +++ b/core/trace.cc @@ -7,6 +7,7 @@ #include "osv/trace.hh" #include <osv/sched.hh> +#include <osv/mutex.h> #include "arch.hh" #include <atomic> #include <regex> @@ -116,11 +117,20 @@ void enable_trace() trace_enabled = true; } -void enable_tracepoint(std::string wildcard) +void ensure_log_initialized() { - static bool buffers_initialized; + static std::mutex _mutex; + static std::atomic<bool> buffers_initialized; + + if (buffers_initialized.load(std::memory_order_acquire)) { + return; + } + + WITH_LOCK(_mutex) { + if (buffers_initialized.load(std::memory_order_relaxed)) { + return; + } - if (!buffers_initialized) { // Ensure we're using power of two sizes * trace_page_size, so round num cpus to ^2 const size_t ncpu = 1 << size_t(ilog2_roundup(sched::cpus.size())); // TODO: examine these defaults. I'm guessing less than 256*mt sized buffers @@ -130,8 +140,13 @@ void enable_tracepoint(std::string wildcard) auto * tbp = percpu_trace_buffer.for_cpu(c); *tbp = trace_buf(size); } - buffers_initialized = true; + + buffers_initialized.store(true, std::memory_order_release); } +} + +void enable_tracepoint(std::string wildcard) +{ wildcard = boost::algorithm::replace_all_copy(wildcard, std::string("*"), std::string(".*")); wildcard = boost::algorithm::replace_all_copy(wildcard, std::string("?"), std::string(".")); std::regex re{wildcard}; @@ -179,6 +194,7 @@ tracepoint_base::~tracepoint_base() void tracepoint_base::enable() { + ensure_log_initialized(); logging = true; update(); }