X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=snapshot.cc;h=5069a1cf1147cb7afb07035cbf607c69daa2c284;hp=fe5110a03fe5a7b0e45e3b62471788eb396a9aed;hb=d775a7d6624fa14284c4a273d039bedd21a1f55c;hpb=2ada1a461101f16a0be8ba75200c8ae4f9ff9d84 diff --git a/snapshot.cc b/snapshot.cc index fe5110a0..5069a1cf 100644 --- a/snapshot.cc +++ b/snapshot.cc @@ -6,14 +6,12 @@ #include #include #include -#include #include "hashtable.h" #include "snapshot.h" #include "mymemory.h" #include "common.h" - -#define FAILURE(mesg) { model_print("failed in the API: %s with errno relative message: %s\n", mesg, strerror(errno)); exit(EXIT_FAILURE); } +#include "context.h" /** PageAlignedAdressUpdate return a page aligned address for the * address being added as a side effect the numBytes are also changed. @@ -46,8 +44,19 @@ struct MemoryRegion { int sizeInPages; // size of memory region in pages }; +/** ReturnPageAlignedAddress returns a page aligned address for the + * address being added as a side effect the numBytes are also changed. + */ +static void * ReturnPageAlignedAddress(void *addr) +{ + return (void *)(((uintptr_t)addr) & ~(PAGESIZE - 1)); +} + /* Primary struct for snapshotting system */ struct mprot_snapshotter { + mprot_snapshotter(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions); + ~mprot_snapshotter(); + struct MemoryRegion *regionsToSnapShot; //This pointer references an array of memory regions to snapshot snapshot_page_t *backingStore; //This pointer references an array of snapshotpage's that form the backing store void *backingStoreBasePtr; //This pointer references an array of snapshotpage's that form the backing store @@ -61,42 +70,40 @@ struct mprot_snapshotter { unsigned int maxRegions; //Stores the max number of memory regions we support unsigned int maxBackingPages; //Stores the total number of backing pages unsigned int maxSnapShots; //Stores the total number of snapshots we allow + + MEMALLOC }; static struct mprot_snapshotter *mprot_snap = NULL; -/** ReturnPageAlignedAddress returns a page aligned address for the - * address being added as a side effect the numBytes are also changed. - */ -static void * ReturnPageAlignedAddress(void *addr) +mprot_snapshotter::mprot_snapshotter(unsigned int backing_pages, unsigned int snapshots, unsigned int regions) : + lastSnapShot(0), + lastBackingPage(0), + lastRegion(0), + maxRegions(regions), + maxBackingPages(backing_pages), + maxSnapShots(snapshots) { - return (void *)(((uintptr_t)addr) & ~(PAGESIZE - 1)); + regionsToSnapShot = (struct MemoryRegion *)model_malloc(sizeof(struct MemoryRegion) * regions); + backingStoreBasePtr = (void *)model_malloc(sizeof(snapshot_page_t) * (backing_pages + 1)); + //Page align the backingstorepages + backingStore = (snapshot_page_t *)PageAlignAddressUpward(backingStoreBasePtr); + backingRecords = (struct BackingPageRecord *)model_malloc(sizeof(struct BackingPageRecord) * backing_pages); + snapShots = (struct SnapShotRecord *)model_malloc(sizeof(struct SnapShotRecord) * snapshots); } -/** The initSnapShotRecord method initialized the snapshotting data - * structures for the mprotect based snapshot. - */ -static void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions) +mprot_snapshotter::~mprot_snapshotter() { - mprot_snap = (struct mprot_snapshotter *)model_malloc(sizeof(struct mprot_snapshotter)); - mprot_snap->regionsToSnapShot = (struct MemoryRegion *)model_malloc(sizeof(struct MemoryRegion) * nummemoryregions); - mprot_snap->backingStoreBasePtr = (void *)model_malloc(sizeof(snapshot_page_t) * (numbackingpages + 1)); - //Page align the backingstorepages - mprot_snap->backingStore = (snapshot_page_t *)PageAlignAddressUpward(mprot_snap->backingStoreBasePtr); - mprot_snap->backingRecords = (struct BackingPageRecord *)model_malloc(sizeof(struct BackingPageRecord) * numbackingpages); - mprot_snap->snapShots = (struct SnapShotRecord *)model_malloc(sizeof(struct SnapShotRecord) * numsnapshots); - mprot_snap->lastSnapShot = 0; - mprot_snap->lastBackingPage = 0; - mprot_snap->lastRegion = 0; - mprot_snap->maxRegions = nummemoryregions; - mprot_snap->maxBackingPages = numbackingpages; - mprot_snap->maxSnapShots = numsnapshots; + model_free(regionsToSnapShot); + model_free(backingStoreBasePtr); + model_free(backingRecords); + model_free(snapShots); } -/** HandlePF is the page fault handler for mprotect based snapshotting +/** mprot_handle_pf is the page fault handler for mprotect based snapshotting * algorithm. */ -static void HandlePF(int sig, siginfo_t *si, void *unused) +static void mprot_handle_pf(int sig, siginfo_t *si, void *unused) { if (si->si_code == SEGV_MAPERR) { model_print("Real Fault at %p\n", si->si_addr); @@ -138,7 +145,7 @@ static void mprot_snapshot_init(unsigned int numbackingpages, struct sigaction sa; sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART | SA_ONSTACK; sigemptyset(&sa.sa_mask); - sa.sa_sigaction = HandlePF; + sa.sa_sigaction = mprot_handle_pf; #ifdef MAC if (sigaction(SIGBUS, &sa, NULL) == -1) { model_print("SIGACTION CANNOT BE INSTALLED\n"); @@ -150,27 +157,27 @@ static void mprot_snapshot_init(unsigned int numbackingpages, exit(EXIT_FAILURE); } - initSnapShotRecord(numbackingpages, numsnapshots, nummemoryregions); + mprot_snap = new mprot_snapshotter(numbackingpages, numsnapshots, nummemoryregions); - // EVIL HACK: We need to make sure that calls into the HandlePF method don't cause dynamic links + // EVIL HACK: We need to make sure that calls into the mprot_handle_pf method don't cause dynamic links // The problem is that we end up protecting state in the dynamic linker... // Solution is to call our signal handler before we start protecting stuff... siginfo_t si; memset(&si, 0, sizeof(si)); si.si_addr = ss.ss_sp; - HandlePF(SIGSEGV, &si, NULL); + mprot_handle_pf(SIGSEGV, &si, NULL); mprot_snap->lastBackingPage--; //remove the fake page we copied void *basemySpace = model_malloc((numheappages + 1) * PAGESIZE); void *pagealignedbase = PageAlignAddressUpward(basemySpace); user_snapshot_space = create_mspace_with_base(pagealignedbase, numheappages * PAGESIZE, 1); - addMemoryRegionToSnapShot(pagealignedbase, numheappages); + snapshot_add_memory_region(pagealignedbase, numheappages); void *base_model_snapshot_space = model_malloc((numheappages + 1) * PAGESIZE); pagealignedbase = PageAlignAddressUpward(base_model_snapshot_space); model_snapshot_space = create_mspace_with_base(pagealignedbase, numheappages * PAGESIZE, 1); - addMemoryRegionToSnapShot(pagealignedbase, numheappages); + snapshot_add_memory_region(pagealignedbase, numheappages); entryPoint(); } @@ -238,8 +245,6 @@ static void mprot_roll_back(snapshot_id theID) #else /* !USE_MPROTECT_SNAPSHOT */ -#include - #define SHARED_MEMORY_DEFAULT (100 * ((size_t)1 << 20)) // 100mb for the shared memory #define STACK_SIZE_DEFAULT (((size_t)1 << 20) * 20) // 20 mb out of the above 100 mb for my stack @@ -273,8 +278,10 @@ static void createSharedMemory() { //step 1. create shared memory. void *memMapBase = mmap(0, SHARED_MEMORY_DEFAULT + STACK_SIZE_DEFAULT, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (MAP_FAILED == memMapBase) - FAILURE("mmap"); + if (memMapBase == MAP_FAILED) { + perror("mmap"); + exit(EXIT_FAILURE); + } //Setup snapshot record at top of free region fork_snap = (struct fork_snapshotter *)memMapBase; @@ -316,7 +323,7 @@ static void fork_snapshot_init(unsigned int numbackingpages, newContext.uc_stack.ss_size = STACK_SIZE_DEFAULT; makecontext(&newContext, entryPoint, 0); /* switch to a new entryPoint context, on a new stack */ - swapcontext(&savedSnapshotContext, &newContext); + model_swapcontext(&savedSnapshotContext, &newContext); /* switch back here when takesnapshot is called */ pid_t forkedID = 0; @@ -360,7 +367,7 @@ static void fork_snapshot_init(unsigned int numbackingpages, static snapshot_id fork_take_snapshot() { - swapcontext(&savedUserSnapshotContext, &savedSnapshotContext); + model_swapcontext(&savedUserSnapshotContext, &savedSnapshotContext); DEBUG("TAKESNAPSHOT RETURN\n"); return snapshotid; } @@ -389,10 +396,11 @@ static void fork_roll_back(snapshot_id theID) #endif /* !USE_MPROTECT_SNAPSHOT */ -/** The initSnapshotLibrary function initializes the snapshot library. - * @param entryPoint the function that should run the program. +/** + * @brief Initializes the snapshot system + * @param entryPoint the function that should run the program. */ -void initSnapshotLibrary(unsigned int numbackingpages, +void snapshot_system_init(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions, unsigned int numheappages, VoidFuncPtr entryPoint) { @@ -403,8 +411,8 @@ void initSnapshotLibrary(unsigned int numbackingpages, #endif } -/** The addMemoryRegionToSnapShot function assumes that addr is page aligned. */ -void addMemoryRegionToSnapShot(void *addr, unsigned int numPages) +/** Assumes that addr is page aligned. */ +void snapshot_add_memory_region(void *addr, unsigned int numPages) { #if USE_MPROTECT_SNAPSHOT mprot_add_to_snapshot(addr, numPages); @@ -413,10 +421,10 @@ void addMemoryRegionToSnapShot(void *addr, unsigned int numPages) #endif } -/** The takeSnapshot function takes a snapshot. +/** Takes a snapshot of memory. * @return The snapshot identifier. */ -snapshot_id takeSnapshot() +snapshot_id take_snapshot() { #if USE_MPROTECT_SNAPSHOT return mprot_take_snapshot(); @@ -425,10 +433,10 @@ snapshot_id takeSnapshot() #endif } -/** The rollBack function rollback to the given snapshot identifier. +/** Rolls the memory state back to the given snapshot identifier. * @param theID is the snapshot identifier to rollback to. */ -void rollBack(snapshot_id theID) +void snapshot_roll_back(snapshot_id theID) { #if USE_MPROTECT_SNAPSHOT mprot_roll_back(theID);