Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions src/native/corehost/hostmisc/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "trace.h"
#include <mutex>
#include <thread>

// g_trace_verbosity is used to encode COREHOST_TRACE and COREHOST_TRACE_VERBOSITY to selectively control output of
// trace::warn(), trace::info(), and trace::verbose()
Expand All @@ -13,9 +14,39 @@
// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=1 implies g_trace_verbosity = 1. // Trace "enabled". error() messages will be produced
static int g_trace_verbosity = 0;
static FILE * g_trace_file = stderr;
static pal::mutex_t g_trace_mutex;
thread_local static trace::error_writer_fn g_error_writer = nullptr;

namespace
{
class spin_lock
{
public:
spin_lock() = default;
spin_lock(const spin_lock&) = delete;
spin_lock& operator=(const spin_lock&) = delete;

void lock()
{
uint32_t spin = 0;
while (flag.test_and_set(std::memory_order_acquire))
{
if (spin++ % 1024 == 0)
std::this_thread::yield();
}
}

void unlock()
{
flag.clear(std::memory_order_release);
}

private:
std::atomic_flag flag = ATOMIC_FLAG_INIT;
};

spin_lock g_trace_lock;
}

//
// Turn on tracing for the corehost based on "COREHOST_TRACE" & "COREHOST_TRACEFILE" env.
//
Expand Down Expand Up @@ -50,7 +81,7 @@ bool trace::enable()
}
else
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

g_trace_file = stderr;
if (pal::getenv(_X("COREHOST_TRACEFILE"), &tracefile_str))
Expand Down Expand Up @@ -95,7 +126,7 @@ void trace::verbose(const pal::char_t* format, ...)
{
if (g_trace_verbosity > 3)
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

va_list args;
va_start(args, format);
Expand All @@ -108,7 +139,7 @@ void trace::info(const pal::char_t* format, ...)
{
if (g_trace_verbosity > 2)
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

va_list args;
va_start(args, format);
Expand All @@ -119,7 +150,7 @@ void trace::info(const pal::char_t* format, ...)

void trace::error(const pal::char_t* format, ...)
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

// Always print errors
va_list args;
Expand Down Expand Up @@ -156,7 +187,7 @@ void trace::error(const pal::char_t* format, ...)

void trace::println(const pal::char_t* format, ...)
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

va_list args;
va_start(args, format);
Expand All @@ -173,7 +204,7 @@ void trace::warning(const pal::char_t* format, ...)
{
if (g_trace_verbosity > 1)
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

va_list args;
va_start(args, format);
Expand All @@ -184,7 +215,7 @@ void trace::warning(const pal::char_t* format, ...)

void trace::flush()
{
std::lock_guard<pal::mutex_t> lock(g_trace_mutex);
std::lock_guard<spin_lock> lock(g_trace_lock);

pal::file_flush(g_trace_file);
pal::err_flush();
Expand Down