1 /* Copyright (c) 2008-2014. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include "mc_private.h"
9 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ignore, mc,
10 "Logging specific to MC ignore mechanism");
13 /**************************** Global variables ******************************/
14 xbt_dynar_t mc_checkpoint_ignore;
15 extern xbt_dynar_t mc_heap_comparison_ignore;
16 extern xbt_dynar_t stacks_areas;
18 /**************************** Structures ******************************/
19 typedef struct s_mc_stack_ignore_variable {
22 } s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
24 /**************************** Free functions ******************************/
26 static void stack_ignore_variable_free(mc_stack_ignore_variable_t v)
28 xbt_free(v->var_name);
33 static void stack_ignore_variable_free_voidp(void *v)
35 stack_ignore_variable_free((mc_stack_ignore_variable_t) * (void **) v);
38 void heap_ignore_region_free(mc_heap_ignore_region_t r)
43 void heap_ignore_region_free_voidp(void *r)
45 heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
48 static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r)
53 static void checkpoint_ignore_region_free_voidp(void *r)
55 checkpoint_ignore_region_free((mc_checkpoint_ignore_region_t) * (void **) r);
58 /***********************************************************************/
60 void MC_ignore_heap(void *address, size_t size)
63 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
67 mc_heap_ignore_region_t region = NULL;
68 region = xbt_new0(s_mc_heap_ignore_region_t, 1);
69 region->address = address;
74 (char *) ((xbt_mheap_t) std_heap)->heapbase) / BLOCKSIZE + 1;
76 if (((xbt_mheap_t) std_heap)->heapinfo[region->block].type == 0) {
77 region->fragment = -1;
78 ((xbt_mheap_t) std_heap)->heapinfo[region->block].busy_block.ignore++;
81 ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> ((xbt_mheap_t)
83 heapinfo[region->block].type;
84 ((xbt_mheap_t) std_heap)->heapinfo[region->block].busy_frag.ignore[region->
88 if (mc_heap_comparison_ignore == NULL) {
89 mc_heap_comparison_ignore =
90 xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
91 heap_ignore_region_free_voidp);
92 xbt_dynar_push(mc_heap_comparison_ignore, ®ion);
98 unsigned int cursor = 0;
99 mc_heap_ignore_region_t current_region = NULL;
101 int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
103 while (start <= end) {
104 cursor = (start + end) / 2;
106 (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
108 mc_heap_ignore_region_t);
109 if (current_region->address == address) {
110 heap_ignore_region_free(region);
114 } else if (current_region->address < address) {
121 if (current_region->address < address)
122 xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, ®ion);
124 xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, ®ion);
130 void MC_remove_ignore_heap(void *address, size_t size)
133 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
137 unsigned int cursor = 0;
139 int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
140 mc_heap_ignore_region_t region;
141 int ignore_found = 0;
143 while (start <= end) {
144 cursor = (start + end) / 2;
146 (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
148 mc_heap_ignore_region_t);
149 if (region->address == address) {
152 } else if (region->address < address) {
155 if ((char *) region->address <= ((char *) address + size)) {
164 if (ignore_found == 1) {
165 xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
166 MC_remove_ignore_heap(address, size);
174 void MC_ignore_global_variable(const char *name)
177 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
181 xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
183 unsigned int cursor = 0;
184 dw_variable_t current_var;
186 int end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
188 while (start <= end) {
189 cursor = (start + end) / 2;
191 (dw_variable_t) xbt_dynar_get_as(mc_libsimgrid_info->global_variables,
192 cursor, dw_variable_t);
193 if (strcmp(current_var->name, name) == 0) {
194 xbt_dynar_remove_at(mc_libsimgrid_info->global_variables, cursor, NULL);
196 end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
197 } else if (strcmp(current_var->name, name) < 0) {
208 /** \brief Ignore a local variable in a scope
210 * Ignore all instances of variables with a given name in
211 * any (possibly inlined) subprogram with a given namespaced
214 * \param var_name Name of the local variable (or parameter to ignore)
215 * \param subprogram_name Name of the subprogram fo ignore (NULL for any)
216 * \param subprogram (possibly inlined) Subprogram of the scope
217 * \param scope Current scope
219 static void mc_ignore_local_variable_in_scope(const char *var_name,
220 const char *subprogram_name,
221 dw_frame_t subprogram,
224 // Processing of direct variables:
226 // If the current subprogram matche the given name:
227 if (subprogram_name == NULL || strcmp(subprogram_name, subprogram->name) == 0) {
229 // Try to find the variable and remove it:
231 int end = xbt_dynar_length(scope->variables) - 1;
233 // Dichotomic search:
234 while (start <= end) {
235 int cursor = (start + end) / 2;
236 dw_variable_t current_var =
237 (dw_variable_t) xbt_dynar_get_as(scope->variables, cursor,
240 int compare = strcmp(current_var->name, var_name);
242 // Variable found, remove it:
243 xbt_dynar_remove_at(scope->variables, cursor, NULL);
247 end = xbt_dynar_length(scope->variables) - 1;
248 } else if (compare < 0) {
256 // And recursive processing in nested scopes:
258 dw_frame_t nested_scope = NULL;
259 xbt_dynar_foreach(scope->scopes, cursor, nested_scope) {
260 // The new scope may be an inlined subroutine, in this case we want to use its
261 // namespaced name in recursive calls:
262 dw_frame_t nested_subprogram =
264 DW_TAG_inlined_subroutine ? nested_scope : subprogram;
266 mc_ignore_local_variable_in_scope(var_name, subprogram_name,
267 nested_subprogram, nested_scope);
271 static void MC_ignore_local_variable_in_object(const char *var_name,
272 const char *subprogram_name,
273 mc_object_info_t info)
275 xbt_dict_cursor_t cursor2;
278 xbt_dict_foreach(info->subprograms, cursor2, key, frame) {
279 mc_ignore_local_variable_in_scope(var_name, subprogram_name, frame, frame);
283 void MC_ignore_local_variable(const char *var_name, const char *frame_name)
286 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
288 if (strcmp(frame_name, "*") == 0)
293 MC_ignore_local_variable_in_object(var_name, frame_name, mc_libsimgrid_info);
294 if (frame_name != NULL)
295 MC_ignore_local_variable_in_object(var_name, frame_name, mc_binary_info);
302 void MC_new_stack_area(void *stack, char *name, void *context, size_t size)
305 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
309 if (stacks_areas == NULL)
310 stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
312 stack_region_t region = NULL;
313 region = xbt_new0(s_stack_region_t, 1);
314 region->address = stack;
315 region->process_name = strdup(name);
316 region->context = context;
320 (char *) ((xbt_mheap_t) std_heap)->heapbase) / BLOCKSIZE + 1;
321 xbt_dynar_push(stacks_areas, ®ion);
327 void MC_ignore(void *addr, size_t size)
330 int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
334 if (mc_checkpoint_ignore == NULL)
335 mc_checkpoint_ignore =
336 xbt_dynar_new(sizeof(mc_checkpoint_ignore_region_t),
337 checkpoint_ignore_region_free_voidp);
339 mc_checkpoint_ignore_region_t region =
340 xbt_new0(s_mc_checkpoint_ignore_region_t, 1);
344 if (xbt_dynar_is_empty(mc_checkpoint_ignore)) {
345 xbt_dynar_push(mc_checkpoint_ignore, ®ion);
348 unsigned int cursor = 0;
350 int end = xbt_dynar_length(mc_checkpoint_ignore) - 1;
351 mc_checkpoint_ignore_region_t current_region = NULL;
353 while (start <= end) {
354 cursor = (start + end) / 2;
356 (mc_checkpoint_ignore_region_t) xbt_dynar_get_as(mc_checkpoint_ignore,
358 mc_checkpoint_ignore_region_t);
359 if (current_region->addr == addr) {
360 if (current_region->size == size) {
361 checkpoint_ignore_region_free(region);
365 } else if (current_region->size < size) {
370 } else if (current_region->addr < addr) {
377 if (current_region->addr == addr) {
378 if (current_region->size < size) {
379 xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, ®ion);
381 xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);
383 } else if (current_region->addr < addr) {
384 xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, ®ion);
386 xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);