/** @brief Register a stack in the model checker * * The stacks are allocated in the heap. The MC handle them especially * when we analyse/compare the content of the heap so it must be told where * they are with this function. * * @param stack * @param process Process owning the stack * @param context * @param size Size of the stack */ void MC_register_stack_area(void *stack, smx_process_t process, void *context, size_t size) { if (mc_mode != MC_MODE_CLIENT) return; xbt_mheap_t heap = mmalloc_get_current_heap(); s_stack_region_t region; memset(®ion, 0, sizeof(region)); region.address = stack; region.context = context; region.size = size; region.block = ((char *) stack - (char *) heap->heapbase) / BLOCKSIZE + 1; #ifdef HAVE_SMPI if (smpi_privatize_global_variables && process) { region.process_index = smpi_process_index_of_smx_process(process); } else #endif region.process_index = -1; s_mc_stack_region_message_t message; message.type = MC_MESSAGE_STACK_REGION; message.stack_region = region; MC_client_send_message(&message, sizeof(message)); }
void MC_ignore_heap(void *address, size_t size) { if (mc_mode != MC_MODE_CLIENT) return; xbt_mheap_t heap = mmalloc_get_current_heap(); s_mc_heap_ignore_region_t region; memset(®ion, 0, sizeof(region)); region.address = address; region.size = size; region.block = ((char *) address - (char *) heap->heapbase) / BLOCKSIZE + 1; if (heap->heapinfo[region.block].type == 0) { region.fragment = -1; heap->heapinfo[region.block].busy_block.ignore++; } else { region.fragment = ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> heap->heapinfo[region.block].type; heap->heapinfo[region.block].busy_frag.ignore[region.fragment]++; } s_mc_ignore_heap_message_t message; message.type = MC_MESSAGE_IGNORE_HEAP; message.region = region; if (MC_protocol_send(mc_client->fd, &message, sizeof(message))) xbt_die("Could not send ignored region to MCer"); }
void Client::declareStack(void *stack, size_t size, smx_actor_t process, ucontext_t* context) { xbt_mheap_t heap = mmalloc_get_current_heap(); s_stack_region_t region; memset(®ion, 0, sizeof(region)); region.address = stack; region.context = context; region.size = size; region.block = ((char *) stack - (char *) heap->heapbase) / BLOCKSIZE + 1; #if HAVE_SMPI if (smpi_privatize_global_variables && process) region.process_index = smpi_process_index_of_smx_process(process); else #endif region.process_index = -1; s_mc_stack_region_message_t message; message.type = MC_MESSAGE_STACK_REGION; message.stack_region = region; if (channel_.send(message)) xbt_die("Coule not send STACK_REGION to model-checker"); }
void Client::ignoreHeap(void* address, std::size_t size) { xbt_mheap_t heap = mmalloc_get_current_heap(); s_mc_ignore_heap_message_t message; message.type = MC_MESSAGE_IGNORE_HEAP; message.address = address; message.size = size; message.block = ((char *) address - (char *) heap->heapbase) / BLOCKSIZE + 1; if (heap->heapinfo[message.block].type == 0) { message.fragment = -1; heap->heapinfo[message.block].busy_block.ignore++; } else { message.fragment = ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> heap->heapinfo[message.block].type; heap->heapinfo[message.block].busy_frag.ignore[message.fragment]++; } if (channel_.send(message)) xbt_die("Could not send ignored region to MCer"); }
static int is_visited_state(){ if(_sg_mc_visited == 0) return -1; int raw_mem_set = (mmalloc_get_current_heap() == raw_heap); MC_SET_RAW_MEM; mc_visited_state_t new_state = visited_state_new(); MC_UNSET_RAW_MEM; if(xbt_dynar_is_empty(visited_states)){ MC_SET_RAW_MEM; xbt_dynar_push(visited_states, &new_state); MC_UNSET_RAW_MEM; if(raw_mem_set) MC_SET_RAW_MEM; return -1; }else{ MC_SET_RAW_MEM; size_t current_bytes_used = new_state->heap_bytes_used; int current_nb_processes = new_state->nb_processes; unsigned int cursor = 0; int previous_cursor = 0, next_cursor = 0; int start = 0; int end = xbt_dynar_length(visited_states) - 1; mc_visited_state_t state_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; state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t); bytes_used_test = state_test->heap_bytes_used; nb_processes_test = state_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; if(bytes_used_test > current_bytes_used) end = cursor - 1; if(bytes_used_test == current_bytes_used){ same_processes_and_bytes_not_found = 0; if(snapshot_compare(new_state->system_state, state_test->system_state) == 0){ XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num); if(raw_mem_set) MC_SET_RAW_MEM; else MC_UNSET_RAW_MEM; return state_test->num; }else{ /* Search another state with same number of bytes used in std_heap */ previous_cursor = cursor - 1; while(previous_cursor >= 0){ state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, previous_cursor, mc_visited_state_t); bytes_used_test = state_test->system_state->heap_bytes_used; if(bytes_used_test != current_bytes_used) break; if(snapshot_compare(new_state->system_state, state_test->system_state) == 0){ XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num); if(raw_mem_set) MC_SET_RAW_MEM; else MC_UNSET_RAW_MEM; return state_test->num; } previous_cursor--; } next_cursor = cursor + 1; while(next_cursor < xbt_dynar_length(visited_states)){ state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, next_cursor, mc_visited_state_t); bytes_used_test = state_test->system_state->heap_bytes_used; if(bytes_used_test != current_bytes_used) break; if(snapshot_compare(new_state->system_state, state_test->system_state) == 0){ XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num); if(raw_mem_set) MC_SET_RAW_MEM; else MC_UNSET_RAW_MEM; return state_test->num; } next_cursor++; } } } } } state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t); bytes_used_test = state_test->heap_bytes_used; if(bytes_used_test < current_bytes_used) xbt_dynar_insert_at(visited_states, cursor + 1, &new_state); else xbt_dynar_insert_at(visited_states, cursor, &new_state); if(xbt_dynar_length(visited_states) > _sg_mc_visited){ int min = mc_stats->expanded_states; unsigned int cursor2 = 0; unsigned int index = 0; xbt_dynar_foreach(visited_states, cursor2, state_test){ if(state_test->num < min){ index = cursor2; min = state_test->num; } } xbt_dynar_remove_at(visited_states, index, NULL); } MC_UNSET_RAW_MEM; if(raw_mem_set) MC_SET_RAW_MEM; return -1; }