trace: support more facets of execution time

- execution time per thread context
- execution time per scheduling context
- quantum and priority

Issue #3192
This commit is contained in:
Alexander Boettcher 2017-09-11 13:03:28 +02:00 committed by Christian Helmuth
parent 66f49e6c42
commit ae16edf1d6
21 changed files with 74 additions and 42 deletions

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <base/native_capability.h> #include <base/native_capability.h>
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/trace/types.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
@ -178,7 +179,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const { return 0; } Trace::Execution_time execution_time() const { return { 0, 0 }; }
/******************************* /*******************************

View File

@ -18,6 +18,7 @@
/* Genode includes */ /* Genode includes */
#include <base/native_capability.h> #include <base/native_capability.h>
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/trace/types.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
@ -193,7 +194,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const; Trace::Execution_time execution_time() const;
/******************************* /*******************************

View File

@ -35,11 +35,11 @@ namespace Fiasco {
using namespace Genode; using namespace Genode;
using namespace Fiasco; using namespace Fiasco;
unsigned long long Platform_thread::execution_time() const Trace::Execution_time Platform_thread::execution_time() const
{ {
Fiasco::l4_kernel_clock_t us = 0; Fiasco::l4_kernel_clock_t us = 0;
l4_thread_stats_time(_thread.local.data()->kcap(), &us); l4_thread_stats_time(_thread.local.data()->kcap(), &us);
return (unsigned long long)us; return { us, 0, 10000 /* quantum readable ?*/, _prio };
} }

View File

@ -51,8 +51,11 @@ Platform_thread::~Platform_thread()
} }
void Platform_thread::quota(size_t const quota) { void Platform_thread::quota(size_t const quota)
Kernel::thread_quota(_kobj.kernel_object(), quota); } {
_quota = quota;
Kernel::thread_quota(_kobj.kernel_object(), quota);
}
Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb) Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
@ -86,8 +89,10 @@ Platform_thread::Platform_thread(size_t const quota,
_pd(nullptr), _pd(nullptr),
_pager(nullptr), _pager(nullptr),
_utcb_pd_addr((Native_utcb *)utcb), _utcb_pd_addr((Native_utcb *)utcb),
_priority(_scale_priority(virt_prio)),
_quota(quota),
_main_thread(false), _main_thread(false),
_kobj(true, _priority(virt_prio), quota, _label.string()) _kobj(true, _priority, _quota, _label.string())
{ {
try { try {
_utcb = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED); _utcb = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED);

View File

@ -18,6 +18,7 @@
/* Genode includes */ /* Genode includes */
#include <base/ram_allocator.h> #include <base/ram_allocator.h>
#include <base/thread.h> #include <base/thread.h>
#include <base/trace/types.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/native_utcb.h> #include <base/internal/native_utcb.h>
@ -58,6 +59,8 @@ namespace Genode {
Native_utcb * _utcb_core_addr { }; /* UTCB addr in core */ Native_utcb * _utcb_core_addr { }; /* UTCB addr in core */
Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */ Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */
Ram_dataspace_capability _utcb { }; /* UTCB dataspace */ Ram_dataspace_capability _utcb { }; /* UTCB dataspace */
unsigned _priority {0};
unsigned _quota {0};
/* /*
* Wether this thread is the main thread of a program. * Wether this thread is the main thread of a program.
@ -83,7 +86,7 @@ namespace Genode {
*/ */
bool _attaches_utcb_by_itself(); bool _attaches_utcb_by_itself();
unsigned _priority(unsigned virt_prio) unsigned _scale_priority(unsigned virt_prio)
{ {
return Cpu_session::scale_priority(Kernel::Cpu_priority::MAX, return Cpu_session::scale_priority(Kernel::Cpu_priority::MAX,
virt_prio); virt_prio);
@ -205,7 +208,8 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const { return 0; } Trace::Execution_time execution_time() const {
return { 0, 0, _quota, _priority }; }
/*************** /***************

View File

@ -18,8 +18,9 @@
/* Genode includes */ /* Genode includes */
#include <base/thread_state.h> #include <base/thread_state.h>
#include <cpu_session/cpu_session.h> #include <base/trace/types.h>
#include <base/weak_ptr.h> #include <base/weak_ptr.h>
#include <cpu_session/cpu_session.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/server_socket_pair.h> #include <base/internal/server_socket_pair.h>
@ -175,7 +176,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const { return 0; } Trace::Execution_time execution_time() const { return { 0, 0 }; }
unsigned long pager_object_badge() const { return 0; } unsigned long pager_object_badge() const { return 0; }
}; };

View File

@ -19,6 +19,7 @@
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/thread.h> #include <base/thread.h>
#include <nova_native_cpu/nova_native_cpu.h> #include <nova_native_cpu/nova_native_cpu.h>
#include <base/trace/types.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/stack.h> #include <base/internal/stack.h>
@ -210,7 +211,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const; Trace::Execution_time execution_time() const;
}; };
} }

View File

@ -857,7 +857,7 @@ Platform::Platform()
", res=", res); ", res=", res);
return { Session_label("kernel"), Trace::Thread_name(name), return { Session_label("kernel"), Trace::Thread_name(name),
Trace::Execution_time(sc_time), affinity }; Trace::Execution_time(sc_time, sc_time), affinity };
} }
Trace_source(Trace::Source_registry &registry, Trace_source(Trace::Source_registry &registry,
@ -909,7 +909,7 @@ Platform::Platform()
} }
return { Session_label("core"), name, return { Session_label("core"), name,
Trace::Execution_time(sc_time), location }; Trace::Execution_time(sc_time, sc_time), location };
} }
Core_trace_source(Trace::Source_registry &registry, Core_trace_source(Trace::Source_registry &registry,

View File

@ -297,19 +297,19 @@ const char * Platform_thread::pd_name() const {
return _pd ? _pd->name() : "unknown"; } return _pd ? _pd->name() : "unknown"; }
unsigned long long Platform_thread::execution_time() const Trace::Execution_time Platform_thread::execution_time() const
{ {
unsigned long long time = 0; unsigned long long time = 0;
/* for ECs without a SC we simply return 0 */ /* for ECs without a SC we simply return 0 */
if (!sc_created()) if (!sc_created())
return time; return { time, time, Nova::Qpd::DEFAULT_QUANTUM, _priority };
uint8_t res = Nova::sc_ctrl(_sel_sc(), time); uint8_t res = Nova::sc_ctrl(_sel_sc(), time);
if (res != Nova::NOVA_OK) if (res != Nova::NOVA_OK)
warning("sc_ctrl failed res=", res); warning("sc_ctrl failed res=", res);
return time; return { time, time, Nova::Qpd::DEFAULT_QUANTUM, _priority };
} }

View File

@ -135,7 +135,7 @@ void Thread::start()
uint64_t sc_time = 0; uint64_t sc_time = 0;
return { Session_label("core"), thread.name(), return { Session_label("core"), thread.name(),
Trace::Execution_time(sc_time), thread._affinity }; Trace::Execution_time(sc_time, sc_time), thread._affinity };
} }
Core_trace_source(Trace::Source_registry &registry, Thread &t) Core_trace_source(Trace::Source_registry &registry, Thread &t)

View File

@ -16,6 +16,7 @@
/* Genode includes */ /* Genode includes */
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/trace/types.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
@ -175,7 +176,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const { return 0; } Trace::Execution_time execution_time() const { return { 0, 0 }; }
/***************************** /*****************************

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <base/native_capability.h> #include <base/native_capability.h>
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/trace/types.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
@ -188,7 +189,7 @@ namespace Genode {
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const { return 0; } Trace::Execution_time execution_time() const { return { 0, 0 }; }
/********************************** /**********************************

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <base/thread_state.h> #include <base/thread_state.h>
#include <util/string.h> #include <util/string.h>
#include <base/trace/types.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
@ -140,7 +141,7 @@ class Genode::Platform_thread : public List<Platform_thread>::Element
/** /**
* Return execution time consumed by the thread * Return execution time consumed by the thread
*/ */
unsigned long long execution_time() const; Trace::Execution_time execution_time() const;
/************************ /************************

View File

@ -586,9 +586,10 @@ Platform::Platform()
seL4_BenchmarkGetThreadUtilisation(tcb_sel.value()); seL4_BenchmarkGetThreadUtilisation(tcb_sel.value());
uint64_t execution_time = buf[BENCHMARK_IDLE_TCBCPU_UTILISATION]; uint64_t execution_time = buf[BENCHMARK_IDLE_TCBCPU_UTILISATION];
uint64_t sc_time = 0; /* not supported */
return { Session_label("kernel"), Trace::Thread_name("idle"), return { Session_label("kernel"), Trace::Thread_name("idle"),
Trace::Execution_time(execution_time), affinity }; Trace::Execution_time(execution_time, sc_time), affinity };
} }
Idle_trace_source(Trace::Source_registry &registry, Idle_trace_source(Trace::Source_registry &registry,

View File

@ -258,11 +258,11 @@ Platform_thread::~Platform_thread()
platform_specific().core_sel_alloc().free(_pager_obj_sel); platform_specific().core_sel_alloc().free(_pager_obj_sel);
} }
unsigned long long Platform_thread::execution_time() const Trace::Execution_time Platform_thread::execution_time() const
{ {
if (!Thread::myself() || !Thread::myself()->utcb()) { if (!Thread::myself() || !Thread::myself()->utcb()) {
error("don't know myself"); error("don't know myself");
return 0; return { 0, 0, 10000, _priority };
} }
Thread &myself = *Thread::myself(); Thread &myself = *Thread::myself();
@ -272,8 +272,9 @@ unsigned long long Platform_thread::execution_time() const
/* kernel puts execution time on ipc buffer of calling thread */ /* kernel puts execution time on ipc buffer of calling thread */
seL4_BenchmarkGetThreadUtilisation(_info.tcb_sel.value()); seL4_BenchmarkGetThreadUtilisation(_info.tcb_sel.value());
uint64_t const execution_time = values[BENCHMARK_TCB_UTILISATION]; uint64_t const ec_time = values[BENCHMARK_TCB_UTILISATION];
return execution_time; uint64_t const sc_time = 0; /* not supported */
return { ec_time, sc_time, 10000, _priority};
} }
void Platform_thread::setup_vcpu(Cap_sel ept, Cap_sel notification) void Platform_thread::setup_vcpu(Cap_sel ept, Cap_sel notification)

View File

@ -125,7 +125,7 @@ void Thread::start()
uint64_t const thread_time = buf[BENCHMARK_TCB_UTILISATION]; uint64_t const thread_time = buf[BENCHMARK_TCB_UTILISATION];
return { Session_label("core"), _thread.name(), return { Session_label("core"), _thread.name(),
Trace::Execution_time(thread_time), _thread._affinity }; Trace::Execution_time(thread_time, 0), _thread._affinity };
} }

View File

@ -17,6 +17,8 @@
/* Genode includes */ /* Genode includes */
#include <util/string.h> #include <util/string.h>
#include <base/affinity.h> #include <base/affinity.h>
#include <base/exception.h>
#include <base/fixed_stdint.h>
#include <base/session_label.h> #include <base/session_label.h>
namespace Genode { namespace Trace { namespace Genode { namespace Trace {
@ -77,10 +79,19 @@ struct Genode::Trace::Subject_id
*/ */
struct Genode::Trace::Execution_time struct Genode::Trace::Execution_time
{ {
unsigned long long value; uint64_t thread_context;
addr_t scheduling_context;
uint16_t quantum { 0 };
uint16_t priority { 0 };
Execution_time() : value(0) { } Execution_time() : thread_context(0), scheduling_context(0) { }
Execution_time(unsigned long long value) : value(value) { } Execution_time(uint64_t thread_context, uint64_t scheduling_context)
: thread_context(thread_context), scheduling_context(scheduling_context) { }
Execution_time(uint64_t thread_context, uint64_t scheduling_context,
unsigned quantum, unsigned priority)
: thread_context(thread_context), scheduling_context(scheduling_context),
quantum(quantum), priority(priority) { }
}; };
@ -112,7 +123,7 @@ class Genode::Trace::Subject_info
Thread_name _thread_name { }; Thread_name _thread_name { };
State _state { INVALID }; State _state { INVALID };
Policy_id _policy_id { 0 }; Policy_id _policy_id { 0 };
Execution_time _execution_time { 0 }; Execution_time _execution_time { 0, 0 };
Affinity::Location _affinity { }; Affinity::Location _affinity { };
public: public:

View File

@ -40,11 +40,11 @@ struct Trace_subject_registry
void update(Genode::Trace::Subject_info const &new_info) void update(Genode::Trace::Subject_info const &new_info)
{ {
if (new_info.execution_time().value < info.execution_time().value) if (new_info.execution_time().thread_context < info.execution_time().thread_context)
recent_execution_time = 0; recent_execution_time = 0;
else else
recent_execution_time = new_info.execution_time().value - recent_execution_time = new_info.execution_time().thread_context -
info.execution_time().value; info.execution_time().thread_context;
info = new_info; info = new_info;
} }

View File

@ -75,12 +75,12 @@ void Monitor::_update_info()
Trace::Subject_info const &info = Trace::Subject_info const &info =
_trace.subject_info(_subject_id); _trace.subject_info(_subject_id);
unsigned long long const last_execution_time = uint64_t const last_execution_time =
_info.execution_time().value; _info.execution_time().thread_context;
_info = info; _info = info;
_recent_exec_time = _recent_exec_time =
_info.execution_time().value - last_execution_time; _info.execution_time().thread_context - last_execution_time;
} }
catch (Trace::Nonexistent_subject) { warning("Cannot update subject info: Nonexistent_subject"); } catch (Trace::Nonexistent_subject) { warning("Cannot update subject info: Nonexistent_subject"); }
} }
@ -101,7 +101,7 @@ void Monitor::print(bool activity, bool affinity)
/* print subjects activity if desired */ /* print subjects activity if desired */
if (activity) if (activity)
log(" <activity total=\"", _info.execution_time().value, log(" <activity total=\"", _info.execution_time().thread_context,
"\" recent=\"", _recent_exec_time, "\" recent=\"", _recent_exec_time,
"\">"); "\">");

View File

@ -41,9 +41,9 @@ struct Trace_subject_registry
void update(Genode::Trace::Subject_info const &new_info) void update(Genode::Trace::Subject_info const &new_info)
{ {
unsigned long long const last_execution_time = info.execution_time().value; unsigned long long const last_execution_time = info.execution_time().thread_context;
info = new_info; info = new_info;
recent_execution_time = info.execution_time().value - last_execution_time; recent_execution_time = info.execution_time().thread_context - last_execution_time;
} }
}; };
@ -134,7 +134,7 @@ struct Trace_subject_registry
if (report_activity) if (report_activity)
xml.node("activity", [&] () { xml.node("activity", [&] () {
xml.attribute("total", e->info.execution_time().value); xml.attribute("total", e->info.execution_time().thread_context);
xml.attribute("recent", e->recent_execution_time); xml.attribute("recent", e->recent_execution_time);
}); });

View File

@ -273,7 +273,10 @@ struct Test_tracing
"name:\"", info.thread_name(), "\" " "name:\"", info.thread_name(), "\" "
"state:", state_name(info.state()), " " "state:", state_name(info.state()), " "
"policy:", info.policy_id().id, " " "policy:", info.policy_id().id, " "
"time:", info.execution_time().value); "thread context time:", info.execution_time().thread_context, " "
"scheduling context time:", info.execution_time().scheduling_context, " ",
"priority:", info.execution_time().priority, " ",
"quantum:", info.execution_time().quantum);
}; };
for_each_subject(subjects, num_subjects, print_info); for_each_subject(subjects, num_subjects, print_info);