Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
nothing to see here.
[simgrid.git] / src / instr / instr_paje_types.cpp
1 /* Copyright (c) 2012-2020. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "simgrid/Exception.hpp"
8 #include "src/instr/instr_private.hpp"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_paje_types, instr, "Paje tracing event system (types)");
11
12 // to check if variables were previously set to 0, otherwise paje won't simulate them
13 static std::set<std::string> platform_variables;
14
15 namespace simgrid {
16 namespace instr {
17
18 Type::Type(e_event_type event_type, const std::string& name, const std::string& alias, const std::string& color,
19            Type* father)
20     : id_(new_paje_id()), name_(name), color_(color), father_(father)
21 {
22   if (name_.empty() || alias.empty())
23     throw TracingError(XBT_THROW_POINT, "can't create a new type with no name or alias");
24
25   if (father != nullptr){
26     father->children_[alias].reset(this);
27     XBT_DEBUG("new type %s, child of %s", get_cname(), father->get_cname());
28     on_creation(*this, event_type);
29   }
30 }
31
32 void StateType::set_event(const std::string& value_name)
33 {
34   events_.push_back(new StateEvent(get_issuer(), this, PAJE_SetState, get_entity_value(value_name), nullptr));
35 }
36
37 void StateType::push_event(const std::string& value_name, TIData* extra)
38 {
39   events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), extra));
40 }
41
42 void StateType::push_event(const std::string& value_name)
43 {
44   events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), nullptr));
45 }
46
47 void StateType::pop_event()
48 {
49   pop_event(nullptr);
50 }
51
52 void StateType::pop_event(TIData* extra)
53 {
54   events_.push_back(new StateEvent(get_issuer(), this, PAJE_PopState, nullptr, extra));
55 }
56
57 void VariableType::instr_event(double now, double delta, const char* resource, double value)
58 {
59   /* To trace resource utilization, we use AddEvent and SubEvent only. This implies to add a SetEvent first to set the
60    * initial value of all variables for subsequent adds/subs. If we don't do so, the first AddEvent would be added to a
61    * non-determined value, hence causing analysis problems.
62    */
63
64   // create a key considering the resource and variable
65   std::string key = std::string(resource) + get_name();
66
67   // check if key exists: if it doesn't, set the variable to zero and mark this in the global map.
68   if (platform_variables.find(key) == platform_variables.end()) {
69     set_event(now, 0);
70     platform_variables.insert(key);
71   }
72
73   add_event(now, value);
74   sub_event(now + delta, value);
75 }
76
77 void VariableType::set_event(double timestamp, double value)
78 {
79   events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SetVariable, value));
80 }
81
82 void VariableType::add_event(double timestamp, double value)
83 {
84   events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_AddVariable, value));
85 }
86
87 void VariableType::sub_event(double timestamp, double value)
88 {
89   events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SubVariable, value));
90 }
91
92 void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key)
93 {
94   start_event(startContainer, value, key, -1);
95 }
96
97 void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key, int size)
98 {
99   new LinkEvent(get_issuer(), this, PAJE_StartLink, startContainer, value, key, size);
100 }
101
102 void LinkType::end_event(Container* endContainer, const std::string& value, const std::string& key)
103 {
104   new LinkEvent(get_issuer(), this, PAJE_EndLink, endContainer, value, key, -1);
105 }
106
107 Type* Type::by_name(const std::string& name)
108 {
109   Type* ret = nullptr;
110   for (auto const& elm : children_) {
111     if (elm.second->name_ == name) {
112       if (ret != nullptr) {
113         throw TracingError(XBT_THROW_POINT, "there are two children types with the same name?");
114       } else {
115         ret = elm.second.get();
116       }
117     }
118   }
119   if (ret == nullptr)
120     throw TracingError(XBT_THROW_POINT, xbt::string_printf("type with name (%s) not found in father type (%s)",
121                                                            name.c_str(), get_cname()));
122   return ret;
123 }
124
125 void ValueType::add_entity_value(const std::string& name)
126 {
127   add_entity_value(name, "");
128 }
129
130 void ValueType::add_entity_value(const std::string& name, const std::string& color)
131 {
132   if (name.empty())
133     throw TracingError(XBT_THROW_POINT, "can't get a value with no name");
134
135   auto it = values_.find(name);
136   if (it == values_.end()) {
137     XBT_DEBUG("new value %s, child of %s", name.c_str(), get_cname());
138     values_.emplace(name, EntityValue(name, color, this));
139   }
140 }
141
142 EntityValue* ValueType::get_entity_value(const std::string& name)
143 {
144   auto ret = values_.find(name);
145   if (ret == values_.end()) {
146     throw TracingError(XBT_THROW_POINT, xbt::string_printf("value with name (%s) not found in father type (%s)",
147                                                            name.c_str(), get_cname()));
148   }
149   return &ret->second;
150 }
151
152 VariableType* Type::by_name_or_create(const std::string& name, const std::string& color)
153 {
154   auto cont = children_.find(name);
155   std::string mycolor = color.empty() ? "1 1 1" : color;
156   return cont == children_.end() ? new VariableType(name, mycolor, this)
157                                  : static_cast<VariableType*>(cont->second.get());
158 }
159
160 LinkType* Type::by_name_or_create(const std::string& name, Type* source, Type* dest)
161 {
162   std::string alias = name + "-" + std::to_string(source->id_) + "-" + std::to_string(dest->id_);
163   auto it           = children_.find(alias);
164   if (it == children_.end()) {
165     return new LinkType(name, source, dest, alias, this);
166   } else
167     return static_cast<LinkType*>(it->second.get());
168 }
169 } // namespace instr
170 } // namespace simgrid