Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Cross-process support for MC_ignore
[simgrid.git] / src / mc / mc_checkpoint.c
index 0f3cb09..1825cdc 100644 (file)
@@ -121,7 +121,9 @@ static mc_mem_region_t mc_region_new_dense(
   region->permanent_addr = permanent_addr;
   region->size = size;
   region->flat.data = xbt_malloc(size);
-  memcpy(region->flat.data, permanent_addr, size);
+  MC_process_read(&mc_model_checker->process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    region->flat.data, permanent_addr, size,
+    MC_PROCESS_INDEX_DISABLED);
   XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu",
             region_type, region->flat.data, permanent_addr, size);
   return region;
@@ -163,11 +165,12 @@ static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region
     break;
 
   case MC_REGION_STORAGE_TYPE_FLAT:
-    memcpy(region->permanent_addr, region->flat.data, region->size);
+    MC_process_write(&mc_model_checker->process, region->flat.data,
+      region->permanent_addr, region->size);
     break;
 
   case MC_REGION_STORAGE_TYPE_CHUNKED:
-    mc_region_restore_sparse(region, ref_region);
+    mc_region_restore_sparse(&mc_model_checker->process, region, ref_region);
     break;
 
   case MC_REGION_STORAGE_TYPE_PRIVATIZED:
@@ -232,8 +235,8 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_
     ref_reg = mc_model_checker->parent_snapshot->snapshot_regions[index];
 
   mc_mem_region_t region;
-  const bool privatization_aware = object_info && MC_object_info_executable(object_info);
-  if (privatization_aware && smpi_privatize_global_variables && smpi_process_count())
+  const bool privatization_aware = MC_object_info_is_privatized(object_info);
+  if (privatization_aware && smpi_process_count())
     region = MC_region_new_privatized(type, start_addr, permanent_addr, size, ref_reg);
   else
     region = MC_region_new(type, start_addr, permanent_addr, size, ref_reg);
@@ -243,27 +246,29 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_
   return;
 }
 
-static void MC_get_memory_regions(mc_snapshot_t snapshot)
+static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot)
 {
-  const mc_process_t process = &mc_model_checker->process;
   const size_t n = process->object_infos_size;
-
   snapshot->snapshot_regions_count = n + 1;
   snapshot->snapshot_regions = xbt_new0(mc_mem_region_t, n + 1);
 
   for (size_t i = 0; i!=n; ++i) {
-    mc_object_info_t object_info = mc_model_checker->process.object_infos[i];
+    mc_object_info_t object_info = process->object_infos[i];
     MC_snapshot_add_region(i, snapshot, MC_REGION_TYPE_DATA, object_info,
       object_info->start_rw, object_info->start_rw,
       object_info->end_rw - object_info->start_rw);
   }
 
-  void *start_heap = std_heap->base;
-  void *end_heap = std_heap->breakval;
+  xbt_mheap_t heap = MC_process_get_heap(process);
+  void *start_heap = heap->base;
+  void *end_heap = heap->breakval;
+
   MC_snapshot_add_region(n, snapshot, MC_REGION_TYPE_HEAP, NULL,
                         start_heap, start_heap,
                         (char *) end_heap - (char *) start_heap);
-  snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
+  snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote(
+    heap->heaplimit,
+    MC_process_get_malloc_info(process));
 
 #ifdef HAVE_SMPI
   if (smpi_privatize_global_variables && smpi_process_count()) {
@@ -271,7 +276,7 @@ static void MC_get_memory_regions(mc_snapshot_t snapshot)
   } else
 #endif
   {
-    snapshot->privatization_index = MC_NO_PROCESS_INDEX;
+    snapshot->privatization_index = MC_PROCESS_INDEX_MISSING;
   }
 }
 
@@ -317,6 +322,18 @@ void MC_find_object_address(memory_map_t maps, mc_object_info_t result)
     i++;
   }
 
+  result->start = result->start_rw;
+  if ((const void*) result->start_ro > result->start)
+    result->start = result->start_ro;
+  if ((const void*) result->start_exec > result->start)
+    result->start = result->start_exec;
+
+  result->end = result->end_rw;
+  if (result->end_ro && (const void*) result->end_ro < result->end)
+    result->end = result->end_ro;
+  if (result->end_exec && (const void*) result->end_exec > result->end)
+    result->end = result->end_exec;
+
   xbt_assert(result->file_name);
   xbt_assert(result->start_rw);
   xbt_assert(result->start_exec);
@@ -557,6 +574,7 @@ static void mc_free_snapshot_ignored_data_pvoid(void* data) {
 
 static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
 {
+  xbt_assert(snapshot->process);
   snapshot->ignored_data = xbt_dynar_new(sizeof(s_mc_snapshot_ignored_data_t), mc_free_snapshot_ignored_data_pvoid);
 
   // Copy the memory:
@@ -567,13 +585,16 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
     ignored_data.start = region->addr;
     ignored_data.size = region->size;
     ignored_data.data = malloc(region->size);
-    memcpy(ignored_data.data, region->addr, 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);
     xbt_dynar_push(snapshot->ignored_data, &ignored_data);
   }
 
   // Zero the memory:
   xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
-    memset(region->addr, 0, region->size);
+    MC_process_clear_memory(snapshot->process, region->addr, region->size);
   }
 
 }
@@ -583,7 +604,8 @@ 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) {
-    memcpy(ignored_data.start, ignored_data.data, ignored_data.size);
+    MC_process_write(snapshot->process,
+      ignored_data.data, ignored_data.start, ignored_data.size);
   }
 }
 
@@ -677,9 +699,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 = (void*) &MC_snapshot_read
+};
+
 mc_snapshot_t MC_take_snapshot(int num_state)
 {
+  mc_process_t mc_process = &mc_model_checker->process;
   mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1);
+  snapshot->process = mc_process;
+  snapshot->address_space.address_space_class = &mc_snapshot_class;
 
   snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL);
   smx_process_t process;
@@ -691,11 +720,14 @@ mc_snapshot_t MC_take_snapshot(int num_state)
 
   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(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  MC_get_memory_regions(mc_process, snapshot);
+  if (use_soft_dirty)
     mc_softdirty_reset();
-  }
 
   snapshot->to_ignore = MC_take_snapshot_ignore();
 
@@ -712,9 +744,8 @@ mc_snapshot_t MC_take_snapshot(int num_state)
   }
 
   MC_snapshot_ignore_restore(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  if (use_soft_dirty)
     mc_model_checker->parent_snapshot = snapshot;
-  }
   return snapshot;
 }
 
@@ -767,15 +798,21 @@ void MC_restore_snapshot_fds(mc_snapshot_t snapshot)
 
 void MC_restore_snapshot(mc_snapshot_t snapshot)
 {
+  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);
   MC_restore_snapshot_fds(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  if (use_soft_dirty) {
     mc_softdirty_reset();
   }
   MC_snapshot_ignore_restore(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  if (use_soft_dirty) {
     mc_model_checker->parent_snapshot = snapshot;
   }
+
+  mc_model_checker->process.cache_flags = 0;
 }
 
 mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)