home *** CD-ROM | disk | FTP | other *** search
- /*
- * recover.c - Emerald Checkpoint operation recovery routines
- *
- * Copyright 1986 Eric Jul and Norm Hutchinson.
- * Copyright 1988 Clinton Jeffery
- * May not be used for any purpose without written permission from the authors.
- * The Emerald kernel for the Emerald programming language.
- *
- * This code was inspired by portions of mobility.c and locate.c
- */
- #include <sys/file.h>
- #include <stdio.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/consts.h"
- #include "Kernel/h/utils.h"
- #include "Kernel/h/cPLog.h"
- #include "Kernel/h/replicant.h"
-
- extern void UnblockInitially();
- extern char *BrandNames[];
- extern Boolean LoadRequest();
- extern ODP OTLookup();
-
-
- /* forwards */
- HResult RecoverItemHandler();
- HResult RecoverCallBack();
-
- typedef struct TRec {
- OID theOID;
- Offset theOffset;
- } TRec, *TRecPtr;
-
- /*
- * RecoverItemHandler
- */
- HResult RecoverItemHandler(fHandlePtr, theOldODP)
- replicantPtr fHandlePtr; /* this is just a magic cookie */
- ODP theOldODP;
- {
- MoveItem item; /* this is a struct { ItemHdr hdr; ODP oldODP; } */
- extern void TriggerCallBacks();
-
- item.oldODP = theOldODP;
- theOldODP = NULL; /* this variable is used later in another context*/
- KMDTrace("Recover", 3, "RecoverItemHandler\n");
-
- TriggerCallBacks((LMHandle *)fHandlePtr, &item, 1);
- }
-
- /*
- * RecoverCallBack
- */
- HResult RecoverCallBack(fReq, fOID)
- GenericReqPtr fReq;
- OID fOID;
- {
- register IncomingMoveReqPtr req;
- extern void DoTranslate(), StartProcessAtAddr();
- req = (IncomingMoveReqPtr) fReq;
- KMDTrace("Recover", 4, "RecoverCallBack; OID %s status %s\n", PPOID(fOID),
- req->status == IMLoadingCode ? "Loading Code" :
- req->status == IMCodeLoadDone? "Code load done" :
- "BAD STATUS");
-
- switch (req->status) {
-
- case IMLoadingCode: {
- ODP oldODP;
- CodeODP newODP;
-
- /* Requested code has arrived */
- oldODP = (ODP) Map_Lookup(req->neededMap, (int) fOID);
-
- if (IsNIL(oldODP)) {
- ErrMsg("RecoverCallBack %s -- ignored\n");
- return;
- }
- Map_Delete(req->neededMap, (int) fOID);
-
- newODP = (CodeODP) OTLookup(fOID);
- assert(NonNULL(newODP));
-
- /* (Note, m uses the pointer to the code area.) */
- KMDTrace("CPTT", 5, "CPTT Map_Insert: (0x%06x -> 0x%06x) for code %s\n",
- oldODP, newODP->dataPtr, PPCodePtr(newODP->dataPtr));
- Map_Insert(req->m, (int) oldODP, (int) newODP->dataPtr);
-
- if (Map_Count(req->neededMap) == 0) {
- KMDTrace("Recover", 4, "All needed code loaded\n");
- req->status = IMCodeLoadDone;
- RecoverCallBack((GenericReqPtr) req, (OID) NULL);
- }
- break;
- }
-
- case IMCodeLoadDone: {
-
- /* All needed code has been loaded, now translate */
- DoTranslate(req->newSet, req->m, 1); /*1 is a recovery flag*/
-
- /* All done now, cleanup */
- Map_Destroy(req->m);
- Map_Destroy(req->neededMap);
- Set_Destroy(req->newSet);
-
- #if 1
- /* Gee, where should the recovery process start up? Lets try here */
- /* this code rehashed from MakeObject in kOps.c */
- {
- CodePtr cType;
- register GODP x;
- SSPtr p;
- extern SSPtr NewProcess();
-
- /* figure out how to fill the parameters */
- x = ((GODP)(req->travellerODP));
- assert(x != (GODP) NULL);
- if( ((x->dataPtr) != (struct GOData *)NULL) &&
- ((cType = (CodePtr)(x->dataPtr->myCodePtr))!= (CodePtr)NULL)) {
- /* Now make a global call of the object's recovery section, if any */
- if (cType->recovery.offset) {
- KMDTrace("Recover",4, "Recovery code for object 0x%04x starts\n",x);
- x->tag.setUpDone = FALSE;
- x->tag.frozen = TRUE;
- x->tag.isResident = TRUE;
- x->tag.xref = TRUE; /* support for local gc */
- x->dataPtr->tag.setUpDone = FALSE;
- x->dataPtr->tag.frozen = TRUE;
- x->dataPtr->tag.isResident= TRUE;
- x->dataPtr->tag.xref = TRUE; /* support for local gc */
- p = NewProcess();
- StartProcessAtAddr(p, x, x->dataPtr,
- (CodeAddr) addOffset(cType, cType->recovery.offset));
-
- } else { /* No recovery */
- x->tag.setUpDone = TRUE;
- x->tag.frozen = FALSE;
- x->tag.isResident = TRUE;
- x->tag.xref = TRUE; /* support for local gc */
- x->dataPtr->tag.setUpDone = TRUE;
- x->dataPtr->tag.frozen = FALSE;
- x->dataPtr->tag.isResident= TRUE;
- x->dataPtr->tag.xref = TRUE; /* support for local gc */
- UnblockInitially(x);
- }
- }
- }
- #endif
-
- FreeRequest((GenericReqPtr) req);
- break;
- }
- default:
- ErrMsg("Bad move status %d in RecoverCallBack\n", req->status);
- (void) abort();
- }
- }
-