Logo AND Algorithmique Numérique Distribuée

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