+ if( sigaction( SIGSEGV, &sa, NULL ) == -1 ){
+ printf("SIGACTION CANNOT BE INSTALLED\n");
+ 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
+ // 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);
+ snapshotrecord->lastBackingPage--; //remove the fake page we copied
+
+ basemySpace=MYMALLOC((numheappages+1)*PAGESIZE);
+ void * pagealignedbase=PageAlignAddressUpward(basemySpace);
+ mySpace = create_mspace_with_base(pagealignedbase, numheappages*PAGESIZE, 1 );
+ addMemoryRegionToSnapShot(pagealignedbase, numheappages);
+ entryPoint();
+}
+#else
+void initSnapShotLibrary(unsigned int numbackingpages,
+ unsigned int numsnapshots, unsigned int nummemoryregions,
+ unsigned int numheappages, VoidFuncPtr entryPoint) {
+ basemySpace=system_malloc((numheappages+1)*PAGESIZE);
+ void * pagealignedbase=PageAlignAddressUpward(basemySpace);
+ mySpace = create_mspace_with_base(pagealignedbase, numheappages*PAGESIZE, 1 );
+ if (!snapshotrecord)
+ createSharedMemory();
+
+ //step 2 setup the stack context.
+ ucontext_t newContext;
+ getcontext( &newContext );
+ newContext.uc_stack.ss_sp = snapshotrecord->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 = snapshotrecord->currSnapShotID;
+ /* This bool indicates that the current process's snapshotid is same
+ as the id to which the rollback needs to occur */
+
+ bool rollback = false;
+ while( true ){
+ snapshotrecord->currSnapShotID=snapshotid+1;
+ forkedID = fork();
+
+ if( 0 == forkedID ){
+ /* If the rollback bool is set, switch to the context we need to
+ return to during a rollback. */
+ if( rollback) {
+ setcontext( &( snapshotrecord->mContextToRollback ) );
+ } else {
+ /*Child process which is forked as a result of takesnapshot
+ call should switch back to the takesnapshot context*/
+ setcontext( &savedUserSnapshotContext );