int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
-void init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2);
+int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2);
int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type, int pointer_level);
void reset_heap_information(void);
int get_pointed_area_size(void *area, int heap);
xbt_dynar_t data);
XBT_PUBLIC(void*) xbt_parmap_next(xbt_parmap_t parmap);
+#ifdef HAVE_MC
+XBT_PUBLIC(xbt_parmap_t) xbt_parmap_mc_new(unsigned int num_workers,
+ e_xbt_parmap_mode_t mode);
+
+XBT_PUBLIC(int) xbt_parmap_mc_apply(xbt_parmap_t parmap,
+ int_f_pvoid_pvoid_t fun,
+ void *data,
+ unsigned int length,
+ void* ref_snapshot);
+#endif
/** \} */
SG_END_DECL()
mc_snapshot_t MC_take_snapshot(){
- int raw_mem = (mmalloc_get_current_heap() == raw_heap);
-
- MC_SET_RAW_MEM;
-
mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1);
snapshot->nb_processes = xbt_swag_size(simix_global->process_list);
MC_dump_checkpoint_ignore(snapshot);
- MC_UNSET_RAW_MEM;
-
- if(raw_mem)
- MC_SET_RAW_MEM;
-
return snapshot;
}
void *p2;
}s_pointers_pair_t, *pointers_pair_t;
-xbt_dynar_t compared_pointers;
+__thread xbt_dynar_t compared_pointers;
/************************** Free functions ****************************/
/********************************************************************/
offset = (char *)current_var->address.address - (char *)start_data_libsimgrid;
res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, current_var->type_origin, r1->size, region_type, start_data, 0);
- if(res == -1){
- xbt_dynar_cursor_rm(variables, &cursor);
- }else if(res == 1){
- XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
+ if(res == 1){
+ XBT_VERB("Global variable %s is different between snapshots", current_var->name);
xbt_dynar_free(&compared_pointers);
+ compared_pointers = NULL;
return 1;
}
}
xbt_dynar_free(&compared_pointers);
+ compared_pointers = NULL;
return 0;
if(xbt_dynar_length(stack1->local_variables) != xbt_dynar_length(stack2->local_variables)){
XBT_VERB("Different number of local variables");
xbt_dynar_free(&compared_pointers);
+ compared_pointers = NULL;
return 1;
}else{
unsigned int cursor = 0;
else
res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_variables_type_binary, mc_variables_type_libsimgrid, current_var1->type, 0, 2, start_data_binary, 0l);
if(res == 1){
- XBT_VERB("Local variable %s (%p - %p) in frame %s is different between snapshots", current_var1->name, (char *)heap1 + offset1, (char *)heap2 + offset2, current_var1->frame);
+ XBT_VERB("Local variable %s in frame %s is different between snapshots", current_var1->name, current_var1->frame);
xbt_dynar_free(&compared_pointers);
+ compared_pointers = NULL;
return res;
}
cursor++;
}
xbt_dynar_free(&compared_pointers);
+ compared_pointers = NULL;
return 0;
}
}
-int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
+int snapshot_compare(void *p1, void *p2){
+
+ mc_snapshot_t s1 = ((mc_pair_t)p1)->graph_state->system_state;
+ mc_snapshot_t s2 = ((mc_pair_t)p2)->graph_state->system_state;
- int raw_mem = (mmalloc_get_current_heap() == raw_heap);
-
- MC_SET_RAW_MEM;
-
int errors = 0;
+ int res_init;
xbt_os_timer_t global_timer = xbt_os_timer_new();
xbt_os_timer_t timer = xbt_os_timer_new();
xbt_os_walltimer_stop(timer);
mc_comp_times->stacks_sizes_comparison_time = xbt_os_timer_elapsed(timer);
}
- XBT_DEBUG("Different size used in stacks : %zu - %zu", size_used1, size_used2);
+ XBT_DEBUG("(%d - %d) Different size used in stacks : %zu - %zu", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num, size_used1, size_used2);
errors++;
is_diff = 1;
#else
#ifdef MC_VERBOSE
- XBT_VERB("Different size used in stacks : %zu - %zu", size_used1, size_used2);
+ XBT_VERB("(%d - %d) Different size used in stacks : %zu - %zu", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num, size_used1, size_used2);
#endif
xbt_os_walltimer_stop(timer);
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
return 1;
#endif
}
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
return 1;
#endif
}
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
return 1;
#endif
}
#endif
/* Init heap information used in heap comparison algorithm */
- init_heap_information((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, s1->to_ignore, s2->to_ignore);
+ res_init = init_heap_information((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, s1->to_ignore, s2->to_ignore);
+ if(res_init == -1){
+ #ifdef MC_DEBUG
+ XBT_DEBUG("(%d - %d) Different heap information", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
+ errors++;
+ #else
+ #ifdef MC_VERBOSE
+ XBT_VERB("(%d - %d) Different heap information", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
+ #endif
+
+ xbt_os_walltimer_stop(global_timer);
+ mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+ xbt_os_timer_free(global_timer);
+
+ return 1;
+ #endif
+ }
+
+ #ifdef MC_DEBUG
+ xbt_os_walltimer_start(timer);
+ #endif
/* Stacks comparison */
unsigned int cursor = 0;
xbt_os_walltimer_stop(timer);
mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer);
}
- XBT_DEBUG("Different local variables between stacks %d", cursor + 1);
+ XBT_DEBUG("(%d - %d) Different local variables between stacks %d", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num, cursor + 1);
errors++;
is_diff = 1;
#else
#ifdef MC_VERBOSE
- XBT_VERB("Different local variables between stacks %d", cursor + 1);
+ XBT_VERB("(%d - %d) Different local variables between stacks %d", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num, cursor + 1);
#endif
reset_heap_information();
xbt_os_walltimer_stop(global_timer);
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
-
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
+
return 1;
#endif
}
#ifdef MC_DEBUG
xbt_os_walltimer_stop(timer);
mc_comp_times->binary_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
- XBT_DEBUG("Different global variables in binary");
+ XBT_DEBUG("(%d - %d) Different global variables in binary", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
errors++;
#else
#ifdef MC_VERBOSE
- XBT_VERB("Different global variables in binary");
+ XBT_VERB("(%d - %d) Different global variables in binary", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
#endif
reset_heap_information();
xbt_os_walltimer_stop(global_timer);
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
-
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
return 1;
#endif
#ifdef MC_DEBUG
xbt_os_walltimer_stop(timer);
mc_comp_times->libsimgrid_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
- XBT_DEBUG("Different global variables in libsimgrid");
+ XBT_DEBUG("(%d - %d) Different global variables in libsimgrid", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
errors++;
#else
#ifdef MC_VERBOSE
- XBT_VERB("Different global variables in libsimgrid");
+ XBT_VERB("(%d - %d) Different global variables in libsimgrid", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
#endif
reset_heap_information();
xbt_os_walltimer_stop(global_timer);
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
-
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
return 1;
#endif
}
-
+
#ifdef MC_DEBUG
xbt_os_walltimer_start(timer);
#endif
#ifdef MC_DEBUG
xbt_os_walltimer_stop(timer);
mc_comp_times->heap_comparison_time = xbt_os_timer_elapsed(timer);
- XBT_DEBUG("Different heap (mmalloc_compare)");
+ XBT_DEBUG("(%d - %d) Different heap (mmalloc_compare)", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
errors++;
#else
#ifdef MC_VERBOSE
- XBT_VERB("Different heap (mmalloc_compare)");
+ XBT_VERB("(%d - %d) Different heap (mmalloc_compare)", ((mc_pair_t)p1)->num, ((mc_pair_t)p2)->num);
#endif
reset_heap_information();
mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
xbt_os_timer_free(global_timer);
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
return 1;
#endif
}else{
print_comparison_times();
#endif
- if(!raw_mem)
- MC_UNSET_RAW_MEM;
-
return errors > 0;
}
mc_state_t mc_current_state = NULL;
char mc_replay_mode = FALSE;
double *mc_time = NULL;
-mc_comparison_times_t mc_comp_times = NULL;
-double mc_snapshot_comparison_time;
+__thread mc_comparison_times_t mc_comp_times = NULL;
+__thread double mc_snapshot_comparison_time;
mc_stats_t mc_stats = NULL;
/* Safety */
else
xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, ®ion);
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
void MC_remove_ignore_heap(void *address, size_t size){
MC_remove_ignore_heap(address, size);
}
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
}
}
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
void MC_ignore_local_variable(const char *var_name, const char *frame_name){
}
}
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
MC_SET_RAW_MEM;
+
if(stacks_areas == NULL)
stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
region->size = size;
region->block = ((char*)stack - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
xbt_dynar_push(stacks_areas, ®ion);
-
- MC_UNSET_RAW_MEM;
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
void MC_ignore(void *addr, size_t size){
MC_get_libsimgrid_plt_section();
MC_get_binary_plt_section();
+ /* Init parmap */
+ parmap = xbt_parmap_mc_new(xbt_os_get_numcores(), XBT_PARMAP_DEFAULT);
+
MC_UNSET_RAW_MEM;
/* Ignore some variables from xbt/ex.h used by exception e for stacks comparison */
MC_ignore_global_variable("smx_current_context_key");
MC_ignore_global_variable("sysv_maestro_context");
MC_ignore_global_variable("counter"); /* Static variable used for tracing */
+
if(raw_mem_set)
MC_SET_RAW_MEM;
xbt_dynar_t acceptance_pairs;
xbt_dynar_t visited_pairs;
xbt_dynar_t successors;
-
+xbt_parmap_t parmap;
/********* Static functions *********/
return values;
}
+static int get_search_interval(xbt_dynar_t all_pairs, mc_pair_t pair, int *min, int *max){
+
+ int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+ MC_SET_RAW_MEM;
+
+ int cursor = 0, previous_cursor, next_cursor;
+ mc_pair_t pair_test;
+ int start = 0;
+ int end = xbt_dynar_length(all_pairs) - 1;
+
+ while(start <= end){
+ cursor = (start + end) / 2;
+ pair_test = (mc_pair_t)xbt_dynar_get_as(all_pairs, cursor, mc_pair_t);
+ if(pair_test->nb_processes < pair->nb_processes){
+ start = cursor + 1;
+ }else if(pair_test->nb_processes > pair->nb_processes){
+ end = cursor - 1;
+ }else{
+ if(pair_test->heap_bytes_used < pair->heap_bytes_used){
+ start = cursor +1;
+ }else if(pair_test->heap_bytes_used > pair->heap_bytes_used){
+ end = cursor - 1;
+ }else{
+ *min = *max = cursor;
+ previous_cursor = cursor - 1;
+ while(previous_cursor >= 0){
+ pair_test = (mc_pair_t)xbt_dynar_get_as(all_pairs, previous_cursor, mc_pair_t);
+ if(pair_test->nb_processes != pair->nb_processes || pair_test->heap_bytes_used != pair->heap_bytes_used)
+ break;
+ *min = previous_cursor;
+ previous_cursor--;
+ }
+ next_cursor = cursor + 1;
+ while(next_cursor < xbt_dynar_length(all_pairs)){
+ pair_test = (mc_pair_t)xbt_dynar_get_as(all_pairs, next_cursor, mc_pair_t);
+ if(pair_test->nb_processes != pair->nb_processes || pair_test->heap_bytes_used != pair->heap_bytes_used)
+ break;
+ *max = next_cursor;
+ next_cursor++;
+ }
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
+ return -1;
+ }
+ }
+ }
+
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
+
+ return cursor;
+}
+
static int is_reached_acceptance_pair(mc_pair_t pair){
int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+ MC_SET_RAW_MEM;
if(xbt_dynar_is_empty(acceptance_pairs)){
- MC_SET_RAW_MEM;
if(pair->graph_state->system_state == NULL){
pair->graph_state->system_state = MC_take_snapshot();
pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
}
xbt_dynar_push(acceptance_pairs, &pair);
- MC_UNSET_RAW_MEM;
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
return -1;
}else{
- MC_SET_RAW_MEM;
-
if(pair->graph_state->system_state == NULL){
pair->graph_state->system_state = MC_take_snapshot();
pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
}
- size_t current_bytes_used = pair->heap_bytes_used;
- int current_nb_processes = pair->nb_processes;
-
- unsigned int cursor = 0;
- int previous_cursor = 0, next_cursor = 0;
- int start = 0;
- int end = xbt_dynar_length(acceptance_pairs) - 1;
-
- mc_pair_t pair_test = NULL;
- size_t bytes_used_test;
- int nb_processes_test;
- int same_processes_and_bytes_not_found = 1;
+ int min = -1, max = -1, index;
+ int res;
+ mc_pair_t pair_test;
+
+ index = get_search_interval(acceptance_pairs, pair, &min, &max);
- while(start <= end && same_processes_and_bytes_not_found){
- cursor = (start + end) / 2;
- pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- nb_processes_test = pair_test->nb_processes;
- if(nb_processes_test < current_nb_processes)
- start = cursor + 1;
- else if(nb_processes_test > current_nb_processes)
- end = cursor - 1;
- else if(nb_processes_test == current_nb_processes){
- if(bytes_used_test < current_bytes_used)
- start = cursor + 1;
- else if(bytes_used_test > current_bytes_used)
- end = cursor - 1;
- else if(bytes_used_test == current_bytes_used){
- same_processes_and_bytes_not_found = 0;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- XBT_DEBUG("Compare with state %d", pair_test->num);
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair_test->num;
- }
- }
- }
- /* Search another pair with same number of bytes used in std_heap */
- previous_cursor = cursor - 1;
- while(previous_cursor >= 0){
- pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, previous_cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- if(bytes_used_test != current_bytes_used)
- break;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- XBT_DEBUG("Compare with state %d", pair_test->num);
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair_test->num;
- }
- }
- }
- previous_cursor--;
- }
- next_cursor = cursor + 1;
- while(next_cursor < xbt_dynar_length(acceptance_pairs)){
- pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, next_cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- if(bytes_used_test != current_bytes_used)
- break;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- XBT_DEBUG("Compare with state %d", pair_test->num);
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair_test->num;
- }
- }
- }
- next_cursor++;
- }
- }
+ if(min != -1 && max != -1){ /* Acceptance pair with same number of processes and same heap bytes used exists */
+ res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(acceptance_pairs, min), (max-min)+1, pair);
+ if(res != -1){
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
+ return ((mc_pair_t)xbt_dynar_get_as(acceptance_pairs, (min+res)-1, mc_pair_t))->num;
+ }
+ xbt_dynar_insert_at(acceptance_pairs, min, &pair);
+ }else{
+ pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, index, mc_pair_t);
+ if(pair_test->nb_processes < pair->nb_processes){
+ xbt_dynar_insert_at(acceptance_pairs, index+1, &pair);
+ }else{
+ if(pair_test->heap_bytes_used < pair->heap_bytes_used)
+ xbt_dynar_insert_at(acceptance_pairs, index + 1, &pair);
+ else
+ xbt_dynar_insert_at(acceptance_pairs, index, &pair);
}
}
- pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
-
- if(bytes_used_test < current_bytes_used)
- xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
- else
- xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
-
-
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
return -1;
int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+ MC_SET_RAW_MEM;
+
if(xbt_dynar_is_empty(acceptance_pairs)){
- MC_SET_RAW_MEM;
if(pair->graph_state->system_state == NULL){
pair->graph_state->system_state = MC_take_snapshot();
pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
}
xbt_dynar_push(acceptance_pairs, &pair);
- MC_UNSET_RAW_MEM;
}else{
- MC_SET_RAW_MEM;
-
if(pair->graph_state->system_state == NULL){
pair->graph_state->system_state = MC_take_snapshot();
pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
size_t current_bytes_used = pair->heap_bytes_used;
int current_nb_processes = pair->nb_processes;
- unsigned int cursor = 0;
+ int cursor = 0;
int start = 0;
int end = xbt_dynar_length(acceptance_pairs) - 1;
if(bytes_used_test < current_bytes_used)
xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
else
- xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
-
- MC_UNSET_RAW_MEM;
-
+ xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
}
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
static void remove_acceptance_pair(mc_pair_t pair){
+ int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+ MC_SET_RAW_MEM;
+
unsigned int cursor = 0;
mc_pair_t pair_test;
int pair_found = 0;
}
}
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
}
static int is_visited_pair(mc_pair_t pair){
int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+ MC_SET_RAW_MEM;
+
if(xbt_dynar_is_empty(visited_pairs)){
- MC_SET_RAW_MEM;
if(pair->graph_state->system_state == NULL)
pair->graph_state->system_state = MC_take_snapshot();
xbt_dynar_push(visited_pairs, &pair);
- MC_UNSET_RAW_MEM;
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
return -1;
}else{
- MC_SET_RAW_MEM;
-
if(pair->graph_state->system_state == NULL)
pair->graph_state->system_state = MC_take_snapshot();
-
- size_t current_bytes_used = pair->heap_bytes_used;
- int current_nb_processes = pair->nb_processes;
-
- unsigned int cursor = 0;
- int previous_cursor = 0, next_cursor = 0;
- int start = 0;
- int end = xbt_dynar_length(visited_pairs) - 1;
-
- mc_pair_t pair_test = NULL;
- size_t bytes_used_test;
- int nb_processes_test;
- int same_processes_and_bytes_not_found = 1;
- while(start <= end && same_processes_and_bytes_not_found){
- cursor = (start + end) / 2;
- pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- nb_processes_test = pair_test->nb_processes;
- if(nb_processes_test < current_nb_processes)
- start = cursor + 1;
- else if(nb_processes_test > current_nb_processes)
- end = cursor - 1;
- else if(nb_processes_test == current_nb_processes){
- if(bytes_used_test < current_bytes_used)
- start = cursor + 1;
- else if(bytes_used_test > current_bytes_used)
- end = cursor - 1;
- else if(bytes_used_test == current_bytes_used){
- same_processes_and_bytes_not_found = 0;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(pair_test->other_num == -1)
- pair->other_num = pair_test->num;
- else
- pair->other_num = pair_test->other_num;
- if(dot_output == NULL)
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
- else
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
- xbt_dynar_remove_at(visited_pairs, cursor, NULL);
- xbt_dynar_insert_at(visited_pairs, cursor, &pair);
- pair_test->visited_removed = 1;
- if(pair_test->stack_removed && pair_test->visited_removed){
- if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
- if(pair_test->acceptance_removed){
- MC_pair_delete(pair_test);
- }
- }else{
- MC_pair_delete(pair_test);
- }
- }
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair->other_num;
- }
- }
- }
- /* Search another pair with same number of bytes used in std_heap */
- previous_cursor = cursor - 1;
- while(previous_cursor >= 0){
- pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, previous_cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- if(bytes_used_test != current_bytes_used)
- break;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(pair_test->other_num == -1)
- pair->other_num = pair_test->num;
- else
- pair->other_num = pair_test->other_num;
- if(dot_output == NULL)
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
- else
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
- xbt_dynar_remove_at(visited_pairs, previous_cursor, NULL);
- xbt_dynar_insert_at(visited_pairs, previous_cursor, &pair);
- pair_test->visited_removed = 1;
- if(pair_test->stack_removed && pair_test->visited_removed){
- if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
- if(pair_test->acceptance_removed){
- MC_pair_delete(pair_test);
- }
- }else{
- MC_pair_delete(pair_test);
- }
- }
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair->other_num;
- }
- }
- }
- previous_cursor--;
- }
- next_cursor = cursor + 1;
- while(next_cursor < xbt_dynar_length(visited_pairs)){
- pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, next_cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
- if(bytes_used_test != current_bytes_used)
- break;
- if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
- if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
- if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
- if(pair_test->other_num == -1)
- pair->other_num = pair_test->num;
- else
- pair->other_num = pair_test->other_num;
- if(dot_output == NULL)
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
- else
- XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
- xbt_dynar_remove_at(visited_pairs, next_cursor, NULL);
- xbt_dynar_insert_at(visited_pairs, next_cursor, &pair);
- pair_test->visited_removed = 1;
- if(pair_test->stack_removed && pair_test->visited_removed){
- if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
- if(pair_test->acceptance_removed){
- MC_pair_delete(pair_test);
- }
- }else{
- MC_pair_delete(pair_test);
- }
- }
- if(raw_mem_set)
- MC_SET_RAW_MEM;
- else
- MC_UNSET_RAW_MEM;
- return pair->other_num;
- }
- }
+ int min = -1, max = -1, index;
+ int res;
+ mc_pair_t pair_test;
+
+ index = get_search_interval(visited_pairs, pair, &min, &max);
+
+ if(min != -1 && max != -1){ /* Visited pair with same number of processes and same heap bytes used exists */
+ res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_pairs, min), (max-min)+1, pair);
+ if(res != -1){
+ pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, (min+res)-1, mc_pair_t);
+ if(pair_test->other_num == -1)
+ pair->other_num = pair_test->num;
+ else
+ pair->other_num = pair_test->other_num;
+ if(dot_output == NULL)
+ XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
+ else
+ XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
+ xbt_dynar_remove_at(visited_pairs, (min + res) - 1, NULL);
+ xbt_dynar_insert_at(visited_pairs, (min+res) - 1, &pair);
+ pair_test->visited_removed = 1;
+ if(pair_test->stack_removed && pair_test->visited_removed){
+ if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
+ if(pair_test->acceptance_removed){
+ MC_pair_delete(pair_test);
}
- next_cursor++;
+ }else{
+ MC_pair_delete(pair_test);
}
}
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
+ return pair->other_num;
+ }
+ xbt_dynar_insert_at(visited_pairs, min, &pair);
+ }else{
+ pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, index, mc_pair_t);
+ if(pair_test->nb_processes < pair->nb_processes){
+ xbt_dynar_insert_at(visited_pairs, index+1, &pair);
+ }else{
+ if(pair_test->heap_bytes_used < pair->heap_bytes_used)
+ xbt_dynar_insert_at(visited_pairs, index + 1, &pair);
+ else
+ xbt_dynar_insert_at(visited_pairs, index, &pair);
}
}
- pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
- bytes_used_test = pair_test->heap_bytes_used;
-
- if(bytes_used_test < current_bytes_used)
- xbt_dynar_insert_at(visited_pairs, cursor + 1, &pair);
- else
- xbt_dynar_insert_at(visited_pairs, cursor, &pair);
-
if(xbt_dynar_length(visited_pairs) > _sg_mc_visited){
int min = mc_stats->expanded_states;
unsigned int cursor2 = 0;
- unsigned int index = 0;
+ unsigned int index2 = 0;
xbt_dynar_foreach(visited_pairs, cursor2, pair_test){
if(pair_test->num < min){
index = cursor2;
min = pair_test->num;
}
}
- xbt_dynar_remove_at(visited_pairs, index, &pair_test);
+ xbt_dynar_remove_at(visited_pairs, index2, &pair_test);
pair_test->visited_removed = 1;
if(pair_test->stack_removed && pair_test->acceptance_removed && pair_test->visited_removed)
MC_pair_delete(pair_test);
}
- MC_UNSET_RAW_MEM;
-
- if(raw_mem_set)
- MC_SET_RAW_MEM;
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
return -1;
-
+
}
-
}
static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l, xbt_dynar_t atomic_propositions_values){
/* Update current state in buchi automaton */
_mc_property_automaton->current_state = current_pair->automaton_state;
- XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness), current_pair->search_cycle);
+ XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d, interleave size %d)", xbt_fifo_size(mc_stack_liveness), current_pair->search_cycle, MC_state_interleave_size(current_pair->graph_state));
mc_stats->visited_pairs++;
#include "msg/msg.h"
#include "msg/datatypes.h"
#include "xbt/strbuff.h"
+#include "xbt/parmap.h"
/****************************** Snapshots ***********************************/
extern double *mc_time;
extern FILE *dot_output;
extern const char* colors[13];
+extern xbt_parmap_t parmap;
extern int user_max_depth_reached;
double hash_local_variables_comparison_time;
}s_mc_comparison_times_t, *mc_comparison_times_t;
-extern mc_comparison_times_t mc_comp_times;
-extern double mc_snapshot_comparison_time;
+extern __thread mc_comparison_times_t mc_comp_times;
+extern __thread double mc_snapshot_comparison_time;
-int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2);
+int snapshot_compare(void *p1, void *p2);
int SIMIX_pre_mc_compare_snapshots(smx_simcall_t simcall, mc_snapshot_t s1, mc_snapshot_t s2);
void print_comparison_times(void);
/* Set size used in the fragment to -1 */
mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = -1;
mdp->heapinfo[block].busy_frag.ignore[frag_nb] = 0;
- mdp->heapinfo[block].busy_frag.equal_to[frag_nb] = NULL;
// fprintf(stderr,"nfree:%zu capa:%d\n", mdp->heapinfo[block].busy_frag.nfree,(BLOCKSIZE >> type));
if (mdp->heapinfo[block].busy_frag.nfree ==
mdp->heapinfo[block].type = 0;
mdp->heapinfo[block].busy_block.size = 1;
mdp->heapinfo[block].busy_block.busy_size = 0;
- mdp->heapinfo[block].busy_block.equal_to = NULL;
/* Keep the statistics accurate. */
mdp -> heapstats.chunks_used++;
/*********************************** Heap comparison ***********************************/
/***************************************************************************************/
-void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL;
-malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL;
-size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
-xbt_dynar_t to_ignore1 = NULL, to_ignore2 = NULL;
+__thread void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL;
+__thread malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL;
+__thread size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
+__thread xbt_dynar_t to_ignore1 = NULL, to_ignore2 = NULL;
+__thread heap_area_t **equals_to1, **equals_to2;
/*********************************** Free functions ************************************/
xbt_dynar_foreach(list, cursor, current_pair){
if(current_pair->fragment1 != -1){
-
- if(heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] != NULL){
- previous_area = heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1];
- heap_area_free(heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
- heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
- heap_area_free(previous_area);
+
+ if(equals_to1[current_pair->block1][current_pair->fragment1] != NULL){
+ previous_area = equals_to1[current_pair->block1][current_pair->fragment1];
+ heap_area_free(equals_to2[previous_area->block][previous_area->fragment]);
+ equals_to2[previous_area->block][previous_area->fragment] = NULL;
+ heap_area_free(previous_area);
}
- if(heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] != NULL){
- previous_area = heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2];
- heap_area_free(heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
- heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
+ if(equals_to2[current_pair->block2][current_pair->fragment2] != NULL){
+ previous_area = equals_to2[current_pair->block2][current_pair->fragment2];
+ heap_area_free(equals_to1[previous_area->block][previous_area->fragment]);
+ equals_to1[previous_area->block][previous_area->fragment] = NULL;
heap_area_free(previous_area);
}
- heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
- heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
+ equals_to1[current_pair->block1][current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
+ equals_to2[current_pair->block2][current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
}else{
- if(heapinfo1[current_pair->block1].busy_block.equal_to != NULL){
- previous_area = heapinfo1[current_pair->block1].busy_block.equal_to;
- heap_area_free(heapinfo2[previous_area->block].busy_block.equal_to);
- heapinfo2[previous_area->block].busy_block.equal_to = NULL;
+ if(equals_to1[current_pair->block1][0] != NULL){
+ previous_area = equals_to1[current_pair->block1][0];
+ heap_area_free(equals_to2[previous_area->block][0]);
+ equals_to2[previous_area->block][0] = NULL;
heap_area_free(previous_area);
}
- if(heapinfo2[current_pair->block2].busy_block.equal_to != NULL){
- previous_area = heapinfo2[current_pair->block2].busy_block.equal_to;
- heap_area_free(heapinfo1[previous_area->block].busy_block.equal_to);
- heapinfo1[previous_area->block].busy_block.equal_to = NULL;
+ if(equals_to2[current_pair->block2][0] != NULL){
+ previous_area = equals_to2[current_pair->block2][0];
+ heap_area_free(equals_to1[previous_area->block][0]);
+ equals_to1[previous_area->block][0] = NULL;
heap_area_free(previous_area);
}
- heapinfo1[current_pair->block1].busy_block.equal_to = new_heap_area(current_pair->block2, current_pair->fragment2);
- heapinfo2[current_pair->block2].busy_block.equal_to = new_heap_area(current_pair->block1, current_pair->fragment1);
+ equals_to1[current_pair->block1][0] = new_heap_area(current_pair->block2, current_pair->fragment2);
+ equals_to2[current_pair->block2][0] = new_heap_area(current_pair->block1, current_pair->fragment1);
}
}
static int equal_blocks(int b1, int b2){
- if(heapinfo1[b1].busy_block.equal_to != NULL){
- if(heapinfo2[b2].busy_block.equal_to != NULL){
- if(((heap_area_t)(heapinfo1[b1].busy_block.equal_to))->block == b2 && ((heap_area_t)(heapinfo2[b2].busy_block.equal_to))->block == b1)
- return 1;
- }
- }
+
+ if(equals_to1[b1][0]->block == b2 && equals_to2[b2][0]->block == b1)
+ return 1;
+
return 0;
}
static int equal_fragments(int b1, int f1, int b2, int f2){
- if(heapinfo1[b1].busy_frag.equal_to[f1] != NULL){
- if(heapinfo2[b2].busy_frag.equal_to[f2] != NULL){
- if(((heap_area_t)(heapinfo1[b1].busy_frag.equal_to[f1]))->block == b2 && ((heap_area_t)(heapinfo2[b2].busy_frag.equal_to[f2]))->block == b1 && ((heap_area_t)(heapinfo1[b1].busy_frag.equal_to[f1]))->fragment == f2 && ((heap_area_t)(heapinfo2[b2].busy_frag.equal_to[f2]))->fragment == f1)
- return 1;
- }
- }
+
+ if(equals_to1[b1][f1]->block == b2 && equals_to1[b1][f1]->fragment == f2 && equals_to2[b2][f2]->block == b1 && equals_to2[b2][f2]->fragment == f1)
+ return 1;
+
return 0;
}
-void init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
+int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
+
+ if((((struct mdesc *)heap1)->heaplimit != ((struct mdesc *)heap2)->heaplimit) || ((((struct mdesc *)heap1)->heapsize != ((struct mdesc *)heap2)->heapsize) ))
+ return -1;
+
+ int i, j;
heaplimit = ((struct mdesc *)heap1)->heaplimit;
to_ignore1 = i1;
to_ignore2 = i2;
+ equals_to1 = malloc(heaplimit * sizeof(heap_area_t *));
+ for(i=0; i<=heaplimit; i++){
+ equals_to1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+ for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++)
+ equals_to1[i][j] = NULL;
+ }
+
+
+ equals_to2 = malloc(heaplimit * sizeof(heap_area_t *));
+ for(i=0; i<=heaplimit; i++){
+ equals_to2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+ for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++)
+ equals_to2[i][j] = NULL;
+ }
+
if(MC_is_active()){
MC_ignore_global_variable("heaplimit");
MC_ignore_global_variable("s_heap");
MC_ignore_global_variable("heapsize2");
MC_ignore_global_variable("to_ignore1");
MC_ignore_global_variable("to_ignore2");
+ MC_ignore_global_variable("equals_to1");
+ MC_ignore_global_variable("equals_to2");
}
+ return 0;
+
}
void reset_heap_information(){
size_t i = 0, j;
- while(i<=heaplimit){
- if(heapinfo1[i].type == 0){
- heap_area_free(heapinfo1[i].busy_block.equal_to);
- heapinfo1[i].busy_block.equal_to = NULL;
- }else if(heapinfo1[i].type > 0){
- for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
- heap_area_free(heapinfo1[i].busy_frag.equal_to[j]);
- heapinfo1[i].busy_frag.equal_to[j] = NULL;
- }
- }
- i++;
+ for(i=0; i<heaplimit; i++){
+ for(j=0; j<MAX_FRAGMENT_PER_BLOCK;j++){
+ heap_area_free(equals_to1[i][j]);
+ equals_to1[i][j] = NULL;
+ heap_area_free(equals_to2[i][j]);
+ equals_to2[i][j] = NULL;
+ }
}
- i = 0;
-
- while(i<=heaplimit){
- if(heapinfo2[i].type == 0){
- heap_area_free(heapinfo2[i].busy_block.equal_to);
- heapinfo2[i].busy_block.equal_to = NULL;
- }else if(heapinfo2[i].type > 0){
- for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
- heap_area_free(heapinfo2[i].busy_frag.equal_to[j]);
- heapinfo2[i].busy_frag.equal_to[j] = NULL;
- }
- }
- i++;
- }
+ free(equals_to1);
+ free(equals_to2);
s_heap = NULL, heapbase1 = NULL, heapbase2 = NULL;
heapinfo1 = NULL, heapinfo2 = NULL;
heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
to_ignore1 = NULL, to_ignore2 = NULL;
+ equals_to1 = NULL, equals_to2 = NULL;
}
int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
- if(heap1 == NULL && heap1 == NULL){
+ if(heap1 == NULL && heap2 == NULL){
XBT_DEBUG("Malloc descriptors null");
return 0;
}
- if(heap1->heaplimit != heap2->heaplimit){
- XBT_DEBUG("Different limit of valid info table indices");
- return 1;
- }
-
/* Start comparison */
size_t i1, i2, j1, j2, k;
- size_t current_block = -1; /* avoid "maybe uninitialized" warning */
- size_t current_fragment;
void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
int nb_diff1 = 0, nb_diff2 = 0;
while(i1 <= heaplimit){
- current_block = i1;
-
if(heapinfo1[i1].type == -1){ /* Free block */
i1++;
continue;
if(is_stack(addr_block1)){
for(k=0; k < heapinfo1[i1].busy_block.size; k++)
- heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i1, -1);
+ equals_to1[i1+k][0] = new_heap_area(i1, -1);
for(k=0; k < heapinfo2[i1].busy_block.size; k++)
- heapinfo2[i1+k].busy_block.equal_to = new_heap_area(i1, -1);
- i1 = i1 + heapinfo1[current_block].busy_block.size;
+ equals_to2[i1+k][0] = new_heap_area(i1, -1);
+ i1 += heapinfo1[i1].busy_block.size;
continue;
}
- if(heapinfo1[i1].busy_block.equal_to != NULL){
+ if(equals_to1[i1][0] != NULL){
i1++;
continue;
}
res_compare = 0;
/* Try first to associate to same block in the other heap */
- if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+ if(heapinfo2[i1].type == heapinfo1[i1].type){
- if(heapinfo2[current_block].busy_block.equal_to == NULL){
-
- addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
+ if(equals_to2[i1][0] == NULL){
+
+ addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
- res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
+ res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0);
if(res_compare == 0){
- for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
- heapinfo2[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
- for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
- heapinfo1[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
+ for(k=1; k < heapinfo2[i1].busy_block.size; k++)
+ equals_to2[i1+k][0] = new_heap_area(i1, -1);
+ for(k=1; k < heapinfo1[i1].busy_block.size; k++)
+ equals_to1[i1+k][0] = new_heap_area(i1, -1);
equal = 1;
- i1 = i1 + heapinfo1[current_block].busy_block.size;
+ i1 += heapinfo1[i1].busy_block.size;
}
xbt_dynar_reset(previous);
addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
- if(i2 == current_block){
+ if(i2 == i1){
i2++;
continue;
}
i2++;
continue;
}
-
- if(heapinfo2[i2].busy_block.equal_to != NULL){
+
+ if(equals_to2[i2][0] != NULL){
i2++;
continue;
}
- res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); /*FIXME */
+ res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0);
if(res_compare == 0){
for(k=1; k < heapinfo2[i2].busy_block.size; k++)
- heapinfo2[i2+k].busy_block.equal_to = new_heap_area(i1, -1);
+ equals_to2[i2+k][0] = new_heap_area(i1, -1);
for(k=1; k < heapinfo1[i1].busy_block.size; k++)
- heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i2, -1);
+ equals_to1[i1+k][0] = new_heap_area(i2, -1);
equal = 1;
- i1 = i1 + heapinfo1[i1].busy_block.size;
+ i1 += heapinfo1[i1].busy_block.size;
}
xbt_dynar_reset(previous);
for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
- current_fragment = j1;
-
if(heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
continue;
- if(heapinfo1[i1].busy_frag.equal_to[j1] != NULL)
+ if(equals_to1[i1][j1] != NULL)
continue;
addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
equal = 0;
/* Try first to associate to same fragment in the other heap */
- if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+ if(heapinfo2[i1].type == heapinfo1[i1].type){
- if(heapinfo2[current_block].busy_frag.equal_to[current_fragment] == NULL){
-
- addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
- addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << ((xbt_mheap_t)s_heap)->heapinfo[current_block].type));
+ if(equals_to2[i1][j1] == NULL){
- res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
+ addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
+ addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)s_heap)->heapinfo[i1].type));
+
+ res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0);
if(res_compare == 0)
equal = 1;
while(i2 <= heaplimit && !equal){
-
if(heapinfo2[i2].type <= 0){
i2++;
continue;
for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
- if(i2 == current_block && j2 == current_fragment)
+ if(i2 == i1 && j2 == j1)
+ continue;
+
+ if(equals_to2[i2][j2] != NULL)
continue;
-
- if(heapinfo2[i2].busy_frag.equal_to[j2] != NULL)
- continue;
addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
- addr_frag2 = (void*) ((char *)addr_block2 + (j2 << ((xbt_mheap_t)s_heap)->heapinfo[i2].type));
+ addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)s_heap)->heapinfo[i2].type));
- res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
+ res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0);
if(res_compare == 0){
equal = 1;
}
- if(heapinfo1[i1].busy_frag.equal_to[j1] == NULL){
- XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p, ignore %d)\n", i1, j1, heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1, heapinfo1[i1].busy_frag.ignore[j1]);
+ if(!equal){
+ XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n", i1, j1, heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1);
i2 = heaplimit + 1;
i1 = heaplimit + 1;
nb_diff1++;
while(i<=heaplimit){
if(heapinfo1[i].type == 0){
- if(current_block == heaplimit){
+ if(i1 == heaplimit){
if(heapinfo1[i].busy_block.busy_size > 0){
- if(heapinfo1[i].busy_block.equal_to == NULL){
+ if(equals_to1[i][0] == NULL){
if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, heapinfo1[i].busy_block.busy_size);
addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
real_addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
- if(current_block == heaplimit){
+ if(i1== heaplimit){
if(heapinfo1[i].busy_frag.frag_size[j] > 0){
- if(heapinfo1[i].busy_frag.equal_to[j] == NULL){
+ if(equals_to1[i][j] == NULL){
if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
i++;
}
- if(current_block == heaplimit)
+ if(i1 == heaplimit)
XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
i = 1;
while(i<=heaplimit){
if(heapinfo2[i].type == 0){
- if(current_block == heaplimit){
+ if(i1 == heaplimit){
if(heapinfo2[i].busy_block.busy_size > 0){
- if(heapinfo2[i].busy_block.equal_to == NULL){
+ if(equals_to2[i][0] == NULL){
if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, heapinfo2[i].busy_block.busy_size);
addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
real_addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
- if(current_block == heaplimit){
+ if(i1 == heaplimit){
if(heapinfo2[i].busy_frag.frag_size[j] > 0){
- if(heapinfo2[i].busy_frag.equal_to[j] == NULL){
+ if(equals_to2[i][j] == NULL){
if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
real_addr_frag2 = (void*) ((char *)real_addr_block2 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
i++;
}
- if(current_block == heaplimit)
+ if(i1 == heaplimit)
XBT_DEBUG("Number of blocks/fragments not found in heap2 : %d", nb_diff2);
xbt_dynar_free(&previous);
if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1))
return 0;
if(strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */
- return (memcmp(area1, area2, area_size) != 0);
+ return (memcmp(area1, area2, area_size) != 0);
}else{
if(area_size != -1 && type->size != area_size)
return -1;
res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_types, all_types, type->dw_type_id, type->size, check_ignore, pointer_level);
else
res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, all_types, other_types, type->dw_type_id, type->size, check_ignore, pointer_level);
- if(res != 0)
+ if(res == 1)
return res;
}
break;
res = compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level);
else
res = (addr_pointed1 != addr_pointed2);
- if(res != 0)
+ if(res == 1)
return res;
}
}else{
res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, other_types, all_types, type_id, -1, check_ignore, 0);
else
res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, all_types, other_types, type_id, -1, check_ignore, 0);
- if(res != 0)
+ if(res == 1)
return res;
}
}else{
res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_types, all_types, member->dw_type_id, -1, check_ignore, 0);
else
res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, all_types, other_types, member->dw_type_id, -1, check_ignore, 0);
- if(res != 0)
+ if(res == 1)
return res;
}
}
void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
void *area1_to_compare, *area2_to_compare;
+ dw_type_t type = NULL;
+ char *type_desc;
int match_pairs = 0;
addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)heapbase1));
addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)heapbase2));
- if(heapinfo1[block1].type == heapinfo2[block2].type){
-
- if(heapinfo1[block1].type == -1){ /* Free block */
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
+ if((heapinfo1[block1].type == -1) && (heapinfo2[block2].type == -1)){ /* Free block */
- }else if(heapinfo1[block1].type == 0){ /* Complete block */
+ if(match_pairs){
+ match_equals(previous);
+ xbt_dynar_free(&previous);
+ }
+ return 0;
- if(heapinfo1[block1].busy_block.equal_to != NULL && heapinfo2[block2].busy_block.equal_to != NULL){
- if(equal_blocks(block1, block2)){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
- }
- }
+ }else if((heapinfo1[block1].type == 0) && (heapinfo2[block2].type == 0)){ /* Complete block */
- if(heapinfo1[block1].busy_block.size != heapinfo2[block2].busy_block.size){
+ if(equals_to1[block1][0] != NULL && equals_to2[block2][0] != NULL){
+ if(equal_blocks(block1, block2)){
if(match_pairs){
+ match_equals(previous);
xbt_dynar_free(&previous);
}
- return 1;
+ return 0;
}
+ }
- if(heapinfo1[block1].busy_block.busy_size != heapinfo2[block2].busy_block.busy_size){
- if(match_pairs){
- xbt_dynar_free(&previous);
+ if(type_id){
+ type = xbt_dict_get_or_null(all_types, type_id);
+ if(strcmp(type->name, "char") ==0){
+ if(area1 == area2)
+ return -1;
+ }
+ if(type->size == 0){
+ type_desc = get_type_description(all_types, type->name);
+ if(type_desc)
+ type = xbt_dict_get_or_null(all_types, type_desc);
+ else
+ type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
+ }
+ if(strcmp(type->name, "s_smx_context") != 0){
+ if(type->size > 1){
+ if(heapinfo1[block1].busy_block.busy_size != type->size && heapinfo2[block2].busy_block.busy_size != type->size)
+ return -1;
}
- return 1;
}
+ }
- if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
+ if(heapinfo1[block1].busy_block.size != heapinfo2[block2].busy_block.size){
+ if(match_pairs){
+ xbt_dynar_free(&previous);
+ }
+ return 1;
+ }
+
+ if(heapinfo1[block1].busy_block.busy_size != heapinfo2[block2].busy_block.busy_size){
+ if(match_pairs){
+ xbt_dynar_free(&previous);
}
+ return 1;
+ }
+
+ if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
+ if(match_pairs){
+ match_equals(previous);
+ xbt_dynar_free(&previous);
+ }
+ return 0;
+ }
- size = heapinfo1[block1].busy_block.busy_size;
+ size = heapinfo1[block1].busy_block.busy_size;
- if(size <= 0){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
+ if(size <= 0){
+ if(match_pairs){
+ match_equals(previous);
+ xbt_dynar_free(&previous);
}
+ return 0;
+ }
- frag1 = -1;
- frag2 = -1;
+ frag1 = -1;
+ frag2 = -1;
- area1_to_compare = addr_block1;
- area2_to_compare = addr_block2;
+ area1_to_compare = addr_block1;
+ area2_to_compare = addr_block2;
- if((heapinfo1[block1].busy_block.ignore > 0) && (heapinfo2[block2].busy_block.ignore == heapinfo1[block1].busy_block.ignore))
- check_ignore = heapinfo1[block1].busy_block.ignore;
+ if((heapinfo1[block1].busy_block.ignore > 0) && (heapinfo2[block2].busy_block.ignore == heapinfo1[block1].busy_block.ignore))
+ check_ignore = heapinfo1[block1].busy_block.ignore;
- }else{ /* Frgamented block */
+ }else if((heapinfo1[block1].type > 0) && (heapinfo2[block2].type > 0)){ /* Fragmented block */
- frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
- frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
+ frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
+ frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
- addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
- addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
+ addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
+ addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
- area1_to_compare = addr_frag1;
- area2_to_compare = addr_frag2;
-
- if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL && heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
- if(equal_fragments(block1, frag1, block2, frag2)){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
- }
- }
+ area1_to_compare = addr_frag1;
+ area2_to_compare = addr_frag2;
- if(heapinfo1[block1].busy_frag.frag_size[frag1] != heapinfo2[block2].busy_frag.frag_size[frag2]){
- if(match_pairs){
- xbt_dynar_free(&previous);
- }
- return 1;
+ if(type_id){
+ type = xbt_dict_get_or_null(all_types, type_id);
+ if(strcmp(type->name, "char") ==0){
+ if(area1 == area2)
+ return -1;
}
-
- if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
+ if(type->size == 0 || type->type == e_dw_pointer_type){
+ if(!type->dw_type_id){
+ type_desc = get_type_description(all_types, type->name);
+ if(type_desc)
+ type = xbt_dict_get_or_null(all_types, type_desc);
+ else
+ type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
+ }else{
+ type = xbt_dict_get_or_null(all_types, type->dw_type_id);
}
- return 0;
}
-
- size = heapinfo1[block1].busy_frag.frag_size[frag1];
-
- if(size <= 0){
- if(match_pairs){
- match_equals(previous);
- xbt_dynar_free(&previous);
- }
- return 0;
+ if(type->size > 1){
+ if(heapinfo1[block1].busy_frag.frag_size[frag1] != type->size || heapinfo2[block2].busy_frag.frag_size[frag2] != type->size)
+ return -1;
}
-
- if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
- check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
-
}
- }else if((heapinfo1[block1].type > 0) && (heapinfo2[block2].type > 0)){
-
- frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
- frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
-
- if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL || heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
+ if(equals_to1[block1][frag1] != NULL && equals_to2[block2][frag2] != NULL){
if(equal_fragments(block1, frag1, block2, frag2)){
if(match_pairs){
match_equals(previous);
if(match_pairs){
xbt_dynar_free(&previous);
}
- return 1;
+ return 1;
}
-
+
if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
if(match_pairs){
match_equals(previous);
return 0;
}
- addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
- addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
-
- area1_to_compare = addr_frag1;
- area2_to_compare = addr_frag2;
-
size = heapinfo1[block1].busy_frag.frag_size[frag1];
if(size <= 0){
}
return 0;
}
-
- if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && (heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
- check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
+
+ if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
+ check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
}else{
+
if(match_pairs){
xbt_dynar_free(&previous);
}
return 1;
- }
+ }
+
/* Start comparison*/
if(type_id != NULL){
}
}else{
res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore);
- if(res_compare != 0){
- if(match_pairs)
- xbt_dynar_free(&previous);
- return res_compare;
- }
+ if(res_compare != 0){
+ if(match_pairs)
+ xbt_dynar_free(&previous);
+ return res_compare;
+ }
}
if(match_pairs){
for (it=0; it<BLOCKIFY(mdp->heapsize * sizeof(malloc_info)); it++){
newinfo[BLOCK(oldinfo)+it].type = 0;
newinfo[BLOCK(oldinfo)+it].busy_block.ignore = 0;
- newinfo[BLOCK(oldinfo+it)].busy_block.equal_to = NULL;
}
newinfo[BLOCK(oldinfo)].busy_block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info));
newinfo[BLOCK(oldinfo)].busy_block.busy_size = size;
- //newinfo[BLOCK(oldinfo)].busy_block.bt_size = 0;// FIXME setup the backtrace
mfree(mdp, (void *) oldinfo);
mdp->heapsize = newsize;
}
/* Update our metadata about this fragment */
candidate_info->busy_frag.frag_size[candidate_frag] = requested_size;
candidate_info->busy_frag.ignore[candidate_frag] = 0;
- candidate_info->busy_frag.equal_to[candidate_frag] = NULL;
//xbt_backtrace_no_malloc(candidate_info->busy_frag.bt[candidate_frag],XBT_BACKTRACE_SIZE);
//xbt_libunwind_backtrace(candidate_info->busy_frag.bt[candidate_frag],XBT_BACKTRACE_SIZE);
for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) {
mdp->heapinfo[block].busy_frag.frag_size[i] = -1;
mdp->heapinfo[block].busy_frag.ignore[i] = 0;
- mdp->heapinfo[block].busy_frag.equal_to[i] = NULL;
}
mdp->heapinfo[block].busy_frag.nfree = i - 1;
mdp->heapinfo[block].freehook.prev = NULL;
/* mark the fragment returned as busy */
mdp->heapinfo[block].busy_frag.frag_size[0] = requested_size;
mdp->heapinfo[block].busy_frag.ignore[0] = 0;
- mdp->heapinfo[block].busy_frag.equal_to[0] = NULL;
//xbt_backtrace_no_malloc(mdp->heapinfo[block].busy_frag.bt[0],XBT_BACKTRACE_SIZE);
//xbt_libunwind_backtrace(mdp->heapinfo[block].busy_frag.bt[0],XBT_BACKTRACE_SIZE);
mdp->heapinfo[block+it].type = 0;
mdp->heapinfo[block+it].busy_block.busy_size = 0;
mdp->heapinfo[block+it].busy_block.ignore = 0;
- mdp->heapinfo[block+it].busy_block.equal_to = NULL;
}
mdp->heapinfo[block].busy_block.size = blocks;
mdp->heapinfo[block].busy_block.busy_size = requested_size;
mdp->heapinfo[block+it].type = 0;
mdp->heapinfo[block+it].busy_block.busy_size = 0;
mdp->heapinfo[block+it].busy_block.ignore = 0;
- mdp->heapinfo[block+it].busy_block.equal_to = NULL;
}
mdp->heapinfo[block].busy_block.size = blocks;
mdp->heapinfo[block].busy_block.busy_size = requested_size;
ssize_t frag_size[MAX_FRAGMENT_PER_BLOCK];
//void *bt[MAX_FRAGMENT_PER_BLOCK][XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
int ignore[MAX_FRAGMENT_PER_BLOCK];
- heap_area_t equal_to[MAX_FRAGMENT_PER_BLOCK];
} busy_frag;
struct {
size_t size; /* Size (in blocks) of a large cluster. */
//void *bt[XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
//int bt_size;
int ignore;
- heap_area_t equal_to;
} busy_block;
/* Heap information for a free block (that may be the first of a free cluster). */
struct {
for (it= block+blocks; it< mdp->heapinfo[block].busy_block.size ; it++){
mdp->heapinfo[it].type = 0; // FIXME that should be useless, type should already be 0 here
mdp->heapinfo[it].busy_block.ignore = 0;
- mdp->heapinfo[it].busy_block.equal_to = NULL;
}
mdp->heapinfo[block + blocks].busy_block.size
mdp->heapinfo[block].busy_block.size = blocks;
mdp->heapinfo[block].busy_block.busy_size = requested_size;
mdp->heapinfo[block].busy_block.ignore = 0;
- mdp->heapinfo[block].busy_block.equal_to = NULL;
result = ptr;
} else if (blocks == mdp->heapinfo[block].busy_block.size) {
result = ptr;
mdp->heapinfo[block].busy_block.busy_size = requested_size;
mdp->heapinfo[block].busy_block.ignore = 0;
- mdp->heapinfo[block].busy_block.equal_to = NULL;
} else {
/* Won't fit, so allocate a new region that will.
int frag_nb = RESIDUAL(result, BLOCKSIZE) >> type;
mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = requested_size;
mdp->heapinfo[block].busy_frag.ignore[frag_nb] = 0;
- mdp->heapinfo[block].busy_frag.equal_to[frag_nb] = NULL;
} else { /* fragment -> Either other fragment, or block */
/* The new size is different; allocate a new space,
static void xbt_parmap_busy_master_signal(xbt_parmap_t parmap);
static void xbt_parmap_busy_worker_wait(xbt_parmap_t parmap, unsigned round);
+#ifdef HAVE_MC
+static void xbt_parmap_mc_work(xbt_parmap_t parmap, int worker_id);
+static void *xbt_parmap_mc_worker_main(void *arg);
+#endif
/**
* \brief Parallel map structure
xbt_dynar_t data; /**< parameters to pass to fun in parallel */
unsigned int index; /**< index of the next element of data to pick */
+#ifdef HAVE_MC
+ int finish;
+ void* ref_snapshot;
+ int_f_pvoid_pvoid_t snapshot_compare;
+ unsigned int length;
+ void* mc_data;
+#endif
+
/* posix only */
xbt_os_cond_t ready_cond;
xbt_os_mutex_t ready_mutex;
return parmap;
}
+#ifdef HAVE_MC
+/**
+ * \brief Creates a parallel map object
+ * \param num_workers number of worker threads to create
+ * \param mode how to synchronize the worker threads
+ * \return the parmap created
+ */
+xbt_parmap_t xbt_parmap_mc_new(unsigned int num_workers, e_xbt_parmap_mode_t mode)
+{
+ unsigned int i;
+ xbt_os_thread_t worker = NULL;
+
+ XBT_DEBUG("Create new parmap (%u workers)", num_workers);
+
+ /* Initialize the thread pool data structure */
+ xbt_parmap_t parmap = xbt_new0(s_xbt_parmap_t, 1);
+
+ parmap->num_workers = num_workers;
+ parmap->status = XBT_PARMAP_WORK;
+ xbt_parmap_set_mode(parmap, mode);
+
+ /* Create the pool of worker threads */
+ xbt_parmap_thread_data_t data;
+ for (i = 1; i < num_workers; i++) {
+ data = xbt_new0(s_xbt_parmap_thread_data_t, 1);
+ data->parmap = parmap;
+ data->worker_id = i;
+ worker = xbt_os_thread_create(NULL, xbt_parmap_mc_worker_main, data, NULL);
+ xbt_os_thread_detach(worker);
+ }
+ return parmap;
+}
+#endif
+
/**
* \brief Destroys a parmap
* \param parmap the parmap to destroy
xbt_parmap_thread_data_t data = (xbt_parmap_thread_data_t) arg;
xbt_parmap_t parmap = data->parmap;
unsigned round = 0;
- smx_context_t context = SIMIX_context_new(NULL, 0, NULL, NULL, NULL);
- SIMIX_context_set_current(context);
+ // smx_context_t context = SIMIX_context_new(NULL, 0, NULL, NULL, NULL);
+ //SIMIX_context_set_current(context);
XBT_DEBUG("New worker thread created");
}
}
+#ifdef HAVE_MC
+
+/**
+ * \brief Applies a list of tasks in parallel.
+ * \param parmap a parallel map object
+ * \param fun the function to call in parallel
+ * \param data each element of this dynar will be passed as an argument to fun
+ */
+int xbt_parmap_mc_apply(xbt_parmap_t parmap, int_f_pvoid_pvoid_t fun,
+ void* data, unsigned int length, void* ref_snapshot)
+{
+ /* Assign resources to worker threads */
+ parmap->snapshot_compare = fun;
+ parmap->mc_data = data;
+ parmap->index = 0;
+ parmap->finish = -1;
+ parmap->length = length;
+ parmap->ref_snapshot = ref_snapshot;
+ parmap->master_signal_f(parmap);
+ xbt_parmap_mc_work(parmap, 0);
+ parmap->master_wait_f(parmap);
+ XBT_DEBUG("Job done");
+ return parmap->finish;
+}
+
+static void xbt_parmap_mc_work(xbt_parmap_t parmap, int worker_id)
+{
+ unsigned int data_size = (parmap->length / parmap->num_workers) +
+ ((parmap->length % parmap->num_workers) ? 1 :0);
+ void* start = (char*)parmap->mc_data + (data_size*worker_id*sizeof(void*));
+ void* end = MIN((char *)start + data_size* sizeof(void*), (char*)parmap->mc_data + parmap->length*sizeof(void*));
+
+ //XBT_CRITICAL("Worker %d : %p -> %p (%d)", worker_id, start, end, data_size);
+
+ while ( start < end && parmap->finish == -1) {
+ //XBT_CRITICAL("Starting with %p", start);
+ int res = parmap->snapshot_compare(*(void**)start, parmap->ref_snapshot);
+ start = (char *)start + sizeof(start);
+ if (!res){
+
+ parmap->finish = ((char*)start - (char*)parmap->mc_data) / sizeof(void*);
+ //XBT_CRITICAL("Find good one %p (%p)", start, parmap->mc_data);
+ break;
+ }
+ }
+}
+
+/**
+ * \brief Main function of a worker thread.
+ * \param arg the parmap
+ */
+static void *xbt_parmap_mc_worker_main(void *arg)
+{
+ xbt_parmap_thread_data_t data = (xbt_parmap_thread_data_t) arg;
+ xbt_parmap_t parmap = data->parmap;
+ unsigned round = 0;
+ /* smx_context_t context = SIMIX_context_new(NULL, 0, NULL, NULL, NULL); */
+ /* SIMIX_context_set_current(context); */
+
+ XBT_DEBUG("New worker thread created");
+
+ /* Worker's main loop */
+ while (1) {
+ parmap->worker_wait_f(parmap, ++round);
+ if (parmap->status == XBT_PARMAP_WORK) {
+
+ XBT_DEBUG("Worker %d got a job", data->worker_id);
+
+ xbt_parmap_mc_work(parmap, data->worker_id);
+ parmap->worker_signal_f(parmap);
+
+ XBT_DEBUG("Worker %d has finished", data->worker_id);
+
+ /* We are destroying the parmap */
+ } else {
+ xbt_free(data);
+ parmap->worker_signal_f(parmap);
+ return NULL;
+ }
+ }
+}
+#endif
+
#ifdef HAVE_FUTEX_H
static void futex_wait(unsigned *uaddr, unsigned val)
{