ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
Stressor.cpp
Go to the documentation of this file.
1 /*
2 
3  @copyright
4 
5  <pre>
6 
7  Copyright 2018 Infineon Technologies AG
8 
9  This file is part of ETISS tool, see <https://github.com/tum-ei-eda/etiss>.
10 
11  The initial version of this software has been created with the funding support by the German Federal
12  Ministry of Education and Research (BMBF) in the project EffektiV under grant 01IS13022.
13 
14  Redistribution and use in source and binary forms, with or without modification, are permitted
15  provided that the following conditions are met:
16 
17  1. Redistributions of source code must retain the above copyright notice, this list of conditions and
18  the following disclaimer.
19 
20  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
21  and the following disclaimer in the documentation and/or other materials provided with the distribution.
22 
23  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
24  or promote products derived from this software without specific prior written permission.
25 
26  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
27  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
29  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  POSSIBILITY OF SUCH DAMAGE.
34 
35  </pre>
36 
37  @author Chair of Electronic Design Automation, TUM
38 
39  @version 0.1
40 
41 */
42 
43 #ifndef NO_ETISS
44 #include "etiss/fault/Stressor.h"
45 #include "etiss/Misc.h"
46 #include "etiss/fault/Injector.h"
47 #else
48 #include "fault/Injector.h"
49 #include "fault/Stressor.h"
50 #endif
51 
52 #include <fstream>
53 #include <iostream>
54 #include <map>
55 
56 #if CXX0X_UP_SUPPORTED
57 #include <mutex>
58 #endif
59 
60 namespace etiss
61 {
62 
63 namespace fault
64 {
65 
66 #if CXX0X_UP_SUPPORTED
67 static std::mutex &faults_sync()
68 {
69  static std::mutex mu;
70  return mu;
71 }
72 #endif
73 // Map with all faults found in XML file
74 static std::map<int32_t, Fault> &faults()
75 {
76  static std::map<int32_t, Fault> map;
77  return map;
78 }
79 
80 bool Stressor::loadXML(const std::string &file, const int coreID)
81 {
82 
83 #ifdef NO_ETISS
84  std::cout << std::string("Called etiss::fault::Stressor::loadXML(file=") + file + std::string(")") << std::endl;
85 #else
86  etiss::log(etiss::INFO, std::string("Called etiss::fault::Stressor::loadXML(file=") + file + std::string(")"));
87 #endif
88 
89  coreIDActuallXML = coreID;
90 
91  // Vector which gets the faults of the xml file
92  std::vector<Fault> faults;
93 
94  // open and parse file
95  std::ifstream in;
96  in.open(file.c_str());
97  if (!in.is_open())
98  {
99 #ifdef NO_ETISS
100  std::cout << "etiss::fault::Stressor::loadXML(): Failed open file " << file << std::endl;
101 #else
102  etiss::log(etiss::ERROR, std::string("etiss::fault::Stressor::loadXML:") +
103  std::string(" Failed to open Trigger file ") + file);
104 #endif
105  return false;
106  }
107  if (!etiss::fault::parseXML(faults, in, std::cout))
108  {
109 #ifdef NO_ETISS
110  std::cout << "etiss::fault::Stressor::loadXML: Failed parse file " << file << std::endl;
111 #else
113  std::string("etiss::fault::Stressor::loadXML:") + std::string(" Failed to parse file ") + file);
114 #endif
115  return false;
116  }
117 
118  // add faults into a map -> access with static std::map<int32_t,Fault> &
119  // faults()
120  bool ok = true;
121  for (size_t i = 0; i < faults.size(); ++i)
122  {
123  if (!addFault(faults[i]))
124  {
125 #ifdef NO_ETISS
126  std::cout << "etiss::fault::Stressor::loadXML: Failed to add Fault: " << faults[i].name_ << std::endl;
127 #else
129  std::string("etiss::fault::Stressor::loadXML:") + std::string(" Failed to add Fault "),
130  faults[i]);
131 #endif
132  ok = false;
133  }
134  }
135  return ok;
136 }
137 
138 bool Stressor::addFault(const Fault &f)
139 {
140 #if CXX0X_UP_SUPPORTED
141  std::lock_guard<std::mutex> lock(faults_sync());
142 #endif
143 
144 #ifdef NO_ETISS
145  std::cout << "etiss::fault::Stressor::addFault called." << std::endl;
146 #else
147  etiss::log(etiss::INFO, std::string("etiss::fault::Stressor::addFault called. "));
148 #endif
149 
150  // check if fault already exists
151  std::map<int32_t, Fault>::iterator find = faults().find(f.id_);
152  if (find != faults().end())
153  {
154 #ifdef NO_ETISS
155  std::cout << "etiss::fault::Stressor::addFault: Trigger already exists:" << f.toString() << std::endl;
156 #else
158  std::string("etiss::fault::Stressor::addFault:") + std::string(" Trigger already exists. "), f);
159 #endif
160  return false;
161  }
162 
163  // insert fault into map
164  faults().insert(std::pair<int32_t, Fault>(f.id_, f));
165 
166  // Iterate through triggers of the fault
167  for (std::vector<Trigger>::const_iterator iter = f.triggers.begin(); iter != f.triggers.end(); ++iter)
168  {
169  Injector::ptr iptr = iter->getInjector();
170 
171  if (iptr)
172  {
173 #ifdef NO_ETISS
174  std::cout << "etiss::fault::Stressor::addFault: Added trigger: " << iter->toString() << std::endl;
175 #else
176  etiss::log(etiss::INFO, std::string("etiss::fault::Stressor::addFault:") + std::string(" Added trigger: "),
177  *iter);
178 #endif
179  iptr->addTrigger(*iter, f.id_);
180  }
181  else
182  {
183 #ifdef NO_ETISS
184  std::cout << "etiss::fault::Stressor::addFault: Error: Injector not found for: " << iter->toString()
185  << std::endl;
186 #else
188  std::string("etiss::fault::Stressor::addFault:") + std::string(" Injector not found for "),
189  *iter);
190 #endif
192  }
193  }
194 
195  return true;
196 }
197 
198 bool Stressor::firedTrigger(const Trigger &triggered, int32_t fault_id, Injector *injector, uint64_t time_ps)
199 {
200  etiss::log(etiss::VERBOSE, std::string("etiss::fault::Stressor::firedTrigger() called. "));
201 #if CXX0X_UP_SUPPORTED
202  std::lock_guard<std::mutex> lock(faults_sync());
203 #endif
204 
205  // find fault in fault-map
206  std::map<int32_t, Fault>::iterator find = faults().find(fault_id);
207  if (find != faults().end())
208  {
209  // iterate through the actions of the given fault
210  for (std::vector<etiss::fault::Action>::iterator iter = find->second.actions.begin();
211  iter != find->second.actions.end(); ++iter)
212  {
213  if (iter->getType() == etiss::fault::Action::INJECTION)
214  {
216  addFault(iter->getFault());
217  }
218  else
219  {
220  if (iter->getInjectorAddress().getInjector())
221  {
222 #if CXX0X_UP_SUPPORTED
223  if (iter->getInjectorAddress().getInjector().get() != injector)
224 #else
225  if (iter->getInjectorAddress().getInjector() != injector)
226 #endif
227  {
228 #ifndef NO_ETISS
230  std::string("etiss::fault::Stressor::firedTrigger: Action") +
231  std::string(" injector is not the injector that triggered this event.") +
232  std::string(" threadsafety must be ensured by user."),
233  find->second, *iter);
234 #endif
235  }
236  std::string err;
237  if (!iter->getInjectorAddress().getInjector()->applyAction(find->second, *iter, err))
238  {
239 #ifdef NO_ETISS
240  std::cout << "Stressor::firedTrigger: Failed to apply action. Fault: " << fault_id << " ["
241  << err << "]" << std::endl;
242 #else
243  etiss::log(etiss::ERROR, std::string("Stressor::firedTrigger: Failed to apply action "),
244  find->second, *iter, err);
245 #endif
246  }
247  return true;
248  }
249  else
250  {
251 #ifdef NO_ETISS
252  std::cout << "Stressor::firedTrigger: Failed to find action target. Fault: " << fault_id
253  << std::endl;
254 #else
255  etiss::log(etiss::ERROR, std::string("Stressor::firedTrigger: Failed to find action target"),
256  find->second, *iter);
257 #endif
258  }
259  }
260  }
261  }
262  else
263  {
264 #ifdef NO_ETISS
265  std::cout << "Stressor::firedTrigger: Failed to find triggered Fault: " << fault_id << std::endl;
266 #else
267  etiss::log(etiss::ERROR, std::string("Stressor::firedTrigger: Failed to find triggered Fault: "), fault_id);
268 #endif
269  }
270 
271  return true;
272 }
273 
275 {
276 #if CXX0X_UP_SUPPORTED
277  std::lock_guard<std::mutex> lock(faults_sync());
278 #endif
279  faults().clear();
280 }
281 
282 } // namespace fault
283 
284 } // namespace etiss
contains the fault injector interface class.
general configuration and logging
contains the stressor class that loads and activates faults.
static __inline__ uint64_t
Definition: arm_cde.h:31
static __inline__ int32_t
Definition: arm_mve.h:51
@ INJECTION
an action that injects a fault definition (trigger + actions)
Definition: Action.h:90
std::string toString() const
operator<< can be used.
Definition: Fault.cpp:213
int32_t id_
Definition: Fault.h:99
std::vector< Trigger > triggers
contains the triggers for this fault
Definition: Fault.h:100
void addTrigger(const Trigger &t, int32_t fault_id)
> Triggers to look at in callbacks
Definition: Injector.cpp:204
static bool loadXML(const std::string &file, const int coreID=0)
extracts faults out of the given xml file.
Definition: Stressor.cpp:80
static bool addFault(const Fault &f)
adds a fault to a static map that can be accessed by static std::map<int32_t,Fault> & faults().
Definition: Stressor.cpp:138
static void clear()
clears the fault map.
Definition: Stressor.cpp:274
static bool firedTrigger(const Trigger &firedTrigger, int32_t fault_id, Injector *injector, uint64_t time_ps)
Checks if the given trigger is valid and calls applyAction.
Definition: Stressor.cpp:198
int coreIDActuallXML
Definition: XML.cpp:61
static std::map< int32_t, Fault > & faults()
Definition: Stressor.cpp:74
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition: Benchmark.h:53
@ INFO
Definition: Misc.h:129
@ VERBOSE
Definition: Misc.h:130
@ WARNING
Definition: Misc.h:128
@ ERROR
Definition: Misc.h:127
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition: Misc.cpp:125