Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
use namespaces for instr containers and values
[simgrid.git] / src / instr / instr_paje_containers.cpp
1 /* Copyright (c) 2010-2017. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "simgrid/s4u/Engine.hpp"
7 #include "simgrid/s4u/Host.hpp"
8 #include "surf/surf.h"
9 #include "src/instr/instr_private.hpp"
10
11 #include <unordered_map>
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_paje_containers, instr, "Paje tracing event system (containers)");
14
15 static container_t rootContainer = nullptr;    /* the root container */
16 static std::unordered_map<std::string, container_t> allContainers; /* all created containers indexed by name */
17 std::set<std::string> trivaNodeTypes;           /* all host types defined */
18 std::set<std::string> trivaEdgeTypes;           /* all link types defined */
19
20 long long int instr_new_paje_id ()
21 {
22   static long long int type_id = 0;
23   return type_id++;
24 }
25
26 container_t PJ_container_get_root()
27 {
28   return rootContainer;
29 }
30
31 void PJ_container_set_root (container_t root)
32 {
33   rootContainer = root;
34 }
35
36 namespace simgrid {
37 namespace instr {
38
39 Container::Container(std::string name, e_container_types kind, Container* father)
40     : name_(name), kind_(kind), father_(father)
41 {
42   static long long int container_id = 0;
43   id_                               = std::to_string(container_id); // id (or alias) of the container
44   container_id++;
45
46   //Search for network_element_t
47   switch (kind){
48     case INSTR_HOST:
49       this->netpoint_ = sg_host_by_name(name.c_str())->pimpl_netpoint;
50       xbt_assert(this->netpoint_, "Element '%s' not found", name.c_str());
51       break;
52     case INSTR_ROUTER:
53       this->netpoint_ = simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name);
54       xbt_assert(this->netpoint_, "Element '%s' not found", name.c_str());
55       break;
56     case INSTR_AS:
57       this->netpoint_ = simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name);
58       xbt_assert(this->netpoint_, "Element '%s' not found", name.c_str());
59       break;
60     default:
61       this->netpoint_ = nullptr;
62       break;
63   }
64
65   if (father_) {
66     this->level_ = father_->level_ + 1;
67     XBT_DEBUG("new container %s, child of %s", name.c_str(), father->name_.c_str());
68   }
69
70   // type definition (method depends on kind of this new container)
71   if (this->kind_ == INSTR_AS) {
72     //if this container is of an AS, its type name depends on its level
73     char as_typename[INSTR_DEFAULT_STR_SIZE];
74     snprintf(as_typename, INSTR_DEFAULT_STR_SIZE, "L%d", this->level_);
75     if (this->father_) {
76       this->type_ = this->father_->type_->getChildOrNull(as_typename);
77       if (this->type_ == nullptr) {
78         this->type_ = Type::containerNew(as_typename, this->father_->type_);
79       }
80     }else{
81       this->type_ = Type::containerNew("0", nullptr);
82     }
83   } else {
84     //otherwise, the name is its kind
85     char typeNameBuff[INSTR_DEFAULT_STR_SIZE];
86     switch (this->kind_) {
87       case INSTR_HOST:
88         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "HOST");
89         break;
90       case INSTR_LINK:
91         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "LINK");
92         break;
93       case INSTR_ROUTER:
94         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "ROUTER");
95         break;
96       case INSTR_SMPI:
97         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MPI");
98         break;
99       case INSTR_MSG_PROCESS:
100         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_PROCESS");
101         break;
102       case INSTR_MSG_VM:
103         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_VM");
104         break;
105       case INSTR_MSG_TASK:
106         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_TASK");
107         break;
108       default:
109         THROWF (tracing_error, 0, "new container kind is unknown.");
110         break;
111     }
112     Type* type = this->father_->type_->getChildOrNull(typeNameBuff);
113     if (type == nullptr){
114       this->type_ = Type::containerNew(typeNameBuff, this->father_->type_);
115     }else{
116       this->type_ = type;
117     }
118   }
119   if (this->father_) {
120     this->father_->children_.insert({this->name_, this});
121     LogContainerCreation(this);
122   }
123
124   //register all kinds by name
125   if (not allContainers.emplace(this->name_, this).second) {
126     THROWF(tracing_error, 1, "container %s already present in allContainers data structure", this->name_.c_str());
127   }
128
129   XBT_DEBUG("Add container name '%s'", this->name_.c_str());
130
131   //register NODE types for triva configuration
132   if (this->kind_ == INSTR_HOST || this->kind_ == INSTR_LINK || this->kind_ == INSTR_ROUTER) {
133     trivaNodeTypes.insert(this->type_->getName());
134   }
135 }
136
137 Container::~Container()
138 {
139   XBT_DEBUG("destroy container %s", name_.c_str());
140   // Begin with destroying my own children
141   for (auto child : children_) {
142     delete child.second;
143   }
144
145   // obligation to dump previous events because they might reference the container that is about to be destroyed
146   TRACE_last_timestamp_to_dump = surf_get_clock();
147   TRACE_paje_dump_buffer(1);
148
149   // trace my destruction
150   if (not TRACE_disable_destroy() && this != PJ_container_get_root()) {
151     // do not trace the container destruction if user requests or if the container is root
152     LogContainerDestruction(this);
153   }
154
155   // remove me from the allContainers data structure
156   allContainers.erase(name_);
157 }
158
159 Container* Container::byNameOrNull(std::string name)
160 {
161   auto cont = allContainers.find(name);
162   return cont == allContainers.end() ? nullptr : cont->second;
163 }
164
165 Container* Container::byName(std::string name)
166 {
167   Container* ret = Container::byNameOrNull(name);
168   if (ret == nullptr)
169     THROWF(tracing_error, 1, "container with name %s not found", name.c_str());
170
171   return ret;
172 }
173 }
174 }
175
176 void PJ_container_remove_from_parent (container_t child)
177 {
178   if (child == nullptr){
179     THROWF (tracing_error, 0, "can't remove from parent with a nullptr child");
180   }
181
182   container_t parent = child->father_;
183   if (parent){
184     XBT_DEBUG("removeChildContainer (%s) FromContainer (%s) ", child->name_.c_str(), parent->name_.c_str());
185     parent->children_.erase(child->name_);
186   }
187 }