X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=snapshot.cc;h=1e7d80b4b5d836d1c4a1cdb653824a626afb82c8;hp=9a69a4b310141cd8fafd8fde5a2b45691b9c9b02;hb=c9719c5b5bebeed83f9864825fa93ff6bae2b575;hpb=84b27b559dac866588ee23920b930d5c58684815 diff --git a/snapshot.cc b/snapshot.cc index 9a69a4b3..1e7d80b4 100644 --- a/snapshot.cc +++ b/snapshot.cc @@ -33,6 +33,17 @@ struct Snapshot * sTheRecord = NULL; #endif #if !USE_MPROTECT_SNAPSHOT +/** @statics +* These variables are necessary because the stack is shared region and +* there exists a race between all processes executing the same function. +* To avoid the problem above, we require variables allocated in 'safe' regions. +* The bug was actually observed with the forkID, these variables below are +* used to indicate the various contexts to which to switch to. +* +* @savedSnapshotContext: contains the point to which takesnapshot() call should switch to. +* @savedUserSnapshotContext: contains the point to which the process whose snapshotid is equal to the rollbackid should switch to +* @snapshotid: it is a running counter for the various forked processes snapshotid. it is incremented and set in a persistently shared record +*/ static ucontext_t savedSnapshotContext; static ucontext_t savedUserSnapshotContext; static snapshot_id snapshotid = 0; @@ -120,7 +131,6 @@ void createSharedLibrary(){ sTheRecord->mStackSize = STACK_SIZE_DEFAULT; sTheRecord->mIDToRollback = -1; sTheRecord->currSnapShotID = 0; - sTheRecord->mbFinalize = false; #endif } @@ -178,37 +188,28 @@ void initSnapShotLibrary(unsigned int numbackingpages, createSharedLibrary(); //step 2 setup the stack context. - - int alreadySwapped = 0; - getcontext( &savedSnapshotContext ); - if( !alreadySwapped ){ - alreadySwapped = 1; - ucontext_t currentContext, swappedContext, newContext; - getcontext( &newContext ); - newContext.uc_stack.ss_sp = sTheRecord->mStackBase; - newContext.uc_stack.ss_size = STACK_SIZE_DEFAULT; - newContext.uc_link = ¤tContext; - makecontext( &newContext, entryPoint, 0 ); - swapcontext( &swappedContext, &newContext ); - } - - //add the code to take a snapshot here... - //to return to user process, do a second swapcontext... + ucontext_t newContext; + getcontext( &newContext ); + newContext.uc_stack.ss_sp = sTheRecord->mStackBase; + 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); + + /* switch back here when takesnapshot is called */ pid_t forkedID = 0; snapshotid = sTheRecord->currSnapShotID; bool swapContext = false; - while( !sTheRecord->mbFinalize ){ + while( true ){ sTheRecord->currSnapShotID=snapshotid+1; forkedID = fork(); if( 0 == forkedID ){ ucontext_t currentContext; -#if 0 - int dbg = 0; - while( !dbg ); -#endif + /*If the rollback bool is set{ see below }, switch to the context we need to return to during a rollback*/ if( swapContext ) swapcontext( ¤tContext, &( sTheRecord->mContextToRollback ) ); else{ + /*Child process which is forked as a result of takesnapshot call should switch back to the takesnapshot context*/ swapcontext( ¤tContext, &savedUserSnapshotContext ); } } else { @@ -225,6 +226,7 @@ void initSnapShotLibrary(unsigned int numbackingpages, if( sTheRecord->mIDToRollback != snapshotid ) exit(EXIT_SUCCESS); else{ + /*This bool indicates that the current process's snapshotid is same as the id to which the rollback needs to occur*/ swapContext = true; } } @@ -306,19 +308,21 @@ void rollBack( snapshot_id theID ){ sTheRecord->mIDToRollback = theID; int sTemp = 0; getcontext( &sTheRecord->mContextToRollback ); + /* + * This is used to quit the process on rollback, so that + * the process which needs to rollback can quit allowing the process whose snapshotid matches the rollbackid to switch to + * this context and continue.... + */ if( !sTemp ){ sTemp = 1; SSDEBUG("Invoked rollback"); exit(EXIT_SUCCESS); } + /* + * This fix obviates the need for a finalize call. hence less dependences for model-checker.... + * + */ + sTheRecord->mIDToRollback = -1; #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; -#endif -}