From 24eea0b653ee1c7a789d836423446e73dd4384c2 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Wed, 12 Jun 2019 17:47:11 +0200 Subject: [PATCH] base: add 'trace' function to base/log.h The 'Genode::trace' convenience function prints messages to Genode's trace buffer (if tracing is enabled). issue #3294 --- repos/base/include/base/log.h | 42 ++++++++++++++++++++++++++ repos/base/lib/symbols/ld | 5 ++- repos/base/src/lib/base/default_log.cc | 23 ++++++++++++++ repos/base/src/lib/base/log.cc | 17 +++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/repos/base/include/base/log.h b/repos/base/include/base/log.h index 9f07524b4..5519a2d37 100644 --- a/repos/base/include/base/log.h +++ b/repos/base/include/base/log.h @@ -16,11 +16,13 @@ #include #include +#include namespace Genode { class Log; class Raw; + class Trace_output; } @@ -101,6 +103,36 @@ class Genode::Raw }; +class Genode::Trace_output +{ + private: + + Lock _lock { }; + + Output &_output; + + void _acquire(); + void _release(); + + public: + + Trace_output(Output &output) : _output(output) { } + + template + void output(ARGS &&... args) + { + _acquire(); + Output::out_args(_output, args...); + _release(); + } + + /** + * Return component-global singleton instance of the 'Trace_output' + */ + static Trace_output &trace_output(); +}; + + namespace Genode { /** @@ -140,6 +172,16 @@ namespace Genode { */ template void raw(ARGS &&... args) { Raw::output(args...); } + + + /** + * Write 'args' to the trace buffer if tracing is enabled + * + * The message is prefixed with a timestamp value + */ + template + void trace(ARGS && ... args) { + Trace_output::trace_output().output(Trace::timestamp(), ": ", args...); } } #endif /* _INCLUDE__BASE__LOG_H_ */ diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index e406d3dbc..25b1a5d35 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -80,6 +80,9 @@ _ZN6Genode11Sliced_heapD1Ev T _ZN6Genode11Sliced_heapD2Ev T _ZN6Genode12Address_infoC1Em T _ZN6Genode12Address_infoC2Em T +_ZN6Genode12Trace_output12trace_outputEv T +_ZN6Genode12Trace_output8_acquireEv T +_ZN6Genode12Trace_output8_releaseEv T _ZN6Genode13Avl_node_base15_rotate_subtreeEPS0_bRNS0_6PolicyE T _ZN6Genode13Avl_node_base18_rebalance_subtreeEPS0_RNS0_6PolicyE T _ZN6Genode13Avl_node_base6_adoptEPS0_bRNS0_6PolicyE T @@ -587,11 +590,11 @@ _ZThn8_N6Genode23Alarm_timeout_scheduler14handle_timeoutENS_8DurationE T _ZThn8_N6Genode23Alarm_timeout_schedulerD0Ev T _ZThn8_N6Genode23Alarm_timeout_schedulerD1Ev T _ZdlPv W -_ZdlPvm W _ZdlPvPN6Genode11DeallocatorE T _ZdlPvPN6Genode9AllocatorE W _ZdlPvRN6Genode11DeallocatorE T _ZdlPvRN6Genode9AllocatorE W +_ZdlPvm W _ZnajPN6Genode9AllocatorE T _ZnajRN6Genode9AllocatorE T _ZnamPN6Genode9AllocatorE T diff --git a/repos/base/src/lib/base/default_log.cc b/repos/base/src/lib/base/default_log.cc index 90356c179..4da0808fb 100644 --- a/repos/base/src/lib/base/default_log.cc +++ b/repos/base/src/lib/base/default_log.cc @@ -62,6 +62,18 @@ Log &Log::log() } +static Trace_output *trace_ptr; + +Trace_output &Trace_output::trace_output() +{ + if (trace_ptr) + return *trace_ptr; + + raw("Error: Missing call of init_log"); + sleep_forever(); +} + + /** * Hook for support the 'fork' implementation of the noux libc backend */ @@ -95,5 +107,16 @@ void Genode::init_log(Parent &parent) unmanaged_singleton(Write_fn()); log_ptr = unmanaged_singleton(*buffered_log_output); + + /* enable trace back end */ + struct Write_trace_fn { void operator () (char const *s) { Thread::trace(s); } }; + + typedef Buffered_output + Buffered_trace_output; + + static Buffered_trace_output *buffered_trace_output = + unmanaged_singleton(Write_trace_fn()); + + trace_ptr = unmanaged_singleton(*buffered_trace_output); } diff --git a/repos/base/src/lib/base/log.cc b/repos/base/src/lib/base/log.cc index f0e30e0b4..90c77f214 100644 --- a/repos/base/src/lib/base/log.cc +++ b/repos/base/src/lib/base/log.cc @@ -59,3 +59,20 @@ void Raw::_release() */ _output().out_string("\033[0m\n"); } + + +void Trace_output::_acquire() +{ + _lock.lock(); +} + + +void Trace_output::_release() +{ + /* + * Add newline + */ + _output.out_string("\n"); + + _lock.unlock(); +}