X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=snapshot.cc;h=afe02efd851ab39062552f972b3f30e91380a6e1;hb=3c9fb84ea4beccce0117cfcc6a1a7f0abc5f7e1a;hp=4d71babeb967f9b8daba74542b6fa8044f120380;hpb=7962faac2edf30977bf5c837e0452c2accb23789;p=c11tester.git diff --git a/snapshot.cc b/snapshot.cc index 4d71babe..afe02efd 100644 --- a/snapshot.cc +++ b/snapshot.cc @@ -18,7 +18,7 @@ #include //extern declaration definition -#define FAILURE(mesg) { printf("failed in the API: %s with errno relative message: %s\n", mesg, strerror( errno ) ); exit( -1 ); } +#define FAILURE(mesg) { printf("failed in the API: %s with errno relative message: %s\n", mesg, strerror( errno ) ); exit(EXIT_FAILURE); } #if USE_MPROTECT_SNAPSHOT struct SnapShot * snapshotrecord = NULL; struct Snapshot_t * sTheRecord = NULL; @@ -44,6 +44,10 @@ static snapshot_id snapshotid = 0; #endif /* Initialize snapshot data structure */ #if USE_MPROTECT_SNAPSHOT + +/** The initSnapShotRecord method initialized the snapshotting data + * structures for the mprotect based snapshot. + */ void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions) { snapshotrecord=( struct SnapShot * )MYMALLOC(sizeof(struct SnapShot)); snapshotrecord->regionsToSnapShot=( struct MemoryRegion * )MYMALLOC(sizeof(struct MemoryRegion)*nummemoryregions); @@ -61,6 +65,10 @@ void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, } #endif //nothing to initialize for the fork based snapshotting. +/** HandlePF is the page fault handler for mprotect based snapshotting + * algorithm. + */ + void HandlePF( int sig, siginfo_t *si, void * unused){ #if USE_MPROTECT_SNAPSHOT if( si->si_code == SEGV_MAPERR ){ @@ -68,6 +76,7 @@ void HandlePF( int sig, siginfo_t *si, void * unused){ exit( EXIT_FAILURE ); } void* addr = ReturnPageAlignedAddress(si->si_addr); + unsigned int backingpage=snapshotrecord->lastBackingPage++; //Could run out of pages... if (backingpage==snapshotrecord->maxBackingPages) { printf("Out of backing pages at %p\n", si->si_addr); @@ -86,14 +95,18 @@ void HandlePF( int sig, siginfo_t *si, void * unused){ #endif //nothing to handle for non snapshotting case. } -//Return a page aligned address for the address being added -//as a side effect the numBytes are also changed. +/** ReturnPageAlignedAddress returns a page aligned address for the + * address being added as a side effect the numBytes are also changed. + */ + void * ReturnPageAlignedAddress(void * addr) { return (void *)(((uintptr_t)addr)&~(PAGESIZE-1)); } -//Return a page aligned address for the address being added -//as a side effect the numBytes are also changed. +/** PageAlignedAdressUpdate return a page aligned address for the + * address being added as a side effect the numBytes are also changed. + */ + void * PageAlignAddressUpward(void * addr) { return (void *)((((uintptr_t)addr)+PAGESIZE-1)&~(PAGESIZE-1)); } @@ -115,11 +128,16 @@ extern "C" { sTheRecord->mStackSize = STACK_SIZE_DEFAULT; sTheRecord->mIDToRollback = -1; sTheRecord->currSnapShotID = 0; + sTheRecord->mbFinalize = false; #endif } #ifdef __cplusplus } #endif + +/** The initSnapShotLibrary function initializes the Snapshot library. + * @param entryPoint the function that should run the program. + */ void initSnapShotLibrary(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions, unsigned int numheappages, VoidFuncPtr entryPoint) { @@ -135,10 +153,17 @@ void initSnapShotLibrary(unsigned int numbackingpages, sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART | SA_ONSTACK; sigemptyset( &sa.sa_mask ); sa.sa_sigaction = HandlePF; +#ifdef MAC + if( sigaction( SIGBUS, &sa, NULL ) == -1 ){ + printf("SIGACTION CANNOT BE INSTALLED\n"); + exit(EXIT_FAILURE); + } +#endif if( sigaction( SIGSEGV, &sa, NULL ) == -1 ){ printf("SIGACTION CANNOT BE INSTALLED\n"); - exit(-1); + exit(EXIT_FAILURE); } + initSnapShotRecord(numbackingpages, numsnapshots, nummemoryregions); // EVIL HACK: We need to make sure that calls into the HandlePF method don't cause dynamic links @@ -146,6 +171,7 @@ void initSnapShotLibrary(unsigned int numbackingpages, // 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); snapshotrecord->lastBackingPage--; //remove the fake page we copied @@ -156,19 +182,10 @@ void initSnapShotLibrary(unsigned int numbackingpages, addMemoryRegionToSnapShot(pagealignedbase, numheappages); entryPoint(); #else - //SUBRAMANIAN: WHY IS THIS SIGNAL HANDLER HERE FOR THE FORK BASED APPROACH???? - //IT LOOKS LIKE SOME CODE WAS REMOVED FROM SIGNAL HANDLER... - //IN ANY CASE, DO NOT REUSE THE HANDLEPF CALL!!!! - //add a signal to indicate that the process is going to terminate. - struct sigaction sa; - sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART; - sigemptyset( &sa.sa_mask ); - sa.sa_sigaction = HandlePF; - if( sigaction( SIGUSR1, &sa, NULL ) == -1 ){ - printf("SIGACTION CANNOT BE INSTALLED\n"); - exit(-1); - } + basemySpace=system_malloc((numheappages+1)*PAGESIZE); + void * pagealignedbase=PageAlignAddressUpward(basemySpace); + mySpace = create_mspace_with_base(pagealignedbase, numheappages*PAGESIZE, 1 ); createSharedLibrary(); //step 2 setup the stack context. @@ -218,7 +235,7 @@ void initSnapShotLibrary(unsigned int numbackingpages, } while( -1 == retVal && errno == EINTR ); if( sTheRecord->mIDToRollback != snapshotid ) - exit(0); + exit(EXIT_SUCCESS); else{ swapContext = true; } @@ -227,33 +244,39 @@ void initSnapShotLibrary(unsigned int numbackingpages, #endif } -/* This function assumes that addr is page aligned */ + +/** The addMemoryRegionToSnapShot function assumes that addr is page aligned. + */ void addMemoryRegionToSnapShot( void * addr, unsigned int numPages) { #if USE_MPROTECT_SNAPSHOT unsigned int memoryregion=snapshotrecord->lastRegion++; if (memoryregion==snapshotrecord->maxRegions) { printf("Exceeded supported number of memory regions!\n"); - exit(-1); + exit(EXIT_FAILURE); } snapshotrecord->regionsToSnapShot[ memoryregion ].basePtr=addr; snapshotrecord->regionsToSnapShot[ memoryregion ].sizeInPages=numPages; #endif //NOT REQUIRED IN THE CASE OF FORK BASED SNAPSHOTS. } -//take snapshot + +/** The takeSnapshot function takes a snapshot. + * @return The snapshot identifier. + */ + snapshot_id takeSnapshot( ){ #if USE_MPROTECT_SNAPSHOT for(unsigned int region=0; regionlastRegion;region++) { if( mprotect(snapshotrecord->regionsToSnapShot[region].basePtr, snapshotrecord->regionsToSnapShot[region].sizeInPages*sizeof(struct SnapShotPage), PROT_READ ) == -1 ){ perror("mprotect"); printf("Failed to mprotect inside of takeSnapShot\n"); - exit(-1); + exit(EXIT_FAILURE); } } unsigned int snapshot=snapshotrecord->lastSnapShot++; if (snapshot==snapshotrecord->maxSnapShots) { printf("Out of snapshots\n"); - exit(-1); + exit(EXIT_FAILURE); } snapshotrecord->snapShots[snapshot].firstBackingPage=snapshotrecord->lastBackingPage; @@ -263,6 +286,11 @@ snapshot_id takeSnapshot( ){ return snapshotid; #endif } + +/** The rollBack function rollback to the given snapshot identifier. + * @param theID is the snapshot identifier to rollback to. + */ + void rollBack( snapshot_id theID ){ #if USE_MPROTECT_SNAPSHOT std::map< void *, bool, std::less< void * >, MyAlloc< std::pair< const void *, bool > > > duplicateMap; @@ -270,7 +298,7 @@ void rollBack( snapshot_id theID ){ if( mprotect(snapshotrecord->regionsToSnapShot[region].basePtr, snapshotrecord->regionsToSnapShot[region].sizeInPages*sizeof(struct SnapShotPage), PROT_READ | PROT_WRITE ) == -1 ){ perror("mprotect"); printf("Failed to mprotect inside of takeSnapShot\n"); - exit(-1); + exit(EXIT_FAILURE); } } for(unsigned int page=snapshotrecord->snapShots[theID].firstBackingPage; pagelastBackingPage; page++) { @@ -297,11 +325,15 @@ void rollBack( snapshot_id theID ){ #if SSDEBUG DumpIntoLog( "ModelSnapshot", "Invoked rollback" ); #endif - exit( 0 ); + exit(EXIT_SUCCESS); } #endif } +/** The finalize method shuts down the snapshotting system. */ +//Subramanian -- remove this function from the external interface and +//have us call it internally + void finalize(){ #if !USE_MPROTECT_SNAPSHOT sTheRecord->mbFinalize = true;