home *** CD-ROM | disk | FTP | other *** search
- /*
- * checkPoint.c - Emerald Checkpoint operation
- *
- * Copyright 1986 Eric Jul and Norm Hutchinson.
- * Copyright 1987, 1988 Clinton Jeffery
- * May not be used for any purpose without written permission from the authors.
- * The Emerald kernel for the Emerald programming language.
- * Last edit: 1/30/88
- *
- */
- #include <sys/file.h>
- #include <stdio.h>
- #include <ndbm.h>
- #include "Kernel/h/system.h"
- #include "Kernel/h/assert.h"
- #include "Kernel/h/macros.h"
- #include "Kernel/h/errMsgs.h"
- #include "Kernel/h/mmCodes.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/timerTypes.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/kEvents.h"
- #include "Kernel/h/emCodes.h"
- #include "Kernel/h/mmMsgTypes.h"
- #include "Kernel/h/lmTypes.h"
- #include "Kernel/h/emkDefs.h"
- #include "Kernel/h/lmCodes.h"
- #include "Kernel/h/hotsTypes.h"
- #include "Kernel/h/map.h"
- #include "Kernel/h/set.h"
- #include "Kernel/h/expandArray.h"
- #include "Kernel/h/consts.h"
- #include "Kernel/h/utils.h"
-
- #include "Kernel/h/cPLog.h"
- #include "Kernel/h/cPDBM.h"
- #include "Kernel/h/checkPoint.h"
- #include "Kernel/h/replicant.h"
-
- /* External declarations */
- extern OID getNextOID();
- extern SSPtr preemptRunning();
- extern void unavail(), OTInsert();
- extern char *BrandNames[];
- extern ODP OTLookup();
- extern char NODEDIR[];
- extern AbConPtr OIDOIDOIDToAbCon();
-
- /* Counters from measure.c */
- extern int cCP_CheckpointsDone, cCP_CheckpointsBytesSent;
-
- /* Forward declarations */
- void CPInit();
- void Checkpoint();
- void CheckpointToTTable();
- void CheckpointVarToTTable();
- void AddVarToCPTTable();
- void AddToCPTTable();
- void TraverseAndCheckpoint();
-
- extern TTGODEntry godEntry;
- extern TTCondEntry condEntry;
- extern TTSSODEntry ssodEntry;
- extern TTAbConEntry abconEntry;
- extern TTCEntry codeodEntry;
- extern TTLOEntry loEntry;
- extern TTMoveGODEntry movegodEntry;
- extern TTMoveCEntry movecodeodEntry;
- extern TTFetchGODEntry fetchgodEntry;
- extern TTCodeAddrEntry codeaddrEntry;
- extern TTMoveCondEntry moveCondEntry;
-
- /*******************
- * CPInit *
- *******************/
- void CPInit()
- {
- GODP recoveryOTE;
- extern int onlyFindingOIDs;
-
- /* set up kmd stuff */
- KMDSetTrace(Checkpoint);
- KMDTrace("Checkpoint", 5,"Checkpoint Init\n");
- KMDSetTrace(CPTT);
- KMDTrace("CPTT", 5,"CheckpointTT Init\n");
- KMDSetTrace(Recover);
- KMDTrace("Recover", 5, "Recover Init\n");
- /* note: recover.c also uses CPTT for TT-specific operations;
- structure is modeled on the original Jul code... */
-
- /* open files */
- if (!CP_InitDbase()) {
- ErrMsg("Checkpoint cannot initialize dbase\n");
- abort();
- }
- KMDTrace("Checkpoint", 5, "Dbase initialized\n");
- if (CP_InitRecover()<0) { /* open logfile, stage 1 */
- ErrMsg("Checkpoint cannot initialize recovery process\n");
- abort();
- }
- KMDTrace("Checkpoint", 5, "Recovery initialized\n");
-
- /* Recovery: iterate over the entire dbase: */
- while((recoveryOTE = CP_LoadDbase()) != (GODP) NULL) {
- /* reconstruct logfile entry's objects */
- if(CP_Recover(recoveryOTE)<0){
- KMDTrace("Checkpoint", 5, "Attempted object recovery fails!\n");
- }
- emfree(recoveryOTE);
- }
- KMDTrace("Checkpoint", 5, "All objects recovered\n");
-
- if (CP_EndRecover()<0){ /* reopen logfile, stage 2 */
- ErrMsg("Checkpoint cannot initialize logfile for further checkpoints\n");
- abort();
- }
- KMDTrace("Checkpoint", 5, "Checkpoint module initialized\n");
- if (onlyFindingOIDs) exit(0);
- }
-
- void CP_writeCompiledCodeFile(theODP)
- GODP theODP; /* ODP for object to Checkpoint */
- /* Write the compiled code for the given object into the local Emerald file system.
- * This is used in connection with the garbage collection of compiled code files.
- */
- {
- CodeODP theCodeODP;
- CodePtr theCode;
- DotoFilePtr theDotoFile;
-
- theCodeODP = (CodeODP)OTLookup(theODP->myCodeOID);
- assert(!theCodeODP);
- theCode = theCodeODP->dataPtr;
-
- theDotoFile = mDotoFilePtrFromCodePtr(theCode);
-
- KMDTrace("Checkpoint", 3, "CP_writeCompiledCodeFile: OID=0x%08x\n", theODP->ownOID);
- }
-
- /**************************************
- * Checkpoint (Kernel call) *
- **************************************/
-
- void Checkpoint() /* From: Move(), by eric */
- /* Checkpoint the object on top of the stack. The object and its friends
- * are saved to the logfile, and their Object Table entries are updated.
- * The object is marked FIXed.
- * I am not sure whether the process continues execution when the move
- * has been initiated or not; depends on whether they mind us mungeing...
- */
- {
- GODP theODP; /* ODP for object to Checkpoint */
- AbConPtr theAbCon; /* abcon for same */
- Map m; /* ODP moved */
- Set dummy;
- KKStatus kstat;
- long thisLogOffset, thisLogSize;
- extern void MoveToTTable();
- /* Who am I ? */
- if (!currentSSP->regs.g->tag.global) {
- KMDTrace("Checkpoint", 3, "Object isn't global\n");
- ErrMsg("Cannot Checkpoint object tagged as %s -- possible compiler error\n",
- PPODBasicTag(currentSSP->regs.g->tag.tag));
- return ;
- }
- theODP = currentSSP->regs.b;
-
- KMDTrace("Checkpoint", 3, "Checkpoint of object (0x%08x)\n", theODP);
-
- /* Start by dispensing with the trivial cases: */
- if (!PPValidAddr((SSAddr *) theODP)) {
- KMDTrace("Checkpoint", 3, "Object is NIL\n",theODP); /*arg is for linting chkpt w/o kmd */
- return;
- }
-
- if (theODP->tag.tag == CondTag) {
- KMDTrace("Checkpoint", 3, "Checkpoint of condition 0x%06x ignored\n", theODP);
- return;
- }
-
- if (theODP->tag.tag != GODTag) {
- ErrMsg("Cannot Checkpoint object tagged as %s -- possible compiler error\n",
- PPODBasicTag(theODP->tag.tag));
- abort();
- }
-
- if (!theODP->tag.isResident) {
- ErrMsg("Implementation restriction; cannot Checkpoint remote object - ignored\n");
- return;
- }
-
- /* OK, go for it */
-
- if(CP_InitReplicant()<0){
- ErrMsg("No memory available for checkpoint! Die...die...\n");
- abort();
- }
-
- /* first, check &/or assign a valid OID to this object */
- if(theODP->ownOID == 0) {
- theODP->ownOID = getNextOID();
- KMDTrace("Checkpoint", 5,"Checkpointing object gets assigned OID 0x%06x\n",
- theODP->ownOID);
- OTInsert((ODP)theODP);
- }
-
- thisLogOffset = CP_StartEntry(theODP->ownOID,LF);
-
- if (thisLogOffset<0) {
- KMDTrace("Checkpoint", 2, "%s CP_startEntry fails; unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
- KMDTrace("Failure", 3, "%s CP_startEntry fails; unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
-
- theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
- (OID)EMNIL,
- theODP->dataPtr->myCodePtr->ownOID);
-
- unavail(preemptRunning(), theODP, theAbCon);
- return;
- }
-
- /*
- * Before the checkpointing itself make sure that the compiled code file exists
- * in the local Emerald file system.
- */
- #if 0
- CP_writeCompiledCodeFile(theODP);
- #endif
-
- m = Map_Create(); /* Create moved map */
- dummy = Set_Create();
-
- MoveToTTable((LMHandle *)0, (ODP) theODP, m, dummy);
-
- Set_Destroy(dummy);
- Map_Destroy(m); /* Clean up */
-
- kstat = CP_EndEntry(LF);
- if (kstat==EOF) {
- KMDTrace("Checkpoint", 2, "%s cPend_entry fails; unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
- theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
- (OID)EMNIL,
- theODP->dataPtr->myCodePtr->ownOID);
-
- unavail(preemptRunning(), theODP, theAbCon);
- return;
- }
-
- /*
- * Count number of Checkpoints.
- */
- cCP_CheckpointsDone++;
- cCP_CheckpointsBytesSent += (thisLogSize = CP_CurrentPosition);
-
- if(CP_WriteDbase((ODP) theODP,thisLogOffset,thisLogSize,CP_DBM)<0) {
- KMDTrace("Checkpoint", 2, "%s cP_write_dbase fails; unavailable in %s\n",
- PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
- theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
- (OID)EMNIL,
- theODP->dataPtr->myCodePtr->ownOID);
-
- unavail(preemptRunning(), theODP, theAbCon);
- return;
- }
-
- KMDTrace("Checkpoint", 3, "cPSequence number %d++",theODP->cPSequenceNum++);
-
- if(theODP->Replicant != (char *)EMNIL) { /* free it up */
- replicant_destroy((replicantPtr)theODP->Replicant);
- }
- theODP->Replicant = (char *)CP_replicant;
-
- KMDTrace("Checkpoint", 3, "Checkpoint of object (0x%08x) succeeds\n",theODP);
- }
-
-