home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Checkpoint / checkPoint.c next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  8.3 KB  |  278 lines

  1. /*
  2.  * checkPoint.c - Emerald Checkpoint operation
  3.  *
  4.  * Copyright 1986 Eric Jul and Norm Hutchinson.
  5.  * Copyright 1987, 1988 Clinton Jeffery
  6.  * May not be used for any purpose without written permission from the authors.
  7.  * The Emerald kernel for the Emerald programming language.
  8.  * Last edit: 1/30/88
  9.  *
  10.  */
  11. #include <sys/file.h>
  12. #include <stdio.h>
  13. #include <ndbm.h>
  14. #include "Kernel/h/system.h"
  15. #include "Kernel/h/assert.h"
  16. #include "Kernel/h/macros.h"
  17. #include "Kernel/h/errMsgs.h"
  18. #include "Kernel/h/mmCodes.h"
  19. #include "Kernel/h/emTypes.h"
  20. #include "Kernel/h/timerTypes.h"
  21. #include "Kernel/h/kmdTypes.h"
  22. #include "Kernel/h/kEvents.h"
  23. #include "Kernel/h/emCodes.h"
  24. #include "Kernel/h/mmMsgTypes.h"
  25. #include "Kernel/h/lmTypes.h"
  26. #include "Kernel/h/emkDefs.h"
  27. #include "Kernel/h/lmCodes.h"
  28. #include "Kernel/h/hotsTypes.h"
  29. #include "Kernel/h/map.h"
  30. #include "Kernel/h/set.h"
  31. #include "Kernel/h/expandArray.h"
  32. #include "Kernel/h/consts.h"
  33. #include "Kernel/h/utils.h"
  34.  
  35. #include "Kernel/h/cPLog.h"
  36. #include "Kernel/h/cPDBM.h"
  37. #include "Kernel/h/checkPoint.h"
  38. #include "Kernel/h/replicant.h"
  39.  
  40. /* External declarations */
  41. extern    OID getNextOID();
  42. extern SSPtr   preemptRunning();
  43. extern void    unavail(), OTInsert();
  44. extern char   *BrandNames[];
  45. extern ODP     OTLookup();
  46. extern char    NODEDIR[];
  47. extern AbConPtr OIDOIDOIDToAbCon();
  48.  
  49. /* Counters from measure.c */
  50. extern int cCP_CheckpointsDone, cCP_CheckpointsBytesSent;
  51.  
  52. /* Forward declarations */
  53. void CPInit();
  54. void Checkpoint();
  55. void CheckpointToTTable();
  56. void CheckpointVarToTTable();
  57. void AddVarToCPTTable();
  58. void AddToCPTTable();
  59. void TraverseAndCheckpoint();
  60.  
  61. extern TTGODEntry              godEntry;
  62. extern TTCondEntry             condEntry;
  63. extern TTSSODEntry             ssodEntry;
  64. extern TTAbConEntry            abconEntry;
  65. extern TTCEntry                codeodEntry;
  66. extern TTLOEntry               loEntry;
  67. extern TTMoveGODEntry          movegodEntry;
  68. extern TTMoveCEntry            movecodeodEntry;
  69. extern TTFetchGODEntry         fetchgodEntry;
  70. extern TTCodeAddrEntry         codeaddrEntry;
  71. extern TTMoveCondEntry         moveCondEntry;
  72.  
  73. /*******************
  74.  *      CPInit     *
  75.  *******************/
  76. void CPInit()
  77. {
  78.   GODP recoveryOTE;
  79.   extern int onlyFindingOIDs;
  80.  
  81.   /* set up kmd stuff */
  82.   KMDSetTrace(Checkpoint);
  83.   KMDTrace("Checkpoint", 5,"Checkpoint Init\n");
  84.   KMDSetTrace(CPTT);
  85.   KMDTrace("CPTT", 5,"CheckpointTT Init\n");
  86.   KMDSetTrace(Recover);
  87.   KMDTrace("Recover", 5, "Recover Init\n");
  88.   /* note: recover.c also uses CPTT for TT-specific operations;
  89.      structure is modeled on the original Jul code...          */
  90.  
  91.   /* open files */
  92.   if (!CP_InitDbase()) {
  93.     ErrMsg("Checkpoint cannot initialize dbase\n");
  94.     abort();
  95.   }
  96.   KMDTrace("Checkpoint", 5, "Dbase initialized\n");
  97.   if (CP_InitRecover()<0) { /* open logfile, stage 1 */
  98.     ErrMsg("Checkpoint cannot initialize recovery process\n");
  99.     abort();
  100.   }
  101.   KMDTrace("Checkpoint", 5, "Recovery initialized\n");
  102.  
  103.   /* Recovery: iterate over the entire dbase: */
  104.   while((recoveryOTE = CP_LoadDbase()) != (GODP) NULL) {
  105.     /* reconstruct logfile entry's objects */
  106.     if(CP_Recover(recoveryOTE)<0){
  107.       KMDTrace("Checkpoint", 5, "Attempted object recovery fails!\n");
  108.     }
  109.     emfree(recoveryOTE);
  110.   }
  111.   KMDTrace("Checkpoint", 5, "All objects recovered\n");
  112.  
  113.   if (CP_EndRecover()<0){    /* reopen logfile, stage 2 */
  114.     ErrMsg("Checkpoint cannot initialize logfile for further checkpoints\n");
  115.     abort();
  116.   }
  117.   KMDTrace("Checkpoint", 5, "Checkpoint module initialized\n");
  118.   if (onlyFindingOIDs) exit(0);
  119. }
  120.  
  121. void CP_writeCompiledCodeFile(theODP)
  122. GODP      theODP;     /* ODP for object to Checkpoint */
  123. /* Write the compiled code for the given object into the local Emerald file system.
  124.  * This is used in connection with the garbage collection of compiled code files.
  125.  */
  126. {
  127.     CodeODP        theCodeODP;
  128.     CodePtr        theCode;
  129.     DotoFilePtr        theDotoFile;
  130.  
  131.     theCodeODP = (CodeODP)OTLookup(theODP->myCodeOID);
  132.     assert(!theCodeODP);
  133.     theCode = theCodeODP->dataPtr;
  134.  
  135.     theDotoFile = mDotoFilePtrFromCodePtr(theCode);
  136.  
  137.     KMDTrace("Checkpoint", 3, "CP_writeCompiledCodeFile: OID=0x%08x\n", theODP->ownOID);
  138. }
  139.  
  140. /**************************************
  141.  *      Checkpoint (Kernel call)      *
  142.  **************************************/
  143.  
  144. void Checkpoint() /* From: Move(), by eric */
  145. /* Checkpoint the object on top of the stack.  The object and its friends
  146.  * are saved to the logfile, and their Object Table entries are updated.
  147.  * The object is marked FIXed.
  148.  * I am not sure whether the process continues execution when the move
  149.  * has been initiated or not; depends on whether they mind us mungeing...
  150.  */
  151. {
  152.   GODP      theODP;     /* ODP for object to Checkpoint */
  153.   AbConPtr  theAbCon;   /* abcon for same */
  154.   Map       m;          /* ODP moved */
  155.   Set       dummy;
  156.   KKStatus  kstat;      
  157.   long      thisLogOffset, thisLogSize;
  158.   extern void MoveToTTable();
  159.   /* Who am I ? */
  160.   if (!currentSSP->regs.g->tag.global) {
  161.     KMDTrace("Checkpoint", 3, "Object isn't global\n");
  162.     ErrMsg("Cannot Checkpoint object tagged as %s -- possible compiler error\n",
  163.        PPODBasicTag(currentSSP->regs.g->tag.tag));
  164.     return ;
  165.   }
  166.   theODP = currentSSP->regs.b;
  167.  
  168.   KMDTrace("Checkpoint", 3, "Checkpoint of object (0x%08x)\n", theODP);
  169.  
  170.   /* Start by dispensing with the trivial cases: */
  171.   if (!PPValidAddr((SSAddr *) theODP)) {
  172.     KMDTrace("Checkpoint", 3, "Object is NIL\n",theODP); /*arg is for linting chkpt w/o kmd */
  173.     return;
  174.   }
  175.  
  176.   if (theODP->tag.tag == CondTag) {
  177.     KMDTrace("Checkpoint", 3, "Checkpoint of condition 0x%06x ignored\n", theODP);
  178.     return;
  179.   }
  180.     
  181.   if (theODP->tag.tag != GODTag) {
  182.     ErrMsg("Cannot Checkpoint object tagged as %s -- possible compiler error\n",
  183.        PPODBasicTag(theODP->tag.tag));
  184.     abort();
  185.   }
  186.  
  187.   if (!theODP->tag.isResident) {
  188.     ErrMsg("Implementation restriction; cannot Checkpoint remote object - ignored\n");
  189.     return;
  190.   }
  191.  
  192.   /* OK, go for it */
  193.  
  194.   if(CP_InitReplicant()<0){
  195.     ErrMsg("No memory available for checkpoint!  Die...die...\n");
  196.     abort();
  197.   }
  198.  
  199.   /* first, check &/or assign a valid OID to this object */
  200.   if(theODP->ownOID == 0) {
  201.     theODP->ownOID = getNextOID();
  202.     KMDTrace("Checkpoint", 5,"Checkpointing object gets assigned OID 0x%06x\n",
  203.          theODP->ownOID);
  204.     OTInsert((ODP)theODP);
  205.   }
  206.  
  207.   thisLogOffset = CP_StartEntry(theODP->ownOID,LF);
  208.  
  209.   if (thisLogOffset<0) {
  210.     KMDTrace("Checkpoint", 2, "%s CP_startEntry fails; unavailable in %s\n",
  211.          PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
  212.     KMDTrace("Failure", 3, "%s CP_startEntry fails; unavailable in %s\n",
  213.          PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
  214.  
  215.     theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
  216.                 (OID)EMNIL,
  217.                 theODP->dataPtr->myCodePtr->ownOID);
  218.  
  219.     unavail(preemptRunning(), theODP, theAbCon);
  220.     return;
  221.   }
  222.  
  223.   /*
  224.    * Before the checkpointing itself make sure that the compiled code file exists
  225.    * in the local Emerald file system.
  226.    */
  227. #if 0
  228.   CP_writeCompiledCodeFile(theODP);
  229. #endif
  230.  
  231.   m = Map_Create();  /* Create moved map */
  232.   dummy = Set_Create();
  233.  
  234.   MoveToTTable((LMHandle *)0, (ODP) theODP, m, dummy);
  235.  
  236.   Set_Destroy(dummy);
  237.   Map_Destroy(m);  /* Clean up */
  238.     
  239.   kstat = CP_EndEntry(LF);
  240.   if (kstat==EOF) {
  241.     KMDTrace("Checkpoint", 2, "%s cPend_entry fails; unavailable in %s\n",
  242.          PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
  243.     theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
  244.                 (OID)EMNIL,
  245.                 theODP->dataPtr->myCodePtr->ownOID);
  246.  
  247.     unavail(preemptRunning(), theODP, theAbCon);
  248.     return;
  249.   }
  250.  
  251.   /*
  252.    * Count number of Checkpoints.
  253.    */
  254.   cCP_CheckpointsDone++;
  255.   cCP_CheckpointsBytesSent += (thisLogSize = CP_CurrentPosition);
  256.  
  257.   if(CP_WriteDbase((ODP) theODP,thisLogOffset,thisLogSize,CP_DBM)<0) {
  258.     KMDTrace("Checkpoint", 2, "%s cP_write_dbase fails; unavailable in %s\n",
  259.          PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
  260.     theAbCon = OIDOIDOIDToAbCon(theODP->dataPtr->myCodePtr->ownAbstractType,
  261.                 (OID)EMNIL,
  262.                 theODP->dataPtr->myCodePtr->ownOID);
  263.  
  264.     unavail(preemptRunning(), theODP, theAbCon);
  265.     return;
  266.   }
  267.  
  268.   KMDTrace("Checkpoint", 3, "cPSequence number %d++",theODP->cPSequenceNum++);
  269.  
  270.   if(theODP->Replicant != (char *)EMNIL) { /* free it up */
  271.     replicant_destroy((replicantPtr)theODP->Replicant);
  272.   }
  273.   theODP->Replicant = (char *)CP_replicant;
  274.  
  275.   KMDTrace("Checkpoint", 3, "Checkpoint of object (0x%08x) succeeds\n",theODP);
  276. }
  277.  
  278.