Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] In MC_ignore, keep the zeroed data out of the main snapshot
authorGabriel Corona <gabriel.corona@loria.fr>
Fri, 13 Jun 2014 12:07:46 +0000 (14:07 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 13 Jun 2014 12:29:33 +0000 (14:29 +0200)
The previous implementation was zeroing out the snapshot data

   * so that it will be automatically ignored by the state comparator;

   * but not for the first snapshot in order to be able to backtrack
     to the initial state;

In preparation for the per-page snapshoting code, we

  1. zero out on the main memory;
  2. keep the zero-ed bytes out of the main snapshot regions;
  3. restore the zero-ed bytes.

This way the state comparison code and the per-page snapshoting code
do not have to worry about this. Moreover by normalizing, the
"ignored" bytes, we increase the possibility of sharing memory pages
in per-page snapshots.

src/mc/mc_checkpoint.c
src/mc/mc_private.h

index ba9b772..2b350b7 100644 (file)
@@ -72,6 +72,7 @@ void MC_free_snapshot(mc_snapshot_t snapshot)
   xbt_free(snapshot->stack_sizes);
   xbt_dynar_free(&(snapshot->stacks));
   xbt_dynar_free(&(snapshot->to_ignore));
+  xbt_dynar_free(&snapshot->ignored_data);
 
   if (snapshot->privatization_regions) {
     size_t n = xbt_dynar_length(snapshot->enabled_processes);
@@ -501,37 +502,41 @@ static xbt_dynar_t MC_take_snapshot_ignore()
 
 }
 
-static void MC_dump_checkpoint_ignore(mc_snapshot_t snapshot)
+static void mc_free_snapshot_ignored_data_pvoid(void* data) {
+  mc_snapshot_ignored_data_t ignored_data = (mc_snapshot_ignored_data_t) data;
+  free(ignored_data->data);
+}
+
+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;
-  size_t offset;
-
-  xbt_dynar_foreach(mc_checkpoint_ignore, cursor, region) {
-    if (region->addr > snapshot->regions[0]->start_addr
-        && (char *) (region->addr) <
-        (char *) snapshot->regions[0]->start_addr + STD_HEAP_SIZE) {
-      offset =
-          (char *) region->addr - (char *) snapshot->regions[0]->start_addr;
-      memset((char *) snapshot->regions[0]->data + offset, 0, region->size);
-    } else if (region->addr > snapshot->regions[2]->start_addr
-               && (char *) (region->addr) <
-               (char *) snapshot->regions[2]->start_addr +
-               snapshot->regions[2]->size) {
-      offset =
-          (char *) region->addr - (char *) snapshot->regions[2]->start_addr;
-      memset((char *) snapshot->regions[2]->data + offset, 0, region->size);
-    } else if (region->addr > snapshot->regions[1]->start_addr
-               && (char *) (region->addr) <
-               (char *) snapshot->regions[1]->start_addr +
-               snapshot->regions[1]->size) {
-      offset =
-          (char *) region->addr - (char *) snapshot->regions[1]->start_addr;
-      memset((char *) snapshot->regions[1]->data + offset, 0, region->size);
-    }
+  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
+    s_mc_snapshot_ignored_data_t ignored_data;
+    ignored_data.start = region->addr;
+    ignored_data.size = region->size;
+    ignored_data.data = malloc(region->size);
+    memcpy(ignored_data.data, region->addr, region->size);
+    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);
+  }
+
+}
+
+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_snapshot_t MC_take_snapshot(int num_state)
@@ -541,9 +546,11 @@ mc_snapshot_t MC_take_snapshot(int num_state)
   snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL);
   smx_process_t process;
   xbt_swag_foreach(process, simix_global->process_list) {
-    xbt_dynar_push_as(snapshot->enabled_processes, int, (int)process->pid); 
+    xbt_dynar_push_as(snapshot->enabled_processes, int, (int)process->pid);
   }
 
+  MC_snapshot_handle_ignore(snapshot);
+
   /* Save the std heap and the writable mapped pages of libsimgrid and binary */
   MC_get_memory_regions(snapshot);
 
@@ -561,9 +568,6 @@ mc_snapshot_t MC_take_snapshot(int num_state)
     snapshot->hash = 0;
   }
 
-  if (num_state > 0)
-    MC_dump_checkpoint_ignore(snapshot);
-
   // mprotect the region after zero-ing ignored parts:
   /*size_t i;
      for(i=0; i!=NB_REGIONS; ++i) {
@@ -571,6 +575,8 @@ mc_snapshot_t MC_take_snapshot(int num_state)
      mprotect(region->data, region->size, PROT_READ);
      } */
 
+  MC_snapshot_ignore_restore(snapshot);
+
   return snapshot;
 
 }
@@ -592,6 +598,8 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
     }
     switch_data_segment(snapshot->privatization_index);
   }
+
+  MC_snapshot_ignore_restore(snapshot);
 }
 
 void *mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot)
index d1e1b19..dd30b53 100644 (file)
@@ -45,6 +45,17 @@ typedef struct s_mc_mem_region{
   size_t size;
 } s_mc_mem_region_t, *mc_mem_region_t;
 
+/** Ignored data
+ *
+ *  Some parts of the snapshot are ignored by zeroing them out: the real
+ *  values is stored here.
+ * */
+typedef struct s_mc_snapshot_ignored_data {
+  void* start;
+  size_t size;
+  void* data;
+} s_mc_snapshot_ignored_data_t, *mc_snapshot_ignored_data_t;
+
 typedef struct s_mc_snapshot{
   size_t heap_bytes_used;
   mc_mem_region_t regions[NB_REGIONS];
@@ -55,6 +66,7 @@ typedef struct s_mc_snapshot{
   xbt_dynar_t stacks;
   xbt_dynar_t to_ignore;
   uint64_t hash;
+  xbt_dynar_t ignored_data;
 } s_mc_snapshot_t, *mc_snapshot_t;
 
 /** Information about a given stack frame