Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
try to fix some compilation erros
[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 "internal_config.h"
10 #include "mc_object_info.h"
11 #include "mc/mc_private.h"
12 #include "smpi/private.h"
13 #include "mc/mc_snapshot.h"
14 #include "mc/mc_ignore.h"
15 #include "mc/mc_protocol.h"
16 #include "mc/mc_client.h"
17
18 #include "mc/Frame.hpp"
19 #include "mc/Variable.hpp"
20 #include "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 // ***** Ignore heap chunks
28
29 extern XBT_PRIVATE xbt_dynar_t mc_heap_comparison_ignore;
30
31 static void heap_ignore_region_free(mc_heap_ignore_region_t r)
32 {
33   xbt_free(r);
34 }
35
36 static void heap_ignore_region_free_voidp(void *r)
37 {
38   heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
39 }
40
41
42 XBT_PRIVATE void MC_heap_region_ignore_insert(mc_heap_ignore_region_t region)
43 {
44   if (mc_heap_comparison_ignore == NULL) {
45     mc_heap_comparison_ignore =
46         xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
47                       heap_ignore_region_free_voidp);
48     xbt_dynar_push(mc_heap_comparison_ignore, &region);
49     return;
50   }
51
52   unsigned int cursor = 0;
53   mc_heap_ignore_region_t current_region = NULL;
54   int start = 0;
55   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
56
57   // Find the position where we want to insert the mc_heap_ignore_region_t:
58   while (start <= end) {
59     cursor = (start + end) / 2;
60     current_region =
61         (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
62                                                    cursor,
63                                                    mc_heap_ignore_region_t);
64     if (current_region->address == region->address) {
65       heap_ignore_region_free(region);
66       return;
67     } else if (current_region->address < region->address) {
68       start = cursor + 1;
69     } else {
70       end = cursor - 1;
71     }
72   }
73
74   // Insert it mc_heap_ignore_region_t:
75   if (current_region->address < region->address)
76     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
77   else
78     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
79 }
80
81 XBT_PRIVATE void MC_heap_region_ignore_remove(void *address, size_t size)
82 {
83   unsigned int cursor = 0;
84   int start = 0;
85   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
86   mc_heap_ignore_region_t region;
87   int ignore_found = 0;
88
89   while (start <= end) {
90     cursor = (start + end) / 2;
91     region =
92         (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
93                                                    cursor,
94                                                    mc_heap_ignore_region_t);
95     if (region->address == address) {
96       ignore_found = 1;
97       break;
98     } else if (region->address < address) {
99       start = cursor + 1;
100     } else {
101       if ((char *) region->address <= ((char *) address + size)) {
102         ignore_found = 1;
103         break;
104       } else {
105         end = cursor - 1;
106       }
107     }
108   }
109
110   if (ignore_found == 1) {
111     xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
112     MC_remove_ignore_heap(address, size);
113   }
114 }
115
116 // ***** Ignore global variables
117
118 XBT_PRIVATE void MCer_ignore_global_variable(const char *name)
119 {
120   simgrid::mc::Process* process = &mc_model_checker->process();
121   xbt_assert(!process->object_infos.empty(), "MC subsystem not initialized");
122
123   for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : process->object_infos) {
124
125     // Binary search:
126     int start = 0;
127     int end = info->global_variables.size() - 1;
128     while (start <= end) {
129       unsigned int cursor = (start + end) / 2;
130       simgrid::mc::Variable* current_var = &info->global_variables[cursor];
131       int cmp = current_var->name.compare(name);
132       if (cmp == 0) {
133         info->global_variables.erase(
134           info->global_variables.begin() + cursor);
135         start = 0;
136         end = info->global_variables.size() - 1;
137       } else if (cmp < 0) {
138         start = cursor + 1;
139       } else {
140         end = cursor - 1;
141       }
142     }
143   }
144 }
145
146 // ***** Ignore local variables
147
148 static void mc_ignore_local_variable_in_scope(const char *var_name,
149                                               const char *subprogram_name,
150                                               simgrid::mc::Frame* subprogram,
151                                               simgrid::mc::Frame* scope);
152 static void MC_ignore_local_variable_in_object(const char *var_name,
153                                                const char *subprogram_name,
154                                                simgrid::mc::ObjectInformation* info);
155
156 void MC_ignore_local_variable(const char *var_name, const char *frame_name)
157 {
158   simgrid::mc::Process* process = &mc_model_checker->process();
159   if (strcmp(frame_name, "*") == 0)
160     frame_name = NULL;
161
162   for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : process->object_infos)
163     MC_ignore_local_variable_in_object(var_name, frame_name, info.get());
164 }
165
166 static void MC_ignore_local_variable_in_object(const char *var_name,
167                                                const char *subprogram_name,
168                                                simgrid::mc::ObjectInformation* info)
169 {
170   for (auto& entry : info->subprograms)
171     mc_ignore_local_variable_in_scope(
172       var_name, subprogram_name, &entry.second, &entry.second);
173 }
174
175 /** \brief Ignore a local variable in a scope
176  *
177  *  Ignore all instances of variables with a given name in
178  *  any (possibly inlined) subprogram with a given namespaced
179  *  name.
180  *
181  *  \param var_name        Name of the local variable (or parameter to ignore)
182  *  \param subprogram_name Name of the subprogram fo ignore (NULL for any)
183  *  \param subprogram      (possibly inlined) Subprogram of the scope
184  *  \param scope           Current scope
185  */
186 static void mc_ignore_local_variable_in_scope(const char *var_name,
187                                               const char *subprogram_name,
188                                               simgrid::mc::Frame* subprogram,
189                                               simgrid::mc::Frame* scope)
190 {
191   // Processing of direct variables:
192
193   // If the current subprogram matches the given name:
194   if (subprogram_name == nullptr ||
195       (!subprogram->name.empty()
196         && subprogram->name == subprogram_name)) {
197
198     // Try to find the variable and remove it:
199     int start = 0;
200     int end = scope->variables.size() - 1;
201
202     // Dichotomic search:
203     while (start <= end) {
204       int cursor = (start + end) / 2;
205       simgrid::mc::Variable* current_var = &scope->variables[cursor];
206
207       int compare = current_var->name.compare(var_name);
208       if (compare == 0) {
209         // Variable found, remove it:
210         scope->variables.erase(scope->variables.begin() + cursor);
211
212         // and start again:
213         start = 0;
214         end = scope->variables.size() - 1;
215       } else if (compare < 0) {
216         start = cursor + 1;
217       } else {
218         end = cursor - 1;
219       }
220     }
221
222   }
223   // And recursive processing in nested scopes:
224   for (simgrid::mc::Frame& nested_scope : scope->scopes) {
225     // The new scope may be an inlined subroutine, in this case we want to use its
226     // namespaced name in recursive calls:
227     simgrid::mc::Frame* nested_subprogram =
228         nested_scope.tag ==
229         DW_TAG_inlined_subroutine ? &nested_scope : subprogram;
230
231     mc_ignore_local_variable_in_scope(var_name, subprogram_name,
232                                       nested_subprogram, &nested_scope);
233   }
234 }
235
236 extern XBT_PRIVATE xbt_dynar_t stacks_areas;
237
238 XBT_PRIVATE void MC_stack_area_add(stack_region_t stack_area)
239 {
240   if (stacks_areas == NULL)
241     stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
242   xbt_dynar_push(stacks_areas, &stack_area);
243 }
244
245 }