X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/e68d03f1f2c0206497381c7ef3b91bd5d46f1964..0ab8ced3df24230adfeaec1e79d49db3a4f5d632:/src/mc/mc_checkpoint.cpp diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index b5aba8c368..d583acde74 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -29,7 +29,7 @@ #include #include "mc_snapshot.h" -#include "mc_dwarf.hpp" +#include "mc_object_info.h" #include "mc_mmu.h" #include "mc_unw.h" #include "mc_protocol.h" @@ -63,7 +63,7 @@ static void MC_region_restore(mc_mem_region_t region) break; case simgrid::mc::StorageType::Flat: - mc_model_checker->process().write_bytes(region->flat_data().data(), + mc_model_checker->process().write_bytes(region->flat_data(), region->size(), region->permanent_address()); break; @@ -85,7 +85,8 @@ namespace mc { #ifdef HAVE_SMPI simgrid::mc::RegionSnapshot privatized_region( - RegionType region_type, void *start_addr, void* permanent_addr, size_t size + RegionType region_type, void *start_addr, void* permanent_addr, size_t size, + const simgrid::mc::RegionSnapshot* ref_region ) { size_t process_count = MC_smpi_process_count(); @@ -102,11 +103,13 @@ simgrid::mc::RegionSnapshot privatized_region( std::vector data; data.reserve(process_count); - for (size_t i = 0; i < process_count; i++) - data.push_back( - simgrid::mc::region(region_type, start_addr, - privatisation_regions[i].address, size) - ); + for (size_t i = 0; i < process_count; i++) { + const simgrid::mc::RegionSnapshot* ref_privatized_region = nullptr; + if (ref_region && ref_region->storage_type() == StorageType::Privatized) + ref_privatized_region = &ref_region->privatized_data()[i]; + data.push_back(simgrid::mc::region(region_type, start_addr, + privatisation_regions[i].address, size, ref_privatized_region)); + } simgrid::mc::RegionSnapshot region = simgrid::mc::RegionSnapshot( region_type, start_addr, permanent_addr, size); @@ -130,15 +133,20 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, else if (type == simgrid::mc::RegionType::Heap) xbt_assert(!object_info, "Unexpected object info for heap region."); - simgrid::mc::RegionSnapshot region; + simgrid::mc::RegionSnapshot const* ref_region = nullptr; + if (mc_model_checker->parent_snapshot_) + ref_region = mc_model_checker->parent_snapshot_->snapshot_regions[index].get(); + simgrid::mc::RegionSnapshot region; #ifdef HAVE_SMPI - const bool privatization_aware = object_info && object_info->privatized(); + const bool privatization_aware = object_info + && mc_model_checker->process().privatized(*object_info); if (privatization_aware && MC_smpi_process_count()) - region = simgrid::mc::privatized_region(type, start_addr, permanent_addr, size); + region = simgrid::mc::privatized_region( + type, start_addr, permanent_addr, size, ref_region); else #endif - region = simgrid::mc::region(type, start_addr, permanent_addr, size); + region = simgrid::mc::region(type, start_addr, permanent_addr, size, ref_region); region.object_info(object_info); snapshot->snapshot_regions[index] @@ -172,7 +180,7 @@ static void MC_get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t s process->get_malloc_info()); #ifdef HAVE_SMPI - if (smpi_privatize_global_variables && MC_smpi_process_count()) { + if (mc_model_checker->process().privatized() && MC_smpi_process_count()) { // snapshot->privatization_index = smpi_loaded_page mc_model_checker->process().read_variable( "smpi_loaded_page", &snapshot->privatization_index, @@ -191,7 +199,7 @@ static void MC_get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t s void MC_find_object_address( std::vector const& maps, simgrid::mc::ObjectInformation* result) { - const char* file_name = xbt_strdup(result->file_name.c_str()); + char* file_name = xbt_strdup(result->file_name.c_str()); const char *name = basename(file_name); for (size_t i = 0; i < maps.size(); ++i) { simgrid::mc::VmMap const& reg = maps[i]; @@ -239,6 +247,7 @@ void MC_find_object_address( xbt_assert(result->start_rw); xbt_assert(result->start_exec); + free(file_name); } /************************************* Take Snapshot ************************************/ @@ -467,7 +476,7 @@ static std::vector MC_take_snapshot_ignore() static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) { - xbt_assert(snapshot->process); + xbt_assert(snapshot->process()); // Copy the memory: for (auto const& region : mc_model_checker->process().ignored_regions()) { @@ -475,7 +484,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) ignored_data.start = (void*)region.addr; ignored_data.data.resize(region.size); // TODO, we should do this once per privatization segment: - snapshot->process->read_bytes( + snapshot->process()->read_bytes( ignored_data.data.data(), region.size, remote(region.addr), simgrid::mc::ProcessIndexDisabled); snapshot->ignored_data.push_back(std::move(ignored_data)); @@ -483,7 +492,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) // Zero the memory: for(auto const& region : mc_model_checker->process().ignored_regions()) { - snapshot->process->clear_bytes(remote(region.addr), region.size); + snapshot->process()->clear_bytes(remote(region.addr), region.size); } } @@ -491,7 +500,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot) { for (auto const& ignored_data : snapshot->ignored_data) - snapshot->process->write_bytes( + snapshot->process()->write_bytes( ignored_data.data.data(), ignored_data.data.size(), remote(ignored_data.start)); } @@ -581,9 +590,8 @@ mc_snapshot_t MC_take_snapshot(int num_state) simgrid::mc::Process* mc_process = &mc_model_checker->process(); - mc_snapshot_t snapshot = new simgrid::mc::Snapshot(); + mc_snapshot_t snapshot = new simgrid::mc::Snapshot(mc_process); - snapshot->process = mc_process; snapshot->num_state = num_state; smx_process_t process; @@ -595,15 +603,19 @@ mc_snapshot_t MC_take_snapshot(int num_state) if (_sg_mc_snapshot_fds) snapshot->current_fds = MC_get_current_fds(process->pid); + const bool use_soft_dirty = _sg_mc_sparse_checkpoint && _sg_mc_soft_dirty; + /* 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_process->reset_soft_dirty(); snapshot->to_ignore = MC_take_snapshot_ignore(); if (_sg_mc_visited > 0 || strcmp(_sg_mc_property_file, "")) { snapshot->stacks = MC_take_snapshot_stacks(&snapshot); - if (_sg_mc_hash && !snapshot->stacks.empty()) { + if (_sg_mc_hash) { snapshot->hash = simgrid::mc::hash(*snapshot); } else { snapshot->hash = 0; @@ -613,6 +625,8 @@ 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; } @@ -628,13 +642,11 @@ void MC_restore_snapshot_regions(mc_snapshot_t snapshot) #ifdef HAVE_SMPI // TODO, send a message to implement this in the MCed process if(snapshot->privatization_index >= 0) { - // We just rewrote the global variables. - // The privatisation segment SMPI thinks - // is mapped might be inconsistent with the segment which - // is really mapped in memory (kernel state). - // We ask politely SMPI to map the segment anyway, - // even if it thinks it is the current one: - smpi_really_switch_data_segment(snapshot->privatization_index); + // Fix the privatization mmap: + s_mc_restore_message message; + message.type = MC_MESSAGE_RESTORE; + message.index = snapshot->privatization_index; + mc_model_checker->process().send_message(message); } #endif } @@ -663,11 +675,16 @@ 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_restore_snapshot_regions(snapshot); if (_sg_mc_snapshot_fds) MC_restore_snapshot_fds(snapshot); + if (use_soft_dirty) + mc_model_checker->process().reset_soft_dirty(); MC_snapshot_ignore_restore(snapshot); mc_model_checker->process().cache_flags = 0; + if (use_soft_dirty) + mc_model_checker->parent_snapshot_ = snapshot; } mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)