X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/ea9cce21b6d3f37823143217f1ca183bb2f0c9ac..3ae4039533d80613612bb81524c164f33384df92:/src/mc/mc_checkpoint.cpp diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 1db06bc863..aca9153fc5 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -35,6 +35,8 @@ #include "mc_protocol.h" #include "mc_smx.h" +using simgrid::mc::remote; + extern "C" { XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc, @@ -98,25 +100,12 @@ void MC_region_destroy(mc_mem_region_t region) xbt_free(region); } -void MC_free_snapshot(mc_snapshot_t snapshot) -{ - for (size_t i = 0; i < snapshot->snapshot_regions_count; i++) { - MC_region_destroy(snapshot->snapshot_regions[i]); - } - xbt_free(snapshot->snapshot_regions); - xbt_free(snapshot->stack_sizes); - xbt_dynar_free(&(snapshot->stacks)); - xbt_dynar_free(&(snapshot->to_ignore)); - xbt_dynar_free(&snapshot->ignored_data); - xbt_free(snapshot); -} - /******************************* Snapshot regions ********************************/ /*********************************************************************************/ static mc_mem_region_t mc_region_new_dense( mc_region_type_t region_type, - void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg) + void *start_addr, void* permanent_addr, size_t size) { mc_mem_region_t region = xbt_new(s_mc_mem_region_t, 1); region->region_type = region_type; @@ -125,9 +114,9 @@ static mc_mem_region_t mc_region_new_dense( region->permanent_addr = permanent_addr; region->size = size; region->flat.data = xbt_malloc(size); - MC_process_read(&mc_model_checker->process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, - region->flat.data, permanent_addr, size, - MC_PROCESS_INDEX_DISABLED); + mc_model_checker->process().read_bytes(region->flat.data, size, + remote(permanent_addr), + simgrid::mc::ProcessIndexDisabled); XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", region_type, region->flat.data, permanent_addr, size); return region; @@ -139,28 +128,22 @@ static mc_mem_region_t mc_region_new_dense( * @param start_addr Address of the region in the simulated process * @param permanent_addr Permanent address of this data (for privatized variables, this is the virtual address of the privatized mapping) * @param size Size of the data* - * @param ref_reg Reference corresponding region */ -static mc_mem_region_t MC_region_new(mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg) +static mc_mem_region_t MC_region_new( + mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size) { if (_sg_mc_sparse_checkpoint) { - return mc_region_new_sparse(type, start_addr, permanent_addr, size, ref_reg); + return mc_region_new_sparse(type, start_addr, permanent_addr, size); } else { - return mc_region_new_dense(type, start_addr, permanent_addr, size, ref_reg); + return mc_region_new_dense(type, start_addr, permanent_addr, size); } } /** @brief Restore a region from a snapshot - * - * If we are using per page snapshots, it is possible to use the reference - * region in order to do an incremental restoration of the region: the - * softclean pages which are shared between the two snapshots do not need - * to be restored. * * @param reg Target region - * @param reg_reg Current region (if not NULL), used for lazy per page restoration */ -static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region) +static void MC_region_restore(mc_mem_region_t region) { switch(region->storage_type) { case MC_REGION_STORAGE_TYPE_NONE: @@ -169,22 +152,19 @@ static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region break; case MC_REGION_STORAGE_TYPE_FLAT: - MC_process_write(&mc_model_checker->process, region->flat.data, - region->permanent_addr, region->size); + mc_model_checker->process().write_bytes(region->flat.data, region->size, + remote(region->permanent_addr)); break; case MC_REGION_STORAGE_TYPE_CHUNKED: - mc_region_restore_sparse(&mc_model_checker->process, region, ref_region); + mc_region_restore_sparse(&mc_model_checker->process(), region); break; case MC_REGION_STORAGE_TYPE_PRIVATIZED: { - bool has_ref_regions = ref_region && - ref_region->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED; size_t process_count = region->privatized.regions_count; for (size_t i = 0; i < process_count; i++) { - MC_region_restore(region->privatized.regions[i], - has_ref_regions ? ref_region->privatized.regions[i] : NULL); + MC_region_restore(region->privatized.regions[i]); } break; } @@ -192,8 +172,8 @@ static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region } static mc_mem_region_t MC_region_new_privatized( - mc_region_type_t region_type, void *start_addr, void* permanent_addr, size_t size, - mc_mem_region_t ref_reg) + mc_region_type_t region_type, void *start_addr, void* permanent_addr, size_t size + ) { size_t process_count = MC_smpi_process_count(); mc_mem_region_t region = xbt_new(s_mc_mem_region_t, 1); @@ -207,21 +187,18 @@ static mc_mem_region_t MC_region_new_privatized( // Read smpi_privatisation_regions from MCed: smpi_privatisation_region_t remote_smpi_privatisation_regions; - MC_process_read_variable(&mc_model_checker->process, + mc_model_checker->process().read_variable( "smpi_privatisation_regions", &remote_smpi_privatisation_regions, sizeof(remote_smpi_privatisation_regions)); s_smpi_privatisation_region_t privatisation_regions[process_count]; - MC_process_read_simple(&mc_model_checker->process, &privatisation_regions, - remote_smpi_privatisation_regions, sizeof(privatisation_regions)); + mc_model_checker->process().read_bytes( + &privatisation_regions, sizeof(privatisation_regions), + remote(remote_smpi_privatisation_regions)); for (size_t i = 0; i < process_count; i++) { - mc_mem_region_t ref_subreg = NULL; - if (ref_reg && ref_reg->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED) - ref_subreg = ref_reg->privatized.regions[i]; region->privatized.regions[i] = MC_region_new(region_type, start_addr, - privatisation_regions[i].address, size, - ref_subreg); + privatisation_regions[i].address, size); } return region; @@ -236,16 +213,12 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_ else if (type == MC_REGION_TYPE_HEAP) xbt_assert(!object_info, "Unexpected object info for heap region."); - mc_mem_region_t ref_reg = NULL; - if (mc_model_checker->parent_snapshot) - ref_reg = mc_model_checker->parent_snapshot->snapshot_regions[index]; - mc_mem_region_t region; const bool privatization_aware = MC_object_info_is_privatized(object_info); if (privatization_aware && MC_smpi_process_count()) - region = MC_region_new_privatized(type, start_addr, permanent_addr, size, ref_reg); + region = MC_region_new_privatized(type, start_addr, permanent_addr, size); else - region = MC_region_new(type, start_addr, permanent_addr, size, ref_reg); + region = MC_region_new(type, start_addr, permanent_addr, size); region->object_info = object_info; snapshot->snapshot_regions[index] = region; @@ -265,7 +238,7 @@ static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot) object_info->end_rw - object_info->start_rw); } - xbt_mheap_t heap = MC_process_get_heap(process); + xbt_mheap_t heap = process->get_heap(); void *start_heap = heap->base; void *end_heap = heap->breakval; @@ -274,18 +247,18 @@ static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot) (char *) end_heap - (char *) start_heap); snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote( heap->heaplimit, - MC_process_get_malloc_info(process)); + process->get_malloc_info()); #ifdef HAVE_SMPI if (smpi_privatize_global_variables && MC_smpi_process_count()) { // snapshot->privatization_index = smpi_loaded_page - MC_process_read_variable(&mc_model_checker->process, + mc_model_checker->process().read_variable( "smpi_loaded_page", &snapshot->privatization_index, sizeof(snapshot->privatization_index)); } else #endif { - snapshot->privatization_index = MC_PROCESS_INDEX_MISSING; + snapshot->privatization_index = simgrid::mc::ProcessIndexMissing; } } @@ -373,7 +346,7 @@ static bool mc_valid_variable(dw_variable_t var, dw_frame_t scope, static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_frame_t scope, int process_index, xbt_dynar_t result) { - mc_process_t process = &mc_model_checker->process; + mc_process_t process = &mc_model_checker->process(); void *ip = (void *) stack_frame->ip; if (ip < scope->low_pc || ip >= scope->high_pc) @@ -409,7 +382,7 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, current_variable->object_info, &(stack_frame->unw_cursor), (void *) stack_frame->frame_base, - (mc_address_space_t) &mc_model_checker->process, process_index); + &mc_model_checker->process(), process_index); switch(mc_get_location_type(&location)) { case MC_LOCATION_TYPE_ADDRESS: @@ -460,7 +433,7 @@ static void MC_stack_frame_free_voipd(void *s) static xbt_dynar_t MC_unwind_stack_frames(mc_unw_context_t stack_context) { - mc_process_t process = &mc_model_checker->process; + mc_process_t process = &mc_model_checker->process(); xbt_dynar_t result = xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd); @@ -489,7 +462,7 @@ static xbt_dynar_t MC_unwind_stack_frames(mc_unw_context_t stack_context) // TODO, use real addresses in frame_t instead of fixing it here - dw_frame_t frame = MC_process_find_function(process, (void *) ip); + dw_frame_t frame = process->find_function(remote(ip)); stack_frame->frame = frame; if (frame) { @@ -538,11 +511,11 @@ static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot) // Read the context from remote process: unw_context_t context; - MC_process_read_simple(&mc_model_checker->process, - &context, (unw_context_t*) current_stack->context, sizeof(context)); + mc_model_checker->process().read_bytes( + &context, sizeof(context), remote(current_stack->context)); st->context = xbt_new0(s_mc_unw_context_t, 1); - if (mc_unw_init_context(st->context, &mc_model_checker->process, + if (mc_unw_init_context(st->context, &mc_model_checker->process(), &context) < 0) { xbt_die("Could not initialise the libunwind context."); } @@ -602,23 +575,21 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) snapshot->ignored_data = xbt_dynar_new(sizeof(s_mc_snapshot_ignored_data_t), mc_free_snapshot_ignored_data_pvoid); // Copy the memory: - unsigned int cursor = 0; - mc_checkpoint_ignore_region_t region; - xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) { + for (auto const& region : mc_model_checker->process().ignored_regions()) { s_mc_snapshot_ignored_data_t ignored_data; - ignored_data.start = region->addr; - ignored_data.size = region->size; - ignored_data.data = malloc(region->size); + ignored_data.start = (void*)region.addr; + ignored_data.size = region.size; + ignored_data.data = malloc(region.size); // TODO, we should do this once per privatization segment: - MC_process_read(snapshot->process, - MC_ADDRESS_SPACE_READ_FLAGS_NONE, - ignored_data.data, region->addr, region->size, MC_PROCESS_INDEX_DISABLED); + snapshot->process->read_bytes( + ignored_data.data, region.size, remote(region.addr), + simgrid::mc::ProcessIndexDisabled); xbt_dynar_push(snapshot->ignored_data, &ignored_data); } // Zero the memory: - xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) { - MC_process_clear_memory(snapshot->process, region->addr, region->size); + for(auto const& region : mc_model_checker->process().ignored_regions()) { + snapshot->process->clear_bytes(remote(region.addr), region.size); } } @@ -628,30 +599,11 @@ static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot) unsigned int cursor = 0; s_mc_snapshot_ignored_data_t ignored_data; xbt_dynar_foreach (snapshot->ignored_data, cursor, ignored_data) { - MC_process_write(snapshot->process, - ignored_data.data, ignored_data.start, ignored_data.size); + snapshot->process->write_bytes(ignored_data.data, ignored_data.size, + remote(ignored_data.start)); } } -/** @brief Can we remove this snapshot? - * - * Some snapshots cannot be removed (yet) because we need them - * at this point. - * - * @param snapshot - */ -int mc_important_snapshot(mc_snapshot_t snapshot) -{ - // We need this snapshot in order to know which - // pages needs to be stored in the next snapshot. - // This field is only non-NULL when using soft-dirty - // page tracking. - if (snapshot == mc_model_checker->parent_snapshot) - return true; - - return false; -} - static void MC_get_current_fd(mc_snapshot_t snapshot) { @@ -733,20 +685,16 @@ static void MC_get_current_fd(mc_snapshot_t snapshot) closedir (fd_dir); } -static s_mc_address_space_class_t mc_snapshot_class = { - .read = (mc_address_space_class_read_callback_t) &MC_snapshot_read, - .get_process = NULL -}; - mc_snapshot_t MC_take_snapshot(int num_state) { XBT_DEBUG("Taking snapshot %i", num_state); - mc_process_t mc_process = &mc_model_checker->process; - mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1); + mc_process_t mc_process = &mc_model_checker->process(); + + mc_snapshot_t snapshot = new simgrid::mc::Snapshot(); + snapshot->process = mc_process; snapshot->num_state = num_state; - snapshot->address_space.address_space_class = &mc_snapshot_class; snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL); @@ -759,14 +707,8 @@ mc_snapshot_t MC_take_snapshot(int num_state) if (_sg_mc_snapshot_fds) MC_get_current_fd(snapshot); - const bool use_soft_dirty = _sg_mc_sparse_checkpoint - && _sg_mc_soft_dirty - && MC_process_is_self(mc_process); - /* Save the std heap and the writable mapped pages of libsimgrid and binary */ MC_get_memory_regions(mc_process, snapshot); - if (use_soft_dirty) - mc_softdirty_reset(); snapshot->to_ignore = MC_take_snapshot_ignore(); @@ -783,22 +725,17 @@ mc_snapshot_t MC_take_snapshot(int num_state) } MC_snapshot_ignore_restore(snapshot); - if (use_soft_dirty) - mc_model_checker->parent_snapshot = snapshot; return snapshot; } static inline void MC_restore_snapshot_regions(mc_snapshot_t snapshot) { - mc_snapshot_t parent_snapshot = mc_model_checker->parent_snapshot; - const size_t n = snapshot->snapshot_regions_count; for (size_t i = 0; i < n; i++) { // For privatized, variables we decided it was not necessary to take the snapshot: if (snapshot->snapshot_regions[i]) - MC_region_restore(snapshot->snapshot_regions[i], - parent_snapshot ? parent_snapshot->snapshot_regions[i] : NULL); + MC_region_restore(snapshot->snapshot_regions[i]); } #ifdef HAVE_SMPI @@ -841,23 +778,11 @@ void MC_restore_snapshot_fds(mc_snapshot_t snapshot) void MC_restore_snapshot(mc_snapshot_t snapshot) { XBT_DEBUG("Restore snapshot %i", snapshot->num_state); - - const bool use_soft_dirty = _sg_mc_sparse_checkpoint - && _sg_mc_soft_dirty - && MC_process_is_self(&mc_model_checker->process); - MC_restore_snapshot_regions(snapshot); if (_sg_mc_snapshot_fds) MC_restore_snapshot_fds(snapshot); - if (use_soft_dirty) { - mc_softdirty_reset(); - } MC_snapshot_ignore_restore(snapshot); - if (use_soft_dirty) { - mc_model_checker->parent_snapshot = snapshot; - } - - mc_model_checker->process.cache_flags = 0; + mc_model_checker->process().cache_flags = 0; } mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)