mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-21 00:23:16 +00:00
Remove obsolete Trace::Session::subject_info RPC
Issue #3610 Fixes #4349
This commit is contained in:
@ -111,7 +111,7 @@ static void copy_msg_to_utcb(Msgbuf_base const &snd_msg, L4_Word_t local_name)
|
|||||||
uint8_t const num_msg_words = num_data_words + num_header_words;
|
uint8_t const num_msg_words = num_data_words + num_header_words;
|
||||||
|
|
||||||
if (num_msg_words >= L4_GetMessageRegisters()) {
|
if (num_msg_words >= L4_GetMessageRegisters()) {
|
||||||
raw("Message does not fit into UTCB message registers");
|
raw("Message does not fit into UTCB message registers, num_msg_words=", num_msg_words);
|
||||||
L4_LoadMR(0, 0);
|
L4_LoadMR(0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,9 +126,6 @@ struct Genode::Trace::Session_client : Genode::Rpc_client<Genode::Trace::Session
|
|||||||
void resume(Subject_id subject) override {
|
void resume(Subject_id subject) override {
|
||||||
call<Rpc_resume>(subject); }
|
call<Rpc_resume>(subject); }
|
||||||
|
|
||||||
Subject_info subject_info(Subject_id subject) override {
|
|
||||||
return call<Rpc_subject_info>(subject); }
|
|
||||||
|
|
||||||
Dataspace_capability buffer(Subject_id subject) override {
|
Dataspace_capability buffer(Subject_id subject) override {
|
||||||
return call<Rpc_buffer>(subject); }
|
return call<Rpc_buffer>(subject); }
|
||||||
|
|
||||||
|
@ -85,13 +85,6 @@ struct Genode::Trace::Session : Genode::Session
|
|||||||
*/
|
*/
|
||||||
virtual void resume(Subject_id) = 0;
|
virtual void resume(Subject_id) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain details about tracing subject
|
|
||||||
*
|
|
||||||
* \throw Nonexistent_subject
|
|
||||||
*/
|
|
||||||
virtual Subject_info subject_info(Subject_id) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain trace buffer of given subject
|
* Obtain trace buffer of given subject
|
||||||
*
|
*
|
||||||
@ -144,8 +137,6 @@ struct Genode::Trace::Session : Genode::Session
|
|||||||
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
|
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
|
||||||
GENODE_RPC_THROW(Rpc_subject_infos, size_t, subject_infos,
|
GENODE_RPC_THROW(Rpc_subject_infos, size_t, subject_infos,
|
||||||
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
|
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
|
||||||
GENODE_RPC_THROW(Rpc_subject_info, Subject_info, subject_info,
|
|
||||||
GENODE_TYPE_LIST(Nonexistent_subject), Subject_id);
|
|
||||||
GENODE_RPC_THROW(Rpc_buffer, Dataspace_capability, buffer,
|
GENODE_RPC_THROW(Rpc_buffer, Dataspace_capability, buffer,
|
||||||
GENODE_TYPE_LIST(Nonexistent_subject, Subject_not_traced),
|
GENODE_TYPE_LIST(Nonexistent_subject, Subject_not_traced),
|
||||||
Subject_id);
|
Subject_id);
|
||||||
@ -154,7 +145,7 @@ struct Genode::Trace::Session : Genode::Session
|
|||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_alloc_policy, Rpc_policy,
|
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_alloc_policy, Rpc_policy,
|
||||||
Rpc_unload_policy, Rpc_trace, Rpc_rule, Rpc_pause,
|
Rpc_unload_policy, Rpc_trace, Rpc_rule, Rpc_pause,
|
||||||
Rpc_resume, Rpc_subjects, Rpc_subject_info, Rpc_buffer,
|
Rpc_resume, Rpc_subjects, Rpc_buffer,
|
||||||
Rpc_free, Rpc_subject_infos);
|
Rpc_free, Rpc_subject_infos);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ class Genode::Trace::Session_component
|
|||||||
void rule(Session_label const &, Thread_name const &, Policy_id, size_t) override;
|
void rule(Session_label const &, Thread_name const &, Policy_id, size_t) override;
|
||||||
void pause(Subject_id) override;
|
void pause(Subject_id) override;
|
||||||
void resume(Subject_id) override;
|
void resume(Subject_id) override;
|
||||||
Subject_info subject_info(Subject_id) override;
|
|
||||||
Dataspace_capability buffer(Subject_id) override;
|
Dataspace_capability buffer(Subject_id) override;
|
||||||
void free(Subject_id) override;
|
void free(Subject_id) override;
|
||||||
};
|
};
|
||||||
|
@ -146,12 +146,6 @@ void Session_component::resume(Subject_id subject_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Subject_info Session_component::subject_info(Subject_id subject_id)
|
|
||||||
{
|
|
||||||
return _subjects.lookup_by_id(subject_id).info();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Dataspace_capability Session_component::buffer(Subject_id subject_id)
|
Dataspace_capability Session_component::buffer(Subject_id subject_id)
|
||||||
{
|
{
|
||||||
return _subjects.lookup_by_id(subject_id).buffer();
|
return _subjects.lookup_by_id(subject_id).buffer();
|
||||||
|
@ -65,7 +65,6 @@ struct Migrate
|
|||||||
Signal_handler<Migrate> timer_handler { env.ep(), *this,
|
Signal_handler<Migrate> timer_handler { env.ep(), *this,
|
||||||
&Migrate::check_traces };
|
&Migrate::check_traces };
|
||||||
|
|
||||||
Trace::Subject_id trace_id { };
|
|
||||||
Affinity::Location location { };
|
Affinity::Location location { };
|
||||||
unsigned loc_same { 0 };
|
unsigned loc_same { 0 };
|
||||||
unsigned loc_pos { 0 };
|
unsigned loc_pos { 0 };
|
||||||
@ -95,13 +94,12 @@ struct Migrate
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case LOOKUP_TRACE_ID:
|
case LOOKUP_TRACE_ID:
|
||||||
{
|
{
|
||||||
auto count = trace.for_each_subject_info([&](Trace::Subject_id const &id,
|
auto count = trace.for_each_subject_info([&](Trace::Subject_id const &,
|
||||||
Trace::Subject_info const &info)
|
Trace::Subject_info const &info)
|
||||||
{
|
{
|
||||||
if (info.thread_name() != "migrate")
|
if (info.thread_name() != "migrate")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
trace_id = id;
|
|
||||||
location = info.affinity();
|
location = info.affinity();
|
||||||
state = CHECK_AFFINITY;
|
state = CHECK_AFFINITY;
|
||||||
|
|
||||||
@ -116,7 +114,11 @@ struct Migrate
|
|||||||
}
|
}
|
||||||
case CHECK_AFFINITY:
|
case CHECK_AFFINITY:
|
||||||
{
|
{
|
||||||
Trace::Subject_info const info = trace.subject_info(trace_id);
|
trace.for_each_subject_info([&](Trace::Subject_id const &,
|
||||||
|
Trace::Subject_info const &info)
|
||||||
|
{
|
||||||
|
if (info.thread_name() != "migrate")
|
||||||
|
return;
|
||||||
|
|
||||||
loc_same ++;
|
loc_same ++;
|
||||||
|
|
||||||
@ -130,7 +132,7 @@ struct Migrate
|
|||||||
state = MIGRATE;
|
state = MIGRATE;
|
||||||
}
|
}
|
||||||
log ("[ep] .");
|
log ("[ep] .");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loc_same = 0;
|
loc_same = 0;
|
||||||
@ -142,6 +144,8 @@ struct Migrate
|
|||||||
test_rounds ++;
|
test_rounds ++;
|
||||||
if (test_rounds == 4)
|
if (test_rounds == 4)
|
||||||
log("--- test completed successfully ---");
|
log("--- test completed successfully ---");
|
||||||
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MIGRATE:
|
case MIGRATE:
|
||||||
|
@ -90,23 +90,22 @@ class Main
|
|||||||
_monitors_switch = !_monitors_switch;
|
_monitors_switch = !_monitors_switch;
|
||||||
|
|
||||||
/* update available subject IDs and iterate over them */
|
/* update available subject IDs and iterate over them */
|
||||||
try { _num_subjects = _trace.subjects(_subjects, MAX_SUBJECTS); }
|
_trace.for_each_subject_info([&] (Trace::Subject_id const id,
|
||||||
catch (Out_of_ram ) { warning("Cannot list subjects: Out_of_ram" ); return; }
|
Trace::Subject_info const &info) {
|
||||||
catch (Out_of_caps) { warning("Cannot list subjects: Out_of_caps"); return; }
|
|
||||||
for (unsigned i = 0; i < _num_subjects; i++) {
|
|
||||||
|
|
||||||
Trace::Subject_id const id = _subjects[i];
|
|
||||||
try {
|
try {
|
||||||
/* skip dead subjects */
|
/* skip dead subjects */
|
||||||
if (_trace.subject_info(id).state() == Trace::Subject_info::DEAD)
|
if (info.state() == Trace::Subject_info::DEAD)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
/* check if there is a matching policy in the XML config */
|
/* check if there is a matching policy in the XML config */
|
||||||
Session_policy session_policy = _session_policy(id);
|
Session_policy session_policy = _session_policy(info);
|
||||||
try {
|
try {
|
||||||
/* lookup monitor by subject ID */
|
/* lookup monitor by subject ID */
|
||||||
Monitor &monitor = old_monitors.find_by_subject_id(id);
|
Monitor &monitor = old_monitors.find_by_subject_id(id);
|
||||||
|
|
||||||
|
monitor.update_info(info);
|
||||||
|
|
||||||
/* move monitor from old to new tree */
|
/* move monitor from old to new tree */
|
||||||
old_monitors.remove(&monitor);
|
old_monitors.remove(&monitor);
|
||||||
new_monitors.insert(&monitor);
|
new_monitors.insert(&monitor);
|
||||||
@ -114,12 +113,13 @@ class Main
|
|||||||
} catch (Monitor_tree::No_match) {
|
} catch (Monitor_tree::No_match) {
|
||||||
|
|
||||||
/* create monitor for subject in the new tree */
|
/* create monitor for subject in the new tree */
|
||||||
_new_monitor(new_monitors, id, session_policy);
|
_new_monitor(new_monitors, id, info, session_policy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Trace::Nonexistent_subject ) { continue; }
|
catch (Trace::Nonexistent_subject ) { return; }
|
||||||
catch (Session_policy::No_policy_defined) { continue; }
|
catch (Session_policy::No_policy_defined) { return; }
|
||||||
}
|
});
|
||||||
|
|
||||||
/* all monitors in the old tree are deprecated, destroy them */
|
/* all monitors in the old tree are deprecated, destroy them */
|
||||||
while (Monitor *monitor = old_monitors.first())
|
while (Monitor *monitor = old_monitors.first())
|
||||||
_destroy_monitor(old_monitors, *monitor);
|
_destroy_monitor(old_monitors, *monitor);
|
||||||
@ -145,8 +145,9 @@ class Main
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _new_monitor(Monitor_tree &monitors,
|
void _new_monitor(Monitor_tree &monitors,
|
||||||
Trace::Subject_id id,
|
Trace::Subject_id const id,
|
||||||
Session_policy &session_policy)
|
Trace::Subject_info const &info,
|
||||||
|
Session_policy const &session_policy)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Number_of_bytes const buffer_sz = session_policy.attribute_value("buffer", _default_buf_sz);
|
Number_of_bytes const buffer_sz = session_policy.attribute_value("buffer", _default_buf_sz);
|
||||||
@ -158,7 +159,7 @@ class Main
|
|||||||
_policies.insert(policy);
|
_policies.insert(policy);
|
||||||
_trace.trace(id.id, policy.id(), buffer_sz);
|
_trace.trace(id.id, policy.id(), buffer_sz);
|
||||||
}
|
}
|
||||||
monitors.insert(new (_heap) Monitor(_trace, _env.rm(), id));
|
monitors.insert(new (_heap) Monitor(_trace, _env.rm(), id, info));
|
||||||
}
|
}
|
||||||
catch (Trace::Already_traced ) { warning("Cannot activate tracing: Already_traced" ); return; }
|
catch (Trace::Already_traced ) { warning("Cannot activate tracing: Already_traced" ); return; }
|
||||||
catch (Trace::Source_is_dead ) { warning("Cannot activate tracing: Source_is_dead" ); return; }
|
catch (Trace::Source_is_dead ) { warning("Cannot activate tracing: Source_is_dead" ); return; }
|
||||||
@ -173,9 +174,8 @@ class Main
|
|||||||
log("new monitor: subject ", id.id);
|
log("new monitor: subject ", id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Session_policy _session_policy(Trace::Subject_id id)
|
Session_policy _session_policy(Trace::Subject_info const &info)
|
||||||
{
|
{
|
||||||
Trace::Subject_info info = _trace.subject_info(id);
|
|
||||||
Session_label const label(info.session_label());
|
Session_label const label(info.session_label());
|
||||||
Session_policy policy(label, _config);
|
Session_policy policy(label, _config);
|
||||||
if (policy.has_attribute("thread"))
|
if (policy.has_attribute("thread"))
|
||||||
|
@ -60,36 +60,34 @@ Monitor &Monitor::find_by_subject_id(Trace::Subject_id const subject_id)
|
|||||||
|
|
||||||
Monitor::Monitor(Trace::Connection &trace,
|
Monitor::Monitor(Trace::Connection &trace,
|
||||||
Region_map &rm,
|
Region_map &rm,
|
||||||
Trace::Subject_id subject_id)
|
Trace::Subject_id const subject_id,
|
||||||
|
Trace::Subject_info const &info)
|
||||||
:
|
:
|
||||||
Monitor_base(trace, rm, subject_id),
|
Monitor_base(trace, rm, subject_id),
|
||||||
_subject_id(subject_id), _buffer(_buffer_raw)
|
_subject_id(subject_id), _buffer(_buffer_raw)
|
||||||
{
|
{
|
||||||
_update_info();
|
update_info(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Monitor::_update_info()
|
void Monitor::update_info(Trace::Subject_info const &info)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Trace::Subject_info const &info =
|
|
||||||
_trace.subject_info(_subject_id);
|
|
||||||
|
|
||||||
uint64_t const last_execution_time =
|
uint64_t const last_execution_time =
|
||||||
_info.execution_time().thread_context;
|
_info.execution_time().thread_context;
|
||||||
|
|
||||||
_info = info;
|
_info = info;
|
||||||
|
|
||||||
_recent_exec_time =
|
_recent_exec_time =
|
||||||
_info.execution_time().thread_context - 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"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Monitor::print(bool activity, bool affinity)
|
void Monitor::print(bool activity, bool affinity)
|
||||||
{
|
{
|
||||||
_update_info();
|
|
||||||
|
|
||||||
/* print general subject information */
|
/* print general subject information */
|
||||||
typedef Trace::Subject_info Subject_info;
|
typedef Trace::Subject_info Subject_info;
|
||||||
Subject_info::State const state = _info.state();
|
Subject_info::State const state = _info.state();
|
||||||
|
@ -60,13 +60,12 @@ class Monitor : public Monitor_base,
|
|||||||
unsigned long long _recent_exec_time { 0 };
|
unsigned long long _recent_exec_time { 0 };
|
||||||
char _curr_entry_data[MAX_ENTRY_LENGTH];
|
char _curr_entry_data[MAX_ENTRY_LENGTH];
|
||||||
|
|
||||||
void _update_info();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Monitor(Genode::Trace::Connection &trace,
|
Monitor(Genode::Trace::Connection &trace,
|
||||||
Genode::Region_map &rm,
|
Genode::Region_map &rm,
|
||||||
Genode::Trace::Subject_id subject_id);
|
Genode::Trace::Subject_id subject_id,
|
||||||
|
Genode::Trace::Subject_info const &info);
|
||||||
|
|
||||||
void print(bool activity, bool affinity);
|
void print(bool activity, bool affinity);
|
||||||
|
|
||||||
@ -86,6 +85,8 @@ class Monitor : public Monitor_base,
|
|||||||
|
|
||||||
Genode::Trace::Subject_id subject_id() const { return _subject_id; }
|
Genode::Trace::Subject_id subject_id() const { return _subject_id; }
|
||||||
Genode::Trace::Subject_info const &info() const { return _info; }
|
Genode::Trace::Subject_info const &info() const { return _info; }
|
||||||
|
|
||||||
|
void update_info(Genode::Trace::Subject_info const &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,12 +93,8 @@ struct Trace_subject_registry
|
|||||||
|
|
||||||
void update(Genode::Trace::Connection &trace, Genode::Allocator &alloc)
|
void update(Genode::Trace::Connection &trace, Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
unsigned const num_subjects = update_subjects(trace);
|
trace.for_each_subject_info([&] (Genode::Trace::Subject_id id,
|
||||||
|
Genode::Trace::Subject_info const &info) {
|
||||||
/* add and update existing entries */
|
|
||||||
for (unsigned i = 0; i < num_subjects; i++) {
|
|
||||||
|
|
||||||
Genode::Trace::Subject_id const id = _subjects[i];
|
|
||||||
|
|
||||||
Entry *e = _lookup(id);
|
Entry *e = _lookup(id);
|
||||||
if (!e) {
|
if (!e) {
|
||||||
@ -106,7 +102,7 @@ struct Trace_subject_registry
|
|||||||
_entries.insert(e);
|
_entries.insert(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->update(trace.subject_info(id));
|
e->update(info);
|
||||||
|
|
||||||
/* purge dead threads */
|
/* purge dead threads */
|
||||||
if (e->info.state() == Genode::Trace::Subject_info::DEAD) {
|
if (e->info.state() == Genode::Trace::Subject_info::DEAD) {
|
||||||
@ -114,7 +110,7 @@ struct Trace_subject_registry
|
|||||||
_entries.remove(e);
|
_entries.remove(e);
|
||||||
Genode::destroy(alloc, e);
|
Genode::destroy(alloc, e);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
_sort_by_recent_execution_time();
|
_sort_by_recent_execution_time();
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Genode Labs GmbH
|
* Copyright (C) 2020-2021 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
@ -21,38 +21,27 @@ void Cpu::Trace::_read_idle_times(bool skip_max_idle)
|
|||||||
|
|
||||||
_idle_slot = (_idle_slot + 1) % HISTORY;
|
_idle_slot = (_idle_slot + 1) % HISTORY;
|
||||||
|
|
||||||
|
auto count = _trace->for_each_subject_info([&](Subject_id const &,
|
||||||
|
Subject_info const &info)
|
||||||
|
{
|
||||||
|
if (info.session_label() != "kernel" || info.thread_name() != "idle")
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (info.affinity().xpos() < MAX_CORES && info.affinity().ypos() < MAX_THREADS)
|
||||||
|
_idle_times[info.affinity().xpos()][info.affinity().ypos()][_idle_slot] = info.execution_time();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (count.count == count.limit) {
|
||||||
|
Genode::log("reconstruct trace session, subject_count=", count.count);
|
||||||
|
_reconstruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip_max_idle)
|
||||||
|
return;
|
||||||
|
|
||||||
for (unsigned x = 0; x < _space.width(); x++) {
|
for (unsigned x = 0; x < _space.width(); x++) {
|
||||||
for (unsigned y = 0; y < _space.height(); y++) {
|
for (unsigned y = 0; y < _space.height(); y++) {
|
||||||
Affinity::Location const idle_location(x,y);
|
Affinity::Location const idle_location(x,y);
|
||||||
Subject_id const &subject_id = _idle_id[x][y];
|
|
||||||
|
|
||||||
if (!subject_id.id || _subject_id_reread)
|
|
||||||
_lookup_missing_idle_id(idle_location);
|
|
||||||
|
|
||||||
if (!subject_id.id) {
|
|
||||||
_idle_times[x][y][_idle_slot] = Execution_time(0, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Subject_info const info = _trace->subject_info(subject_id);
|
|
||||||
|
|
||||||
Affinity::Location location = info.affinity();
|
|
||||||
|
|
||||||
if (location.xpos() != int(x) || location.ypos() != int(y)) {
|
|
||||||
Subject_id const subject_id_old = subject_id;
|
|
||||||
|
|
||||||
_lookup_missing_idle_id(idle_location);
|
|
||||||
|
|
||||||
Genode::warning("idle location mismatch ", x, "x", y, " vs ",
|
|
||||||
location.xpos(), "x", location.ypos(), " subject id=",
|
|
||||||
subject_id_old.id, " vs ", _idle_id[x][y].id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_idle_times[x][y][_idle_slot] = info.execution_time();
|
|
||||||
|
|
||||||
if (skip_max_idle)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* determine max available execution time by monitoring idle */
|
/* determine max available execution time by monitoring idle */
|
||||||
auto const time = diff_idle_times(idle_location);
|
auto const time = diff_idle_times(idle_location);
|
||||||
auto &max = _idle_max[x][y];
|
auto &max = _idle_max[x][y];
|
||||||
@ -63,43 +52,6 @@ void Cpu::Trace::_read_idle_times(bool skip_max_idle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cpu::Trace::_lookup_missing_idle_id(Affinity::Location const &location)
|
|
||||||
{
|
|
||||||
Subject_id found_id { };
|
|
||||||
|
|
||||||
do {
|
|
||||||
auto count = _trace->for_each_subject_info([&](Subject_id const &id,
|
|
||||||
Subject_info const &info)
|
|
||||||
{
|
|
||||||
if (found_id.id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (info.affinity().xpos() != location.xpos() ||
|
|
||||||
info.affinity().ypos() != location.ypos())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (info.session_label() != "kernel" || info.thread_name() != "idle")
|
|
||||||
return;
|
|
||||||
|
|
||||||
_idle_id[location.xpos()][location.ypos()] = id;
|
|
||||||
found_id = id;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (count.count == count.limit) {
|
|
||||||
Genode::log("reconstruct trace session, subject_count=", count.count);
|
|
||||||
_reconstruct();
|
|
||||||
found_id = Subject_id();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_id.id) {
|
|
||||||
Genode::error("idle trace id missing");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (!found_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::Trace::Subject_id
|
Genode::Trace::Subject_id
|
||||||
Cpu::Trace::lookup_missing_id(Session_label const &label,
|
Cpu::Trace::lookup_missing_id(Session_label const &label,
|
||||||
Thread_name const &thread)
|
Thread_name const &thread)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Genode Labs GmbH
|
* Copyright (C) 2020-2021 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
@ -45,15 +45,12 @@ class Cpu::Trace
|
|||||||
|
|
||||||
enum { MAX_CORES = 64, MAX_THREADS = 2, HISTORY = 4 };
|
enum { MAX_CORES = 64, MAX_THREADS = 2, HISTORY = 4 };
|
||||||
|
|
||||||
Subject_id _idle_id [MAX_CORES][MAX_THREADS];
|
|
||||||
Execution_time _idle_times[MAX_CORES][MAX_THREADS][HISTORY];
|
Execution_time _idle_times[MAX_CORES][MAX_THREADS][HISTORY];
|
||||||
Execution_time _idle_max [MAX_CORES][MAX_THREADS];
|
Execution_time _idle_max [MAX_CORES][MAX_THREADS];
|
||||||
unsigned _idle_slot { HISTORY - 1 };
|
unsigned _idle_slot { HISTORY - 1 };
|
||||||
|
|
||||||
unsigned _subject_id_reread { 0 };
|
unsigned _subject_id_reread { 0 };
|
||||||
|
|
||||||
void _lookup_missing_idle_id(Affinity::Location const &);
|
|
||||||
|
|
||||||
void _reconstruct(Genode::size_t const upgrade = 4 * 4096)
|
void _reconstruct(Genode::size_t const upgrade = 4 * 4096)
|
||||||
{
|
{
|
||||||
_ram_quota += upgrade;
|
_ram_quota += upgrade;
|
||||||
@ -124,14 +121,21 @@ class Cpu::Trace
|
|||||||
Session_label lookup_my_label();
|
Session_label lookup_my_label();
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
void retrieve(Subject_id const id, FUNC const &fn)
|
void retrieve(Subject_id const target_id, FUNC const &fn)
|
||||||
{
|
{
|
||||||
if (!_trace.constructed())
|
if (!_trace.constructed())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Ieegs, XXX, avoid copying whole object */
|
auto count = _trace->for_each_subject_info([&](Subject_id const &id,
|
||||||
Subject_info info = _trace->subject_info(id);
|
Subject_info const &info) {
|
||||||
|
if (id == target_id)
|
||||||
fn(info.execution_time(), info.affinity());
|
fn(info.execution_time(), info.affinity());
|
||||||
|
});
|
||||||
|
|
||||||
|
if (count.count == count.limit) {
|
||||||
|
Genode::log("reconstruct trace session, subject_count=", count.count);
|
||||||
|
_reconstruct();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Execution_time abs_idle_times(Affinity::Location const &location)
|
Execution_time abs_idle_times(Affinity::Location const &location)
|
||||||
|
@ -221,16 +221,6 @@ struct Test_tracing
|
|||||||
return "undefined";
|
return "undefined";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FUNC>
|
|
||||||
void for_each_subject(Trace::Subject_id subjects[],
|
|
||||||
size_t max_subjects, FUNC const &func)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < max_subjects; i++) {
|
|
||||||
Trace::Subject_info info = trace.subject_info(subjects[i]);
|
|
||||||
func(subjects[i].id, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Failed : Genode::Exception { };
|
struct Failed : Genode::Exception { };
|
||||||
|
|
||||||
Test_tracing(Env &env) : env(env)
|
Test_tracing(Env &env) : env(env)
|
||||||
@ -273,14 +263,6 @@ struct Test_tracing
|
|||||||
/* wait some time before querying the subjects */
|
/* wait some time before querying the subjects */
|
||||||
timer.msleep(1500);
|
timer.msleep(1500);
|
||||||
|
|
||||||
Trace::Subject_id subjects[MAX_SUBJECTS];
|
|
||||||
size_t num_subjects = trace.subjects(subjects, MAX_SUBJECTS);
|
|
||||||
|
|
||||||
log(num_subjects, " tracing subjects present");
|
|
||||||
|
|
||||||
if (num_subjects == MAX_SUBJECTS)
|
|
||||||
error("Seems we reached the maximum number of subjects.");
|
|
||||||
|
|
||||||
auto print_info = [this] (Trace::Subject_id id, Trace::Subject_info info) {
|
auto print_info = [this] (Trace::Subject_id id, Trace::Subject_info info) {
|
||||||
|
|
||||||
log("ID:", id.id, " "
|
log("ID:", id.id, " "
|
||||||
@ -294,7 +276,7 @@ struct Test_tracing
|
|||||||
"quantum:", info.execution_time().quantum);
|
"quantum:", info.execution_time().quantum);
|
||||||
};
|
};
|
||||||
|
|
||||||
for_each_subject(subjects, num_subjects, print_info);
|
trace.for_each_subject_info(print_info);
|
||||||
|
|
||||||
auto check_untraced = [this] (Trace::Subject_id id, Trace::Subject_info info) {
|
auto check_untraced = [this] (Trace::Subject_id id, Trace::Subject_info info) {
|
||||||
|
|
||||||
@ -302,7 +284,7 @@ struct Test_tracing
|
|||||||
error("Subject ", id.id, " is not UNTRACED");
|
error("Subject ", id.id, " is not UNTRACED");
|
||||||
};
|
};
|
||||||
|
|
||||||
for_each_subject(subjects, num_subjects, check_untraced);
|
trace.for_each_subject_info(check_untraced);
|
||||||
|
|
||||||
/* enable tracing for test-thread */
|
/* enable tracing for test-thread */
|
||||||
auto enable_tracing = [this, &env] (Trace::Subject_id id,
|
auto enable_tracing = [this, &env] (Trace::Subject_id id,
|
||||||
@ -329,12 +311,12 @@ struct Test_tracing
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for_each_subject(subjects, num_subjects, enable_tracing);
|
trace.for_each_subject_info(enable_tracing);
|
||||||
|
|
||||||
/* give the test thread some time to run */
|
/* give the test thread some time to run */
|
||||||
timer.msleep(1000);
|
timer.msleep(1000);
|
||||||
|
|
||||||
for_each_subject(subjects, num_subjects, print_info);
|
trace.for_each_subject_info(print_info);
|
||||||
|
|
||||||
/* read events from trace buffer */
|
/* read events from trace buffer */
|
||||||
if (test_monitor.constructed()) {
|
if (test_monitor.constructed()) {
|
||||||
|
Reference in New Issue
Block a user