Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
9208684f97dcda72bc14768265758ea5446a3b61
[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
9 #include "surf/surf.h"
10
11 #include "src/instr/instr_private.h"
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 xbt_dict_t allContainers = nullptr;     /* 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 void PJ_container_alloc ()
27 {
28   allContainers = xbt_dict_new_homogeneous(nullptr);
29 }
30
31 void PJ_container_release ()
32 {
33   xbt_dict_free (&allContainers);
34 }
35
36 void PJ_container_set_root (container_t root)
37 {
38   rootContainer = root;
39 }
40
41 simgrid::instr::Container::Container(const char* name, simgrid::instr::e_container_types kind, Container* father)
42     : name_(xbt_strdup(name)), father_(father)
43 {
44   xbt_assert(name != nullptr, "Container name cannot be nullptr");
45
46   static long long int container_id = 0;
47   id_                               = bprintf("%lld", container_id); // id (or alias) of the container
48   container_id++;
49
50   //Search for network_element_t
51   switch (kind){
52     case simgrid::instr::INSTR_HOST:
53       this->netpoint_ = sg_host_by_name(name)->pimpl_netpoint;
54       xbt_assert(this->netpoint_, "Element '%s' not found", name);
55       break;
56     case simgrid::instr::INSTR_ROUTER:
57       this->netpoint_ = simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name);
58       xbt_assert(this->netpoint_, "Element '%s' not found", name);
59       break;
60     case simgrid::instr::INSTR_AS:
61       this->netpoint_ = simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name);
62       xbt_assert(this->netpoint_, "Element '%s' not found", name);
63       break;
64     default:
65       this->netpoint_ = nullptr;
66       break;
67   }
68
69   if (father_) {
70     this->level_ = father_->level_ + 1;
71     XBT_DEBUG("new container %s, child of %s", name, father->name_);
72   }
73
74   // type definition (method depends on kind of this new container)
75   this->kind_ = kind;
76   if (this->kind_ == simgrid::instr::INSTR_AS) {
77     //if this container is of an AS, its type name depends on its level
78     char as_typename[INSTR_DEFAULT_STR_SIZE];
79     snprintf(as_typename, INSTR_DEFAULT_STR_SIZE, "L%d", this->level_);
80     if (this->father_) {
81       this->type_ = simgrid::instr::Type::getOrNull(as_typename, this->father_->type_);
82       if (this->type_ == nullptr) {
83         this->type_ = simgrid::instr::Type::containerNew(as_typename, this->father_->type_);
84       }
85     }else{
86       this->type_ = simgrid::instr::Type::containerNew("0", nullptr);
87     }
88   }else{
89     //otherwise, the name is its kind
90     char typeNameBuff[INSTR_DEFAULT_STR_SIZE];
91     switch (this->kind_) {
92       case simgrid::instr::INSTR_HOST:
93         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "HOST");
94         break;
95       case simgrid::instr::INSTR_LINK:
96         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "LINK");
97         break;
98       case simgrid::instr::INSTR_ROUTER:
99         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "ROUTER");
100         break;
101       case simgrid::instr::INSTR_SMPI:
102         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MPI");
103         break;
104       case simgrid::instr::INSTR_MSG_PROCESS:
105         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_PROCESS");
106         break;
107       case simgrid::instr::INSTR_MSG_VM:
108         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_VM");
109         break;
110       case simgrid::instr::INSTR_MSG_TASK:
111         snprintf (typeNameBuff, INSTR_DEFAULT_STR_SIZE, "MSG_TASK");
112         break;
113       default:
114         THROWF (tracing_error, 0, "new container kind is unknown.");
115         break;
116     }
117     simgrid::instr::Type* type = simgrid::instr::Type::getOrNull(typeNameBuff, this->father_->type_);
118     if (type == nullptr){
119       this->type_ = simgrid::instr::Type::containerNew(typeNameBuff, this->father_->type_);
120     }else{
121       this->type_ = type;
122     }
123   }
124   this->children_ = xbt_dict_new_homogeneous(nullptr);
125   if (this->father_) {
126     xbt_dict_set(this->father_->children_, this->name_, this, nullptr);
127     LogContainerCreation(this);
128   }
129
130   //register all kinds by name
131   if (xbt_dict_get_or_null(allContainers, this->name_) != nullptr) {
132     THROWF(tracing_error, 1, "container %s already present in allContainers data structure", this->name_);
133   }
134
135   xbt_dict_set(allContainers, this->name_, this, nullptr);
136   XBT_DEBUG("Add container name '%s'", this->name_);
137
138   //register NODE types for triva configuration
139   if (this->kind_ == simgrid::instr::INSTR_HOST || this->kind_ == simgrid::instr::INSTR_LINK ||
140       this->kind_ == simgrid::instr::INSTR_ROUTER) {
141     trivaNodeTypes.insert(this->type_->name_);
142   }
143 }
144 simgrid::instr::Container::~Container()
145 {
146   XBT_DEBUG("destroy container %s", name_);
147
148   // obligation to dump previous events because they might
149   // reference the container that is about to be destroyed
150   TRACE_last_timestamp_to_dump = surf_get_clock();
151   TRACE_paje_dump_buffer(1);
152
153   // trace my destruction
154   if (not TRACE_disable_destroy() && this != PJ_container_get_root()) {
155     // do not trace the container destruction if user requests
156     // or if the container is root
157     LogContainerDestruction(this);
158   }
159
160   // remove it from allContainers data structure
161   xbt_dict_remove(allContainers, name_);
162
163   // free
164   xbt_free(name_);
165   xbt_free(id_);
166   xbt_dict_free(&children_);
167 }
168
169 container_t PJ_container_get (const char *name)
170 {
171   container_t ret = PJ_container_get_or_null (name);
172   if (ret == nullptr){
173     THROWF(tracing_error, 1, "container with name %s not found", name);
174   }
175   return ret;
176 }
177
178 container_t PJ_container_get_or_null (const char *name)
179 {
180   return static_cast<container_t>(name != nullptr ? xbt_dict_get_or_null(allContainers, name) : nullptr);
181 }
182
183 container_t PJ_container_get_root ()
184 {
185   return rootContainer;
186 }
187
188 void PJ_container_remove_from_parent (container_t child)
189 {
190   if (child == nullptr){
191     THROWF (tracing_error, 0, "can't remove from parent with a nullptr child");
192   }
193
194   container_t parent = child->father_;
195   if (parent){
196     XBT_DEBUG("removeChildContainer (%s) FromContainer (%s) ", child->name_, parent->name_);
197     xbt_dict_remove(parent->children_, child->name_);
198   }
199 }
200
201 static void recursiveDestroyContainer (container_t container)
202 {
203   if (container == nullptr){
204     THROWF (tracing_error, 0, "trying to recursively destroy a nullptr container");
205   }
206   XBT_DEBUG("recursiveDestroyContainer %s", container->name_);
207   xbt_dict_cursor_t cursor = nullptr;
208   container_t child;
209   char *child_name;
210   xbt_dict_foreach (container->children_, cursor, child_name, child) {
211     recursiveDestroyContainer (child);
212   }
213   delete container;
214 }
215
216 void PJ_container_free_all ()
217 {
218   container_t root = PJ_container_get_root();
219   if (root == nullptr){
220     THROWF (tracing_error, 0, "trying to free all containers, but root is nullptr");
221   }
222   recursiveDestroyContainer (root);
223   rootContainer = nullptr;
224
225   //checks
226   if (not xbt_dict_is_empty(allContainers)) {
227     THROWF(tracing_error, 0, "some containers still present even after destroying all of them");
228   }
229 }