The Sparta Modeling Framework
Loading...
Searching...
No Matches
RootTreeNode.hpp
Go to the documentation of this file.
1// <RootTreeNode> -*- C++ -*-
2
8#pragma once
9
10#include <memory>
11#include <ostream>
12#include <string>
13#include <vector>
14
16#include "sparta/simulation/TreeNodeExtensions.hpp"
19#include "sparta/log/NotificationSource.hpp"
20#include "sparta/simulation/TreeNodePrivateAttorney.hpp"
21#include "sparta/simulation/ParameterTree.hpp"
26
27namespace sparta
28{
29 class ArchData;
30 class Clock;
31 class TreeNodeExtensionManager;
32
33 namespace app {
34 class Simulation;
35 }
36
37 namespace python {
38 class PythonInterpreter;
39 }
40
54 class RootTreeNode : public TreeNode
55 {
56 public:
57
63
80 RootTreeNode(const std::string & name,
81 const std::string & desc,
82 app::Simulation* sim,
83 GlobalTreeNode* search_scope) :
85 sim_(sim),
86 new_node_noti_(this,
87 "descendant_attached",
88 "Notification immediately after a node becomes a descendant of this "
89 "root at any distance. This new node may have children already attached "
90 "which will not receive their own descendant_attached notification",
91 "descendant_attached")
92 {
93 if(search_scope != nullptr){
94 search_node_ = search_scope;
95 }else{
96 search_node_ = new GlobalTreeNode();
97 alloc_search_node_.reset(search_node_);
98 }
99 search_node_->addChild(this);
100
101 /* Define the default scope that all tree nodes will be in. This is
102 * to ensure that getScopeRoot() never returns nullptr event when no
103 * scope is explicitly defined. */
104 setScopeRoot();
105 }
106
110 RootTreeNode(const std::string & name,
111 const std::string & desc,
112 GlobalTreeNode* search_scope) :
113 RootTreeNode(name, desc, nullptr, search_scope)
114 {
115 // Delegated construction
116 }
117
121 RootTreeNode(const std::string & name) :
122 RootTreeNode(name, "Top of device tree", nullptr, nullptr)
123 {
124 // Delegated construction
125 }
126
130 RootTreeNode(const std::string & name,
131 const std::string & desc,
132 app::Simulation* sim) :
133 RootTreeNode(name, desc, sim, nullptr)
134 {
135 // Delegated construction
136 }
137
142 RootTreeNode(const std::string & name,
143 const std::string & desc) :
144 RootTreeNode(name, desc, nullptr, nullptr)
145 {
146 // Delegated construction
147 }
148
153 RootTreeNode("top", "Top of device tree", sim, nullptr)
154 {
155 // Delegated construction
156 }
157
162 RootTreeNode("top", "Top of device tree", nullptr, search_scope)
163 {
164 // Delegated construction
165 }
166
171 RootTreeNode("top", "Top of device tree", sim, search_scope)
172 {
173 // Delegated construction
174 }
175
180 RootTreeNode("top", "Top of device tree", nullptr, nullptr)
181 {
182 // Delegated construction
183 }
184
192 virtual ~RootTreeNode() {
193 // Inform Search Scope node since it will not be notified by
194 // ~TreeNode, which does not recognize the search scope as a parent
195 if(search_node_){
196 removeFromParentForTeardown_(search_node_);
197 }
198
199 // No need to alert children, because ~TreeNode will do this next
200 }
201
202 // Returns true. Tree root is always considered "attached"
203 virtual bool isAttached() const override final {
204 return true;
205 }
206
207 // Returns 0. Tree root will never have a parent
208 virtual TreeNode* getParent() override final { return nullptr; }
209
210 // Returns 0. Tree root will never have a parent
211 virtual const TreeNode* getParent() const override final { return nullptr; }
212
213 // Override TreeNode::setClock() so we can pass that clock to the search scope
214 virtual void setClock(const Clock * clk) override final {
215 if (search_node_) {
216 search_node_->setClock(clk);
217 }
219 }
220
225 return sim_;
226 }
227
235 sparta_assert(search_node_);
236 return search_node_;
237 }
238
248 if(getPhase() != TREE_BUILDING){
249 throw SpartaException("Device tree with root \"")
250 << getLocation()<< "\" not currently in the TREE_BUILDING phase, so it cannot "
251 "enter TREE_CONFIGURING";
252 }
253
254 enterConfig_(); // Enter the next phase (cannot throw)
255 }
256
272 void enterFinalized(sparta::python::PythonInterpreter* pyshell = nullptr);
273
290 if(getPhase() != TREE_FINALIZED){
291 throw SpartaException("Device tree with root \"")
292 << getLocation()
293 << "\" not in the TREE_FINALIZED phase, so it cannot be bound (bindTreeEarly)";
294 }
295
297 }
298
310 if(getPhase() != TREE_FINALIZED){
311 throw SpartaException("Device tree with root \"")
312 << getLocation()
313 << "\" not in the TREE_FINALIZED phase, so it cannot be bound (bindTreeLate)";
314 }
315
317 }
318
333
341 if(getPhase() != TREE_FINALIZED){
342 throw SpartaException("Device tree with root \"")
343 << getLocation()
344 << "\" not in the TREE_FINALIZED phase, so it cannot be pre-run validated";
345 }
346
347 validateTree_(); // Validate all nodes, which may throw
348 }
349
350
358
369 void dumpDebugContent(std::ostream& out) noexcept {
371 }
372
384 enterTeardown_(); // Enter the next phase
385 }
386
394 virtual std::string stringize(bool pretty=false) const override {
395 (void) pretty;
396 std::stringstream ss;
397 ss << "<" << getLocation() << " (root)>";
398 return ss.str();
399 }
400
404
417 return new_node_noti_;
418 }
419
422
427
439 void getArchDataAssociations(std::vector<const ArchData*>& ad_this_tree,
440 std::vector<const ArchData*>& ad_no_assoc,
441 std::vector<const ArchData*>& ad_not_attached,
442 std::vector<const ArchData*>& ad_other_tree) const noexcept;
443
455
466 void dumpArchDataAssociations(std::ostream& o) const noexcept;
467
471 void dumpTypeMix(std::ostream& o) const;
472
479 void setExtensionManager(TreeNodeExtensionManager* mgr);
480
484 const TreeNodeExtensionManager * getExtensionManager(bool must_exist = true) const {
485 if (!extension_mgr_ && must_exist) {
486 throw SpartaException("Expecting TreeNodeExtensionsManager to exist but it doesn't");
487 }
488 return extension_mgr_;
489 }
490
494 TreeNodeExtensionManager * getExtensionManager(bool must_exist = true) {
495 if (!extension_mgr_ && must_exist) {
496 throw SpartaException("Expecting TreeNodeExtensionsManager to exist but it doesn't");
497 }
498 return extension_mgr_;
499 }
500
503
504 private:
505
506 // The TreeNodeExtensionManager object owned by CommandLineSimulator,
507 // a simulation subclass, or in the SimulationConfiguration object
508 // on the stack in a unit test.
509 TreeNodeExtensionManager * extension_mgr_ = nullptr;
510
511 // No effect on root
512 virtual void createResource_() override {};
513
523 virtual void onSettingParent_(const TreeNode* parent) const override final {
524 if(parent != search_node_){
525 throw SpartaException("This RootTreeNode \"")
526 << "\" cannot be a child of any other node except its constructed "
527 "GlobalTreeNode";
528 }
529 }
530
539 virtual void setParent_(TreeNode* parent, bool) override final {
540 if(parent != search_node_){
541 throw SpartaCriticalError("This RootTreeNode \"")
542 << "\" cannot be a child of any other node except its constructed "
543 "GlobalTreeNode";
544 }
545
546 // NOTE: Do not store parent because the root should act as if there is no parent
547 }
548
549 virtual void onDescendentSubtreeAdded_(TreeNode* des) noexcept override final {
550 // Broadcast notification for self coming into existence
551 try{
552 new_node_noti_.postNotification(*des);
553
554 // Iterate subtree headed by des and notify observers of these
556 onDescendentSubtreeAdded_(child);
557 }
558 }catch(SpartaException& ex){
559 std::stringstream msg;
560 msg << ex.what() <<
561 "\nThis exception within onDescendentSubtreeAdded_, which is not exception-"
562 "safe. The integrity of this sparta tree (" << getRoot() << ") is compromised. "
563 "Aborting. ";
564 sparta_abort(false,msg.str());
565 }
566 }
567
572 std::unique_ptr<GlobalTreeNode> alloc_search_node_;
573
578 GlobalTreeNode* search_node_;
579
583 app::Simulation* sim_;
584
589 NewDescendantNotiSrc new_node_noti_;
590 };
591
592} // namespace sparta
Configuration Applicators.
TreeNode refinement representing the global namespace (above "top") of a device tree.
A set of sparta::Parameters per sparta::ResourceTreeNode.
Basic Node framework in sparta device tree composite pattern.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_abort(...)
Simple variatic assertion that will print a message to std::cerr and call std::terminate()
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Basic Node framework in sparta device tree composite pattern.
A representation of simulated time.
Definition Clock.hpp:44
TreeNode which represents some "global" namespace of the device tree, containing only RootTreeNodes,...
A TreeNode that generates a specific type of notification which propagates up a tree of TreeNodes (us...
void postNotification(const NotificationDataT &data) const
Post with reference to data with parent as message origin.
TreePhase getPhase() const
Gets the trees current phase.
@ TREE_BUILDING
Setting up tree hierarchy only (initial state)
@ TREE_FINALIZED
Tree and all resources have been instantiated. No more configuration/connection allowed.
TreeNode which represents the root ("top") of a device tree.
RootTreeNode(app::Simulation *sim, GlobalTreeNode *search_scope)
Constructor with only a simulator and search scope.
app::Simulation * getSimulator() const
Gets the simulator (if any) associated with this Root node.
void simulationTerminating()
Called after simulation has stopped, but before statistic/report generation.
RootTreeNode(const std::string &name)
Constructor with name only.
void dumpArchDataAssociations(std::ostream &o) const noexcept
Debugging tool which checks all ArchDatas in existence to see if they are associated with this tree....
RootTreeNode(GlobalTreeNode *search_scope)
Constructor with only a search scope.
RootTreeNode(const std::string &name, const std::string &desc, app::Simulation *sim)
Consturctor with name, desc, and simulator.
virtual ~RootTreeNode()
Destructor.
NotificationSource< TreeNode > NewDescendantNotiSrc
Type for notification source in this node which is posted when a new descendent is attached.
RootTreeNode()
Default constuctor.
RootTreeNode(app::Simulation *sim)
Constructor with only a simulator.
void bindTreeEarly()
Public method for recursively giving all resources and nodes a chance to bind ports locally....
virtual std::string stringize(bool pretty=false) const override
Render description of this RootTreeNode as a string.
GlobalTreeNode * getSearchScope()
Gets the search node "parent" of this root node which is suitable for performing searches that includ...
void dumpTypeMix(std::ostream &o) const
Dumps the mix of tree node concrete types to the ostream.
void enterConfiguring()
Public method to crystalize the tree structure and begin configuring.
void bindTreeLate()
Public method for recursively giving all resources and nodes a chance to bind ports locally....
void validatePreRun()
Validate the entire tree immediately prior to running. All ports should be bound ,...
void enterTeardown()
Places this tree into TREE_TEARDOWN phase so that nodes may be deleted without errors.
void dumpDebugContent(std::ostream &out) noexcept
Dump all debug content from each resource in the tree to an ostream.
void validatePostRun()
Validate all resources in the simulator, throwing exceptions if invalid state is detected....
TreeNodeExtensionManager * getExtensionManager(bool must_exist=true)
Get the TreeNodeExtensionsManager.
void setExtensionManager(TreeNodeExtensionManager *mgr)
Enable tree node extensions by giving the root node a TreeNodeExtensionsManager.
virtual bool isAttached() const override final
Is this node part of a device tree with a proper RootTreeNode at the root.
const TreeNodeExtensionManager * getExtensionManager(bool must_exist=true) const
Get the TreeNodeExtensionsManager.
void enterFinalized(sparta::python::PythonInterpreter *pyshell=nullptr)
Public method for recursive tree finalization. Places tree temporarily into TREE_FINALIZING phase bef...
RootTreeNode(const std::string &name, const std::string &desc, GlobalTreeNode *search_scope)
Constructor with name, desc, and search scope.
void validateArchDataAssociations() const
Gets the results.
void getArchDataAssociations(std::vector< const ArchData * > &ad_this_tree, std::vector< const ArchData * > &ad_no_assoc, std::vector< const ArchData * > &ad_not_attached, std::vector< const ArchData * > &ad_other_tree) const noexcept
Gets vectors of all the ArchData instances in existance now categorized into several groups....
RootTreeNode(const std::string &name, const std::string &desc, app::Simulation *sim, GlobalTreeNode *search_scope)
Constructor.
virtual TreeNode * getParent() override final
Gets immediate parent of this node if one exists.
NewDescendantNotiSrc & getNodeAttachedNotification()
Returns the post-write notification-source node for this register which can be used to observe writes...
RootTreeNode(const std::string &name, const std::string &desc)
Constructor with name and desc.
virtual void setClock(const Clock *clk) override final
Assigns a clock to this node. This clock will then be accessed by any descendant which has no assigne...
Used to construct and throw a standard C++ exception. Inherits from std::exception.
static const TreeNode::ChildrenVector & getAllChildren(const TreeNode &node)
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:204
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
Definition TreeNode.hpp:302
std::string getLocation() const override final
void validateTree_()
Iterates the finalized tree and validates each node (e.g. ensures statistics can be evaluated)
virtual TreeNode * getRoot()
Gets farthest ancestor of this node.
static constexpr char GROUP_NAME_NONE[]
Group name indicating that a node belongs to no group.
Definition TreeNode.hpp:313
void simulationTerminating_()
Hook to allow simulation resources to clean-up before simulation is ended.
void enterTeardown_() noexcept
Recursively enter TREE_TEARDOWN phase while alerting nodes through onEnteringTeardown_ and alterting ...
TreeNode()=delete
Not default-constructable.
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
virtual void setClock(const Clock *clk)
Assigns a clock to this node. This clock will then be accessed by any descendant which has no assigne...
void dumpDebugContent_(std::ostream &out) const noexcept
Allows resources to write out detailed textual debugging information about the node....
void enterConfig_() noexcept
Recursively enter TREE_CONFIGURING phase.
void bindTreeLate_()
Recursively invoke TreeNode::onBindTreeEarly_ and Resource::onBindTreeLate_ (in that order for each n...
void bindTreeEarly_()
Recursively invoke TreeNode::onBindTreeEarly_ and Resource::onBindTreeEarly_ (in that order for each ...
void removeFromParentForTeardown_(TreeNode *parent)
Protected Wrapper for getParent()->removeChildForTeardown_ which allows subclases of TreeNode to indi...
Simulator which builds a sparta DeviceTree.
Macros for handling exponential backoff.