mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 13:25:45 +02:00
trace: move BeesTrace and BeesNote into their own translation unit
This allows these components to be used by test executables without pulling in all of bees, and more rapidly iterate their code. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
6adaedeecd
commit
03532effed
@ -20,6 +20,7 @@ BEES_OBJS = \
|
||||
bees-resolve.o \
|
||||
bees-roots.o \
|
||||
bees-thread.o \
|
||||
bees-trace.o \
|
||||
bees-types.o \
|
||||
|
||||
ALL_OBJS = $(BEES_OBJS) $(PROGRAM_OBJS)
|
||||
|
154
src/bees-trace.cc
Normal file
154
src/bees-trace.cc
Normal file
@ -0,0 +1,154 @@
|
||||
#include "bees.h"
|
||||
|
||||
// tracing ----------------------------------------
|
||||
|
||||
int bees_log_level = 8;
|
||||
|
||||
thread_local BeesTracer *BeesTracer::tl_next_tracer = nullptr;
|
||||
thread_local bool BeesTracer::tl_first = true;
|
||||
thread_local bool BeesTracer::tl_silent = false;
|
||||
|
||||
BeesTracer::~BeesTracer()
|
||||
{
|
||||
if (!tl_silent && current_exception()) {
|
||||
if (tl_first) {
|
||||
BEESLOGNOTICE("--- BEGIN TRACE --- exception ---");
|
||||
tl_first = false;
|
||||
}
|
||||
try {
|
||||
m_func();
|
||||
} catch (exception &e) {
|
||||
BEESLOGNOTICE("Nested exception: " << e.what());
|
||||
} catch (...) {
|
||||
BEESLOGNOTICE("Nested exception ...");
|
||||
}
|
||||
if (!m_next_tracer) {
|
||||
BEESLOGNOTICE("--- END TRACE --- exception ---");
|
||||
}
|
||||
}
|
||||
tl_next_tracer = m_next_tracer;
|
||||
if (!m_next_tracer) {
|
||||
tl_silent = false;
|
||||
tl_first = true;
|
||||
}
|
||||
}
|
||||
|
||||
BeesTracer::BeesTracer(function<void()> f, bool silent) :
|
||||
m_func(f)
|
||||
{
|
||||
m_next_tracer = tl_next_tracer;
|
||||
tl_next_tracer = this;
|
||||
tl_silent = silent;
|
||||
}
|
||||
|
||||
void
|
||||
BeesTracer::trace_now()
|
||||
{
|
||||
BeesTracer *tp = tl_next_tracer;
|
||||
BEESLOGNOTICE("--- BEGIN TRACE ---");
|
||||
while (tp) {
|
||||
tp->m_func();
|
||||
tp = tp->m_next_tracer;
|
||||
}
|
||||
BEESLOGNOTICE("--- END TRACE ---");
|
||||
}
|
||||
|
||||
bool
|
||||
BeesTracer::get_silent()
|
||||
{
|
||||
return tl_silent;
|
||||
}
|
||||
|
||||
void
|
||||
BeesTracer::set_silent()
|
||||
{
|
||||
tl_silent = true;
|
||||
}
|
||||
|
||||
thread_local BeesNote *BeesNote::tl_next = nullptr;
|
||||
mutex BeesNote::s_mutex;
|
||||
map<pid_t, BeesNote*> BeesNote::s_status;
|
||||
thread_local string BeesNote::tl_name;
|
||||
|
||||
BeesNote::~BeesNote()
|
||||
{
|
||||
tl_next = m_prev;
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
if (tl_next) {
|
||||
s_status[crucible::gettid()] = tl_next;
|
||||
} else {
|
||||
s_status.erase(crucible::gettid());
|
||||
}
|
||||
}
|
||||
|
||||
BeesNote::BeesNote(function<void(ostream &os)> f) :
|
||||
m_func(f)
|
||||
{
|
||||
m_name = get_name();
|
||||
m_prev = tl_next;
|
||||
tl_next = this;
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
s_status[crucible::gettid()] = tl_next;
|
||||
}
|
||||
|
||||
void
|
||||
BeesNote::set_name(const string &name)
|
||||
{
|
||||
tl_name = name;
|
||||
catch_all([&]() {
|
||||
DIE_IF_MINUS_ERRNO(pthread_setname_np(pthread_self(), name.c_str()));
|
||||
});
|
||||
}
|
||||
|
||||
string
|
||||
BeesNote::get_name()
|
||||
{
|
||||
// Use explicit name if given
|
||||
if (!tl_name.empty()) {
|
||||
return tl_name;
|
||||
}
|
||||
|
||||
// Try a Task name. If there is one, return it, but do not
|
||||
// remember it. Each output message may be a different Task.
|
||||
// The current task is thread_local so we don't need to worry
|
||||
// about it being destroyed under us.
|
||||
auto current_task = Task::current_task();
|
||||
if (current_task) {
|
||||
return current_task.title();
|
||||
}
|
||||
|
||||
// OK try the pthread name next.
|
||||
char buf[24];
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
int err = pthread_getname_np(pthread_self(), buf, sizeof(buf));
|
||||
if (err) {
|
||||
return string("pthread_getname_np: ") + strerror(err);
|
||||
}
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
// thread_getname_np returns process name
|
||||
// ...by default? ...for the main thread?
|
||||
// ...except during exception handling?
|
||||
// ...randomly?
|
||||
return buf;
|
||||
}
|
||||
|
||||
BeesNote::ThreadStatusMap
|
||||
BeesNote::get_status()
|
||||
{
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
ThreadStatusMap rv;
|
||||
for (auto t : s_status) {
|
||||
ostringstream oss;
|
||||
if (!t.second->m_name.empty()) {
|
||||
oss << t.second->m_name << ": ";
|
||||
}
|
||||
if (t.second->m_timer.age() > BEES_TOO_LONG) {
|
||||
oss << "[" << t.second->m_timer << "s] ";
|
||||
}
|
||||
t.second->m_func(oss);
|
||||
rv[t.first] = oss.str();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
152
src/bees.cc
152
src/bees.cc
@ -31,164 +31,12 @@
|
||||
using namespace crucible;
|
||||
using namespace std;
|
||||
|
||||
int bees_log_level = 8;
|
||||
|
||||
void
|
||||
do_cmd_help(char *argv[])
|
||||
{
|
||||
fprintf(stderr, BEES_USAGE, argv[0]);
|
||||
}
|
||||
|
||||
// tracing ----------------------------------------
|
||||
|
||||
thread_local BeesTracer *BeesTracer::tl_next_tracer = nullptr;
|
||||
thread_local bool BeesTracer::tl_first = true;
|
||||
thread_local bool BeesTracer::tl_silent = false;
|
||||
|
||||
BeesTracer::~BeesTracer()
|
||||
{
|
||||
if (!tl_silent && current_exception()) {
|
||||
if (tl_first) {
|
||||
BEESLOGNOTICE("--- BEGIN TRACE --- exception ---");
|
||||
tl_first = false;
|
||||
}
|
||||
try {
|
||||
m_func();
|
||||
} catch (exception &e) {
|
||||
BEESLOGNOTICE("Nested exception: " << e.what());
|
||||
} catch (...) {
|
||||
BEESLOGNOTICE("Nested exception ...");
|
||||
}
|
||||
if (!m_next_tracer) {
|
||||
BEESLOGNOTICE("--- END TRACE --- exception ---");
|
||||
}
|
||||
}
|
||||
tl_next_tracer = m_next_tracer;
|
||||
if (!m_next_tracer) {
|
||||
tl_silent = false;
|
||||
tl_first = true;
|
||||
}
|
||||
}
|
||||
|
||||
BeesTracer::BeesTracer(function<void()> f, bool silent) :
|
||||
m_func(f)
|
||||
{
|
||||
m_next_tracer = tl_next_tracer;
|
||||
tl_next_tracer = this;
|
||||
tl_silent = silent;
|
||||
}
|
||||
|
||||
void
|
||||
BeesTracer::trace_now()
|
||||
{
|
||||
BeesTracer *tp = tl_next_tracer;
|
||||
BEESLOGNOTICE("--- BEGIN TRACE ---");
|
||||
while (tp) {
|
||||
tp->m_func();
|
||||
tp = tp->m_next_tracer;
|
||||
}
|
||||
BEESLOGNOTICE("--- END TRACE ---");
|
||||
}
|
||||
|
||||
bool
|
||||
BeesTracer::get_silent()
|
||||
{
|
||||
return tl_silent;
|
||||
}
|
||||
|
||||
void
|
||||
BeesTracer::set_silent()
|
||||
{
|
||||
tl_silent = true;
|
||||
}
|
||||
|
||||
thread_local BeesNote *BeesNote::tl_next = nullptr;
|
||||
mutex BeesNote::s_mutex;
|
||||
map<pid_t, BeesNote*> BeesNote::s_status;
|
||||
thread_local string BeesNote::tl_name;
|
||||
|
||||
BeesNote::~BeesNote()
|
||||
{
|
||||
tl_next = m_prev;
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
if (tl_next) {
|
||||
s_status[crucible::gettid()] = tl_next;
|
||||
} else {
|
||||
s_status.erase(crucible::gettid());
|
||||
}
|
||||
}
|
||||
|
||||
BeesNote::BeesNote(function<void(ostream &os)> f) :
|
||||
m_func(f)
|
||||
{
|
||||
m_name = get_name();
|
||||
m_prev = tl_next;
|
||||
tl_next = this;
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
s_status[crucible::gettid()] = tl_next;
|
||||
}
|
||||
|
||||
void
|
||||
BeesNote::set_name(const string &name)
|
||||
{
|
||||
tl_name = name;
|
||||
catch_all([&]() {
|
||||
DIE_IF_MINUS_ERRNO(pthread_setname_np(pthread_self(), name.c_str()));
|
||||
});
|
||||
}
|
||||
|
||||
string
|
||||
BeesNote::get_name()
|
||||
{
|
||||
// Use explicit name if given
|
||||
if (!tl_name.empty()) {
|
||||
return tl_name;
|
||||
}
|
||||
|
||||
// Try a Task name. If there is one, return it, but do not
|
||||
// remember it. Each output message may be a different Task.
|
||||
// The current task is thread_local so we don't need to worry
|
||||
// about it being destroyed under us.
|
||||
auto current_task = Task::current_task();
|
||||
if (current_task) {
|
||||
return current_task.title();
|
||||
}
|
||||
|
||||
// OK try the pthread name next.
|
||||
char buf[24];
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
int err = pthread_getname_np(pthread_self(), buf, sizeof(buf));
|
||||
if (err) {
|
||||
return string("pthread_getname_np: ") + strerror(err);
|
||||
}
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
// thread_getname_np returns process name
|
||||
// ...by default? ...for the main thread?
|
||||
// ...except during exception handling?
|
||||
// ...randomly?
|
||||
return buf;
|
||||
}
|
||||
|
||||
BeesNote::ThreadStatusMap
|
||||
BeesNote::get_status()
|
||||
{
|
||||
unique_lock<mutex> lock(s_mutex);
|
||||
ThreadStatusMap rv;
|
||||
for (auto t : s_status) {
|
||||
ostringstream oss;
|
||||
if (!t.second->m_name.empty()) {
|
||||
oss << t.second->m_name << ": ";
|
||||
}
|
||||
if (t.second->m_timer.age() > BEES_TOO_LONG) {
|
||||
oss << "[" << t.second->m_timer << "s] ";
|
||||
}
|
||||
t.second->m_func(oss);
|
||||
rv[t.first] = oss.str();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static inline helpers ----------------------------------------
|
||||
|
||||
string
|
||||
|
Loading…
x
Reference in New Issue
Block a user