Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1ef7852a84b4ef2a669ec85347cbf92b60c62808
[simgrid.git] / src / mc / mcer_ignore.cpp
1 /* Copyright (c) 2008-2015. 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 <xbt/base.h>
8
9 #include "src/internal_config.h"
10 #include "mc_object_info.h"
11 #include "src/mc/mc_private.h"
12 #include "src/smpi/private.h"
13 #include "src/mc/mc_snapshot.h"
14 #include "src/mc/mc_ignore.h"
15 #include "src/mc/mc_protocol.h"
16 #include "src/mc/mc_client.h"
17
18 #include "src/mc/Frame.hpp"
19 #include "src/mc/Variable.hpp"
20 #include "src/mc/ObjectInformation.hpp"
21
22 extern "C" {
23
24 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mcer_ignore, mc,
25                                 "Logging specific to MC ignore mechanism");
26
27 }
28
29 // ***** Ignore local variables
30
31 static void mc_ignore_local_variable_in_scope(const char *var_name,
32                                               const char *subprogram_name,
33                                               simgrid::mc::Frame* subprogram,
34                                               simgrid::mc::Frame* scope);
35 static void MC_ignore_local_variable_in_object(const char *var_name,
36                                                const char *subprogram_name,
37                                                simgrid::mc::ObjectInformation* info);
38
39 extern "C"
40 void MC_ignore_local_variable(const char *var_name, const char *frame_name)
41 {
42   simgrid::mc::Process* process = &mc_model_checker->process();
43   if (strcmp(frame_name, "*") == 0)
44     frame_name = NULL;
45
46   for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : process->object_infos)
47     MC_ignore_local_variable_in_object(var_name, frame_name, info.get());
48 }
49
50 static void MC_ignore_local_variable_in_object(const char *var_name,
51                                                const char *subprogram_name,
52                                                simgrid::mc::ObjectInformation* info)
53 {
54   for (auto& entry : info->subprograms)
55     mc_ignore_local_variable_in_scope(
56       var_name, subprogram_name, &entry.second, &entry.second);
57 }
58
59 /** \brief Ignore a local variable in a scope
60  *
61  *  Ignore all instances of variables with a given name in
62  *  any (possibly inlined) subprogram with a given namespaced
63  *  name.
64  *
65  *  \param var_name        Name of the local variable (or parameter to ignore)
66  *  \param subprogram_name Name of the subprogram fo ignore (NULL for any)
67  *  \param subprogram      (possibly inlined) Subprogram of the scope
68  *  \param scope           Current scope
69  */
70 static void mc_ignore_local_variable_in_scope(const char *var_name,
71                                               const char *subprogram_name,
72                                               simgrid::mc::Frame* subprogram,
73                                               simgrid::mc::Frame* scope)
74 {
75   // Processing of direct variables:
76
77   // If the current subprogram matches the given name:
78   if (subprogram_name == nullptr ||
79       (!subprogram->name.empty()
80         && subprogram->name == subprogram_name)) {
81
82     // Try to find the variable and remove it:
83     int start = 0;
84     int end = scope->variables.size() - 1;
85
86     // Dichotomic search:
87     while (start <= end) {
88       int cursor = (start + end) / 2;
89       simgrid::mc::Variable* current_var = &scope->variables[cursor];
90
91       int compare = current_var->name.compare(var_name);
92       if (compare == 0) {
93         // Variable found, remove it:
94         scope->variables.erase(scope->variables.begin() + cursor);
95
96         // and start again:
97         start = 0;
98         end = scope->variables.size() - 1;
99       } else if (compare < 0) {
100         start = cursor + 1;
101       } else {
102         end = cursor - 1;
103       }
104     }
105
106   }
107   // And recursive processing in nested scopes:
108   for (simgrid::mc::Frame& nested_scope : scope->scopes) {
109     // The new scope may be an inlined subroutine, in this case we want to use its
110     // namespaced name in recursive calls:
111     simgrid::mc::Frame* nested_subprogram =
112         nested_scope.tag ==
113         DW_TAG_inlined_subroutine ? &nested_scope : subprogram;
114
115     mc_ignore_local_variable_in_scope(var_name, subprogram_name,
116                                       nested_subprogram, &nested_scope);
117   }
118 }