From 2163ce25f696623d6e00d2b290553528171a5bf0 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sat, 23 Feb 2019 19:09:15 +0100 Subject: [PATCH] sculpt: show TCB dependencies of selection This patch enhances the runtime view such that not only immediate dependencies but also all transitive dependencies of the selected component are displayed. This way, the graph nicely reveals the trusted computing base of the selection. --- repos/gems/src/app/sculpt_manager/graph.h | 5 +- .../app/sculpt_manager/model/runtime_config.h | 20 +++++-- .../app/sculpt_manager/model/runtime_state.h | 53 +++++++++++++++++-- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/repos/gems/src/app/sculpt_manager/graph.h b/repos/gems/src/app/sculpt_manager/graph.h index 04678cb7d..7660d02ff 100644 --- a/repos/gems/src/app/sculpt_manager/graph.h +++ b/repos/gems/src/app/sculpt_manager/graph.h @@ -172,7 +172,7 @@ struct Sculpt::Graph Runtime_state::Info const info = _runtime_state.info(name); - bool const show_details = info.selected; + bool const show_details = info.tcb; if (show_details) { component.for_each_secondary_dep([&] (Start_name const &dep) { @@ -266,7 +266,8 @@ struct Sculpt::Graph } if (_node_button_item._hovered.valid()) { - _runtime_state.toggle_selection(_node_button_item._hovered); + _runtime_state.toggle_selection(_node_button_item._hovered, + _runtime_config); _remove_item.reset(); _gen_graph_dialog(); } diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_config.h b/repos/gems/src/app/sculpt_manager/model/runtime_config.h index a99df159a..7cf618803 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_config.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_config.h @@ -149,7 +149,6 @@ class Sculpt::Runtime_config Dep &create_element(Xml_node node) { - log("to_name -> ", _to_name(node), " for ", node); return *new (_alloc) Dep(_to_name(node)); } @@ -186,10 +185,13 @@ class Sculpt::Runtime_config Allocator &_alloc; + Dep::Update_policy _dep_update_policy { _alloc }; + Update_policy(Allocator &alloc) : _alloc(alloc) { } void destroy_element(Component &elem) { + elem.deps.update_from_xml(_dep_update_policy, Xml_node("")); destroy(_alloc, &elem); } @@ -201,12 +203,10 @@ class Sculpt::Runtime_config void update_element(Component &elem, Xml_node node) { - log("update component ", elem.name); elem.primary_dependency = _primary_dependency(node); - Dep::Update_policy policy(_alloc); node.with_sub_node("route", [&] (Xml_node route) { - elem.deps.update_from_xml(policy, route); }); + elem.deps.update_from_xml(_dep_update_policy, route); }); } static bool element_matches_xml_node(Component const &elem, Xml_node node) @@ -234,6 +234,18 @@ class Sculpt::Runtime_config template void for_each_component(FN const &fn) const { _components.for_each(fn); } + + /** + * Call 'fn' with the name of each dependency of component 'name' + */ + template + void for_each_dependency(Start_name const &name, FN const &fn) const + { + _components.for_each([&] (Component const &component) { + if (component.name == name) { + component.deps.for_each([&] (Component::Dep const &dep) { + fn(dep.to_name); }); } }); + } }; #endif /* _MODEL__RUNTIME_CONFIG_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_state.h b/repos/gems/src/app/sculpt_manager/model/runtime_state.h index ebd36be59..4b0626234 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_state.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_state.h @@ -21,6 +21,7 @@ /* local includes */ #include #include +#include namespace Sculpt { class Runtime_state; } @@ -32,6 +33,12 @@ class Sculpt::Runtime_state : public Runtime_info { bool selected; + /* true if component is in the TCB of the selected one */ + bool tcb; + + /* true if 'tcb' is updated for the immediate dependencies */ + bool tcb_updated; + unsigned long assigned_ram; unsigned long avail_ram; @@ -47,7 +54,11 @@ class Sculpt::Runtime_state : public Runtime_info { Start_name const name; - Info info { false, 0, 0, 0, 0 }; + Info info { .selected = false, + .tcb = false, + .tcb_updated = false, + .assigned_ram = 0, .avail_ram = 0, + .assigned_caps = 0, .avail_caps = 0 }; bool abandoned_by_user = false; @@ -118,6 +129,8 @@ class Sculpt::Runtime_state : public Runtime_info { return node.attribute_value("name", Start_name()) == elem.name; } + + static bool node_is_element(Xml_node node) { return node.has_type("child"); } }; public: @@ -169,7 +182,7 @@ class Sculpt::Runtime_state : public Runtime_info Info info(Start_name const &name) const { - Info result { .selected = false, 0, 0, 0, 0 }; + Info result { }; _children.for_each([&] (Child const &child) { if (child.name == name) result = child.info; }); @@ -185,10 +198,42 @@ class Sculpt::Runtime_state : public Runtime_info return result; } - void toggle_selection(Start_name const &name) + void toggle_selection(Start_name const &name, Runtime_config const &config) { _children.for_each([&] (Child &child) { - child.info.selected = (child.name == name) && !child.info.selected; }); + child.info.selected = (child.name == name) && !child.info.selected; + child.info.tcb = child.info.selected; + child.info.tcb_updated = false; + }); + + /* + * Update the TCB flag of the selected child's transitive + * dependencies. + */ + for (;;) { + + Start_name name_of_updated { }; + + /* + * Search child that belongs to TCB but its dependencies + * have not been added to the TCB yet. + */ + _children.for_each([&] (Child &child) { + if (!name_of_updated.valid() && child.info.tcb && !child.info.tcb_updated) { + name_of_updated = child.name; + child.info.tcb_updated = true; /* skip in next iteration */ + } + }); + + if (!name_of_updated.valid()) + break; + + /* tag all dependencies as part of the TCB */ + config.for_each_dependency(name_of_updated, [&] (Start_name const &dep) { + _children.for_each([&] (Child &child) { + if (child.name == dep) + child.info.tcb = true; }); }); + } } void abandon(Start_name const &name)