⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checkpoint.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//***************************************************************** * checkpoint.c *  * Generic checkpoint handling code.  *****************************************************************/#include <stdio.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include "sim.h"#include "simutil.h"#include "sim_error.h"#include "cpu_interface.h"#include "remote_access.h"#include "checkpoint.h"#include "cpu_interface.h"#include "machine_params.h"#include "params.h"#define MAX_GROUPS 50#define MAX_LENGTH 128#define IS_REMOTE_CPT(NAME) (strchr(NAME,':') != NULL)typedef enum cpttype {CPT_INTEGER = 0, CPT_STRING, CPT_BLOCK} CptType;static char lineFormat[3][20] = {"%s = %s", "%s [%d] = %s", "%s [%d,%d] = %s"};#ifdef __alpha#define INT_FORMAT "int:%ld"#define HEX_FORMAT "int:0x%lx"#define BLOCK_FORMAT "binary:position=%ld,size=%ld;"typedef long cptlong;#else#define INT_FORMAT "int:%lld"#define HEX_FORMAT "int:0x%llx"#define BLOCK_FORMAT "binary:position=%lld,size=%lld;"typedef int64 cptlong;#endif#define STRING_FORMAT "string:%s"typedef struct compressiondata {   CptCompression type;   char compress[MAX_PATH_LENGTH];   char decompress[MAX_PATH_LENGTH];   char extender[10];} CompressionData;typedef struct cptentry {   char *name;   int i1, i2;   CptType type;   bool optional;   int64 intval;   int64 ptrval;   struct cptentry *prev;   struct cptentry *next;} CptEntry;typedef struct cptgroup {   char *tag;   FILE *stream;   int binfd;   int binpos;   int failure;   CptCompression compressCpt[2];   CptCompression compressBin[2];   CptEntry *tail;   CptEntry *hint;   CptCallback *callback[NUM_CPU_TYPES];} CptGroup;static CptGroup cptGroup[MAX_GROUPS];static int cptNumGroups;static bool cptRemote;static CompressionData compression[] = {   { NO_COMPRESSION, "cat", "cat", "" },   { GZIP, "gzip", "gunzip", ".gz" },   { COMPRESS, "compress", "zcat", ".Z" }};typedef enum {ITER_CPT, ITER_LOG, NUM_ITERS} CptIter;static CptGroup *NewGroup(char *tag);static CptGroup *FindGroup(char *tag);static CptGroup *IterGroup(CptIter num);static CptEntry *NewEntry(char *name, int i1, int i2, CptType type);static void AddEntry(CptGroup *group, CptEntry *entry);static void FreeEntry(CptEntry *entry);static CptEntry *FindEntryInList(CptGroup *group, char *name, int i1, int i2);static CptEntry *FindEntryInFile(CptGroup *group, char *name, int i1, int i2);static bool ParseInteger(char *str, cptlong *val);static bool ParseBlock(char *str, cptlong *ptr, cptlong *val);static bool ParseString(char *str, char *val);static int64 ReadInteger(CptGroup *group, char *name,                              int i1, int i2);static char *ReadString(CptGroup *group, char *name,                         int i1, int i2);static int64 ReadBlock(CptGroup *group, char *name,                            int i1, int i2, int *size);static void WriteHexInteger(CptGroup *group, char *name,                             int i1, int i2, int64 val);static void WriteInteger(CptGroup *group, char *name,                          int i1, int i2, int64 val);static void WriteString(CptGroup *group, char *name,                         int i1, int i2, char *ptr);static void WriteBlock(CptGroup *group, char *name,                        int i1, int i2, int64 pos, int64 val);static CptCallback LogCheckpointCB;static FILE *OpenFile(CptMode mode, char *filename, CptCompression compress);static FILE *OpenCompressedFile(CptMode mode, CptCompression c, FILE *fp);static void OpenCptFile(CptMode mode, CptGroup *group);static void OpenBinFile(CptMode mode, CptGroup *group);static void CloseCptFile(CptGroup *group);static void CloseBinFile(CptGroup *group);static void SaveLine(CptGroup *group, char *name,                      int i1, int i2, char *valstring);static int RestoreLine(CptGroup *group, char *name,                        int *i1, int *i2, char *valstring);static void SaveBlock(CptGroup *group, caddr_t addr, int size);static int RestoreBlock(CptGroup *group, caddr_t addr, int pos, int size);static int outputFD = -1;static int compressPID = -1;char *CheckpointID;int CheckpointCompress;char *cptSaveDir;char cptName[MAX_PATH_LENGTH];CptVersion cptVersion;voidSimcpt_Init(void){   cptSaveDir = SaveString(".");   cptNumGroups = 0;   cptVersion.saveVer = CPT_VERSION;   cptVersion.saveSub = CPT_SUB_VERSION;   Simcpt_Register("log", LogCheckpointCB, ALL_CPUS);}extern char *EthersimHostname;      /* crissy */extern char *EtherAddress;          /* 8:1:2:3:4:60 */voidSimcpt_Register(char *tag, CptCallback *callback, CPUType cputype){   CptGroup *group = NewGroup(tag);   if (group != NULL) {      if (cputype == ALL_CPUS) {         for (cputype = BASE; cputype < NUM_CPU_TYPES; cputype++) {            group->callback[cputype] = callback;         }      } else if (cputype != NO_CPU) {         group->callback[cputype] = callback;      }   }}voidSimcpt_UseCompression(char *name, CptCompression compress,                       CptCompressMode mode){   CptGroup *group = FindGroup(name);   if (!CheckpointCompress) return;   if (group != NULL) {      if (mode != CPT_FILE_ONLY)         group->compressBin[CPT_SAVE] = compress;      if (mode != BIN_FILE_ONLY)         group->compressCpt[CPT_SAVE] = compress;   }}intCheckpointFile(CptMode mode, CptGroup *group){   CptDescriptor cptd;   int retval = 0;   CPUType cputype = (mode == CPT_SAVE)?simosCPUType:BASE;   /* CPUType cputype = CPUVec.cpuType;*/   cptd.mode = mode;   cptd.group = group;      SIM_DEBUG(('g', "CPT: %s checkpoint file %s\n",               mode == CPT_SAVE ? "Saving" : "Restoring", group->tag));      cptd.group->failure = FALSE;   /* Ugly hack -- when restoring the execstate, always use the base      mode callback */   if (!strcmp(group->tag, "execstate") && (mode == CPT_RESTORE))      cputype = BASE;   /* Even uglier hack: Tcl manages the file itself, so don't go    * through the usual opening/closing stuff.    */   if (!strcmp(group->tag, "tcl")) {     ASSERT(group->callback[cputype]);     retval = (group->callback[cputype])(&cptd);     goto done;   }        if (group->callback[cputype] == NULL) {      if (!strcmp(group->tag,"HOHA")) {          /*           * I guess that HOHA already stands for horrible hack anyway          */         return 0;      }      CPUWarning("CPT: Cpt failed -- no callback registered for %s in %s\n",                 group->tag, simName[cputype]);      return -1;         }   Simcpt_Begin(&cptd);   retval = (group->callback[cputype])(&cptd);   Simcpt_End(&cptd);done:   group->failure = group->failure || (retval != 0);   if (group->failure) CPUError("CPT: Checkpoint failed, tag = %s\n",                                 group->tag);   SIM_DEBUG(('g', "CPT: Done %s checkpoint file %s\n",              mode == CPT_SAVE ? "saving" : "restoring", group->tag));   return (group->failure) ? -1 : 0;}voidSimcpt_Checkpoint(CptMode mode, char *name){   CptGroup *group;   if (mode == CPT_SAVE) {      int num;      char pathname[MAX_PATH_LENGTH];      /* Check if the checkpoint save directory exists and is writeable */      if (access(cptSaveDir, F_OK | W_OK | X_OK) != 0) {         CPUWarning("CPT: Bad checkpoint save directory %s\n",cptSaveDir);         perror("CPT: Cannot write checkpoint");         CPUWarning("\n");         return;      }      /* Search for an unused checkpoint number */      for (num = 1; ; num++) {          sprintf(cptName, "CPT.%s.%03d", CheckpointID, num);         sprintf(pathname, "%s/%s.log", cptSaveDir, cptName);         if (access(pathname, F_OK) != 0)            break;      }      cptRemote = FALSE;   } else if (IS_REMOTE_CPT(name)) {      Simrmt_cptinit(name, cptName);      cptRemote = TRUE;   } else {      strcpy(cptName, name);      cptRemote = FALSE;   }   CPUWarning("CPT: %s checkpoint %s\n",               mode == CPT_SAVE ? "Saving" : "Restoring",              cptName);   if (mode == CPT_SAVE) {      while ((group = IterGroup(ITER_CPT)) != NULL) {         CheckpointFile(mode, group);      }      CPUWarning("CPT: End checkpoint save\n");   } else {      CheckpointFile(mode, FindGroup("log"));   } }intSimcpt_Restore(char *tag){   CptGroup *group = FindGroup(tag);   if (group != NULL) {      return CheckpointFile(CPT_RESTORE, group);   } else {     CPUWarning("CPT: Checkpoint file %s has not been restored\n", tag);     return -1;   }}voidSimcpt_Begin(CptDescriptor *cptd){   SIM_DEBUG(('g', "CPT: Simcpt_Begin %s\n", cptd->group->tag));   OpenCptFile(cptd->mode, cptd->group);}voidSimcpt_End(CptDescriptor *cptd){   CloseCptFile(cptd->group);   if (cptd->group->binfd > 0)      CloseBinFile(cptd->group);      SIM_DEBUG(('g', "CPT: Simcpt_End %s\n", cptd->group->tag));   if (cptd->mode == CPT_RESTORE) {      /* Verify that all data were used here and free the entries */      if (cptd->group->tail != NULL) {         CptEntry *entry = cptd->group->tail;         CptEntry *oldentry;         do {            if (!entry->optional) {               CPUWarning("CPT: Entry %s [%d,%d] in file %s not used\n",                          entry->name, entry->i1, entry->i2, cptd->group->tag);            }            oldentry = entry;            entry = oldentry->next;            FreeEntry(oldentry);         } while (entry != cptd->group->tail);         cptd->group->tail = NULL;      }            SIM_DEBUG(('g', "CPT: Done restoring from checkpoint file %s\n",                  cptd->group->tag));   }}  static CptGroup *NewGroup(char *tag) {   CptGroup *group = FindGroup(tag);   if (group != NULL) {      return group;   } else if (cptNumGroups == MAX_GROUPS) {      CPUWarning("CPT: Too many cpt groups -- creation of group %s failed\n",                  tag);      return NULL;   } else {      group = cptGroup + cptNumGroups++;      group->tag = SaveString(tag);      group->binfd = -1;      return group;   }}static CptGroup *FindGroup(char *tag) {   int g;   CptGroup *group = cptGroup;   for (g = 0; g < cptNumGroups; g++, group++) {      if (!strcmp(group->tag, tag))         return group;   }   return NULL;}static CptGroup *IterGroup(CptIter num){   static int currentGroup[NUM_ITERS];   if (currentGroup[num] == cptNumGroups) {      currentGroup[num] = 0;      return NULL;   } else {      return cptGroup + currentGroup[num]++;   }}static CptEntry *NewEntry(char *name, int i1, int i2, CptType type){   CptEntry *entry = (CptEntry *) MALLOC(sizeof(CptEntry), name);   entry->name = SaveString(name);   entry->i1 = i1;   entry->i2 =i2;   entry->type = type;   entry->optional = FALSE;   return entry;}static voidAddEntry(CptGroup *group, CptEntry *entry)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -