Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Add unit test for mc_snapshot
authorGabriel Corona <gabriel.corona@loria.fr>
Thu, 10 Jul 2014 09:36:32 +0000 (11:36 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Thu, 10 Jul 2014 09:57:53 +0000 (11:57 +0200)
buildtools/Cmake/UnitTesting.cmake
src/mc/mc_checkpoint.c
src/mc/mc_page_store.cpp
src/mc/mc_page_store.h
src/mc/mc_private.h
src/mc/mc_snapshot.c

index 95ee93f..56d60b3 100644 (file)
@@ -30,9 +30,13 @@ set(TEST_UNITS
 
 if(HAVE_MC)
   set(TEST_CFILES ${TEST_CFILES}
 
 if(HAVE_MC)
   set(TEST_CFILES ${TEST_CFILES}
-      src/mc/mc_page_store.cpp)
+      src/mc/mc_page_store.cpp
+      src/mc/mc_snapshot.c
+      )
   set(TEST_UNITS ${TEST_UNITS}
   set(TEST_UNITS ${TEST_UNITS}
-     ${CMAKE_CURRENT_BINARY_DIR}/src/mc_page_store_unit.cpp)
+     ${CMAKE_CURRENT_BINARY_DIR}/src/mc_page_store_unit.cpp
+     ${CMAKE_CURRENT_BINARY_DIR}/src/mc_snapshot_unit.c
+     )
 endif()
 
 ADD_CUSTOM_COMMAND(
 endif()
 
 ADD_CUSTOM_COMMAND(
index 202a2f1..34b2281 100644 (file)
@@ -60,7 +60,7 @@ static void local_variable_free_voidp(void *v)
   local_variable_free((local_variable_t) * (void **) v);
 }
 
   local_variable_free((local_variable_t) * (void **) v);
 }
 
-static void MC_region_destroy(mc_mem_region_t reg)
+void MC_region_destroy(mc_mem_region_t reg)
 {
   //munmap(reg->data, reg->size);
   xbt_free(reg->data);
 {
   //munmap(reg->data, reg->size);
   xbt_free(reg->data);
index f728746..a2072b3 100644 (file)
@@ -165,6 +165,11 @@ mc_pages_store_t mc_pages_store_new()
   return new s_mc_pages_store_t(500);
 }
 
   return new s_mc_pages_store_t(500);
 }
 
+void mc_pages_store_delete(mc_pages_store_t store)
+{
+  delete store;
+}
+
 }
 
 #ifdef SIMGRID_TEST
 }
 
 #ifdef SIMGRID_TEST
index 453d103..8018016 100644 (file)
@@ -198,6 +198,7 @@ SG_BEGIN_DECL()
 
 typedef struct s_mc_pages_store s_mc_pages_store_t, * mc_pages_store_t;
 mc_pages_store_t mc_pages_store_new();
 
 typedef struct s_mc_pages_store s_mc_pages_store_t, * mc_pages_store_t;
 mc_pages_store_t mc_pages_store_new();
+void mc_pages_store_delete(mc_pages_store_t store);
 
 /**
  */
 
 /**
  */
index 7b4e43e..f14ed45 100644 (file)
@@ -142,6 +142,7 @@ void mc_free_page_snapshot_region(size_t* pagenos, size_t page_count);
 void mc_restore_page_snapshot_region(mc_mem_region_t region, size_t page_count, uint64_t* pagemap, mc_mem_region_t reference_region);
 
 mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, size_t size, mc_mem_region_t ref_reg);
 void mc_restore_page_snapshot_region(mc_mem_region_t region, size_t page_count, uint64_t* pagemap, mc_mem_region_t reference_region);
 
 mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, size_t size, mc_mem_region_t ref_reg);
+void MC_region_destroy(mc_mem_region_t reg);
 void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg);
 void mc_softdirty_reset();
 
 void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg);
 void mc_softdirty_reset();
 
@@ -737,6 +738,9 @@ void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot)
 static inline __attribute__((always_inline))
 void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size)
 {
 static inline __attribute__((always_inline))
 void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size)
 {
+  if (region==NULL)
+    return addr;
+
   uintptr_t offset = (char*) addr - (char*) region->start_addr;
 
   xbt_assert(addr >= region->start_addr && (char*) addr+size <= (char*)region->start_addr+region->size,
   uintptr_t offset = (char*) addr - (char*) region->start_addr;
 
   xbt_assert(addr >= region->start_addr && (char*) addr+size <= (char*)region->start_addr+region->size,
index acfae8d..e631109 100644 (file)
@@ -94,8 +94,8 @@ int mc_snapshot_region_memcmp(
   // Using alloca() for large allocations may trigger stack overflow:
   // use malloc if the buffer is too big.
   bool stack_alloc = size < 64;
   // Using alloca() for large allocations may trigger stack overflow:
   // use malloc if the buffer is too big.
   bool stack_alloc = size < 64;
-  void* buffer1a = region1->data ? NULL : stack_alloc ? alloca(size) : malloc(size);
-  void* buffer2a = region2->data ? NULL : stack_alloc ? alloca(size) : malloc(size);
+  void* buffer1a = (region1==NULL || region1->data) ? NULL : stack_alloc ? alloca(size) : malloc(size);
+  void* buffer2a = (region2==NULL || region2->data) ? NULL : stack_alloc ? alloca(size) : malloc(size);
   void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer1a, size);
   void* buffer2 = mc_snapshot_read_region(addr2, region2, buffer2a, size);
   int res;
   void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer1a, size);
   void* buffer2 = mc_snapshot_read_region(addr2, region2, buffer2a, size);
   int res;
@@ -127,3 +127,93 @@ int mc_snapshot_memcp(
   mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2);
   return mc_snapshot_region_memcmp(addr1, region1, addr2, region2, size);
 }
   mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2);
   return mc_snapshot_region_memcmp(addr1, region1, addr2, region2, size);
 }
+
+#ifdef SIMGRID_TEST
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+
+#include "mc/mc_private.h"
+
+XBT_TEST_SUITE("mc_snapshot", "Snapshots");
+
+static inline void init_memory(void* mem, size_t size)
+{
+  size_t hash = 5381;
+  hash = ((hash << 5) + hash) + (uintptr_t) size;
+  hash = ((hash << 5) + hash) + size;
+  char* dest = (char*) mem;
+  for (int i=0; i!=size; ++i) {
+    hash = ((hash << 5) + hash) + size;
+    dest[i] = hash & 255;
+  }
+}
+
+XBT_TEST_UNIT("page_region", test_snapshot_page_read, "Test page snapshots")
+{
+  xbt_test_add("Initialisation");
+  _sg_mc_soft_dirty = 0;
+  xbt_assert(xbt_pagesize == getpagesize());
+  xbt_assert(1 << xbt_pagebits == xbt_pagesize);
+  mc_model_checker = xbt_new0(s_mc_model_checker_t, 1);
+  mc_model_checker->pages = mc_pages_store_new();
+
+  for(int n=1; n!=10; ++n) {
+
+    // Store region page(s):
+    size_t byte_size = n * xbt_pagesize;
+    void* source = mmap(NULL, byte_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+    xbt_assert(source!=MAP_FAILED, "Could not allocate source memory");
+
+    // Init memory and take snapshots:
+    init_memory(source, byte_size);
+    mc_mem_region_t region0 = mc_region_new_sparse(0, source, byte_size, NULL);
+    for(int i=1; i<n; i+=2) {
+      init_memory((char*) source + i*xbt_pagesize, xbt_pagesize);
+    }
+    mc_mem_region_t region = mc_region_new_sparse(0, source, byte_size, NULL);
+
+    void* destination = mmap(NULL, byte_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+    xbt_assert(source!=MAP_FAILED, "Could not allocate destination memory");
+
+    xbt_test_add("Reading region data for %i page(s)", n);
+    for(int j=0; j!=100; ++j) {
+      size_t offset = rand() % byte_size;
+      size_t size = rand() % (byte_size - offset);
+      void* read = mc_snapshot_read_region((char*) source+offset, region, destination, size);
+      xbt_test_assert(!memcmp((char*) source+offset, read, size), "Mismatch in mc_snapshot_read_region()");
+    }
+
+    xbt_test_add("Compare region data for %i page(s)", n);
+    for(int j=0; j!=100; ++j) {
+      size_t offset = rand() % byte_size;
+      size_t size = rand() % (byte_size - offset);
+      xbt_test_assert(!mc_snapshot_region_memcmp((char*) source+offset, NULL, (char*) source+offset, region, size),
+        "Mismatch in mc_snapshot_region_memcmp()");
+    }
+
+
+    if (n==1) {
+      xbt_test_add("Read pointer for %i page(s)", n);
+      memcpy(source, &mc_model_checker, sizeof(void*));
+      mc_mem_region_t region2 = mc_region_new_sparse(0, source, byte_size, NULL);
+      xbt_test_assert(mc_snapshot_read_pointer_region(source, region2) == mc_model_checker,
+        "Mismtach in mc_snapshot_read_pointer_region()");
+      MC_region_destroy(region2);
+    }
+
+    MC_region_destroy(region);
+    MC_region_destroy(region0);
+    munmap(destination, byte_size);
+    munmap(source, byte_size);
+  }
+
+  mc_pages_store_delete(mc_model_checker->pages);
+  xbt_free(mc_model_checker);
+  mc_model_checker = NULL;
+}
+
+#endif /* SIMGRID_TEST */
+