diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index e764578ec..8cace8526 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -140,7 +140,8 @@ Cpu_job & Cpu::schedule() _scheduler.update(_timer.time()); time_t t = _scheduler.head_quota(); _timer.set_timeout(this, t); - _timer.schedule_timeout(); + time_t duration = _timer.schedule_timeout(); + old_job.update_execution_time(duration); } /* return new job */ diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 409a77557..531884b17 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -178,6 +178,11 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout Inter_processor_work_list & work_list() { return _local_work_list; } + + /** + * Return CPU's idle thread object + */ + Kernel::Thread &idle_thread() { return _idle; } }; diff --git a/repos/base-hw/src/core/kernel/cpu_context.h b/repos/base-hw/src/core/kernel/cpu_context.h index aaf5384a5..a9ecc262e 100644 --- a/repos/base-hw/src/core/kernel/cpu_context.h +++ b/repos/base-hw/src/core/kernel/cpu_context.h @@ -35,6 +35,8 @@ class Kernel::Cpu_job : private Cpu_share friend class Cpu; /* static_cast from 'Cpu_share' to 'Cpu_job' */ + time_t _execution_time { 0 }; + /* * Noncopyable */ @@ -112,6 +114,16 @@ class Kernel::Cpu_job : private Cpu_share */ bool own_share_active() { return Cpu_share::ready(); } + /** + * Update total execution time + */ + void update_execution_time(time_t duration) { _execution_time += duration; } + + /** + * Return total execution time + */ + time_t execution_time() const { return _execution_time; } + /*************** ** Accessors ** diff --git a/repos/base-hw/src/core/kernel/timer.cc b/repos/base-hw/src/core/kernel/timer.cc index 6854135fe..ffc153626 100644 --- a/repos/base-hw/src/core/kernel/timer.cc +++ b/repos/base-hw/src/core/kernel/timer.cc @@ -60,16 +60,19 @@ void Timer::set_timeout(Timeout * const timeout, time_t const duration) } -void Timer::schedule_timeout() +time_t Timer::schedule_timeout() { /* get the timeout with the nearest end time */ Timeout * timeout = _timeout_list.first(); assert(timeout); /* install timeout at timer hardware */ - _time += _duration(); + time_t duration = _duration(); + _time += duration; _last_timeout_duration = (timeout->_end > _time) ? timeout->_end - _time : 1; _start_one_shot(_last_timeout_duration); + + return duration; } diff --git a/repos/base-hw/src/core/kernel/timer.h b/repos/base-hw/src/core/kernel/timer.h index e6e9455e5..1f7348c75 100644 --- a/repos/base-hw/src/core/kernel/timer.h +++ b/repos/base-hw/src/core/kernel/timer.h @@ -91,7 +91,10 @@ class Kernel::Timer Timer(Cpu & cpu); - void schedule_timeout(); + /** + * Return duration from last call of this function + */ + time_t schedule_timeout(); void process_timeouts(); diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 46520f1f2..bbdc5a41b 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -12,8 +12,6 @@ * under the terms of the GNU Affero General Public License version 3. */ -/* Genode includes */ -#include /* core includes */ #include @@ -32,6 +30,10 @@ #include #include +/* Genode includes */ +#include +#include + using namespace Genode; @@ -205,6 +207,40 @@ Platform::Platform() init_core_log(Core_log_range { core_local_addr, log_size } ); } + struct Trace_source : public Trace::Source::Info_accessor, + private Trace::Control, + private Trace::Source + { + Kernel::Thread &thread; + Affinity::Location const affinity; + + /** + * Trace::Source::Info_accessor interface + */ + Info trace_source_info() const override + { + Trace::Execution_time execution_time { thread.execution_time(), 0 }; + return { Session_label("kernel"), thread.label(), execution_time, + affinity }; + } + + Trace_source(Trace::Source_registry ®istry, + Kernel::Thread &thread, Affinity::Location affinity) + : + Trace::Control(), + Trace::Source(*this, *this), + thread(thread), affinity(affinity) + { + registry.insert(this); + } + }; + + /* create trace sources for idle threads */ + Kernel::cpu_pool().for_each_cpu([&] (Kernel::Cpu & cpu) { + new (core_mem_alloc()) Trace_source(Trace::sources(), cpu.idle_thread(), + Affinity::Location(cpu.id(), 0)); + }); + log(_rom_fs); } diff --git a/repos/base-hw/src/core/platform_thread.h b/repos/base-hw/src/core/platform_thread.h index 70a1b4e1a..921cef46d 100644 --- a/repos/base-hw/src/core/platform_thread.h +++ b/repos/base-hw/src/core/platform_thread.h @@ -208,8 +208,11 @@ namespace Genode { /** * Return execution time consumed by the thread */ - Trace::Execution_time execution_time() const { - return { 0, 0, _quota, _priority }; } + Trace::Execution_time execution_time() const + { + Genode::uint64_t execution_time = + const_cast(this)->_kobj->execution_time(); + return { execution_time, 0, _quota, _priority }; } /***************