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

📄 checkpoint.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
{   /* Keep list in order of insertion */   if (group->tail == NULL) {      group->tail = group->hint = entry->prev = entry->next = entry;   } else {      entry->prev = group->tail;      entry->next = group->tail->next;      group->tail->next->prev = entry;      group->tail->next = entry;      group->tail = entry;   }}static voidFreeEntry(CptEntry *entry){   free(entry->name);   free(entry);}/* Finds entry in list, and removes it if found before returning it *//* If the entry found is optional, keep looking to see if a value loaded   from the checkpoint file is also present in the list */static CptEntry *FindEntryInList(CptGroup *group, char *name, int i1, int i2){  if (group->tail == NULL) {     return NULL;  } else {    CptEntry *entry = group->hint;    CptEntry *optentry = NULL;    /* Circularly linked list; start at the hint pointer and make one pass through */    do {      if (!strcmp(entry->name,name) && (entry->i1 == i1) && (entry->i2 == i2)) {         if (entry->prev == entry) {            group->tail = NULL;         } else {            group->hint = entry->next;            entry->prev->next = entry->next;            entry->next->prev = entry->prev;            if (group->tail == entry)               group->tail = entry->prev;         }        if (entry->optional)           /* If this entry is optional, keep looking for an entry from the file */           optentry = entry;        else           /* Otherwise, go ahead and return this entry */           return entry;      }      entry = entry->next;    } while (entry != group->hint);    /* If we get here, no non-optional entry was found. */    return optentry;  }}static intLogCheckpointCB(CptDescriptor *cptd){   if (cptd->mode == CPT_SAVE) {      CptGroup *group;      int g = 0;      while ((group = IterGroup(ITER_LOG)) != NULL) {         SaveLine(cptd->group, "CheckpointFile", g, NO_INDEX, group->tag);         g++;      }   }   return 0;}static voidSaveLine(CptGroup *group, char *name, int i1, int i2, char *valstring){   if (group->stream == NULL) {      CPUPrint("CPT: Checkpoint file %s not opened for writing\n",group->tag);      return;   }   if (i1 == NO_INDEX) {      fprintf(group->stream, lineFormat[0], name, valstring);   } else if (i2 == NO_INDEX) {      fprintf(group->stream, lineFormat[1], name, i1, valstring);   } else {      fprintf(group->stream, lineFormat[2], name, i1, i2, valstring);   }   fprintf(group->stream, "\n");}static intRestoreLine(CptGroup *group, char *name, int *i1, int *i2, char *valstring){   char line[MAX_LENGTH];   int status = 0;   if (group->stream == NULL) {      CPUPrint("CPT: Checkpoint file %s not opened for reading\n",group->tag);      return -2;   }   do status = GetLineFromFile(group->stream, line, MAX_LENGTH);   while ((status > 0) && (line[0] == '#')); /* Ignore comment lines */   ASSERT( strlen(line)< MAX_LENGTH);   if (status > 0) {      if (sscanf(line, lineFormat[2], name, i1, i2, valstring) == 4) {         /* Nothing to do -- all arguments in place */      } else if (sscanf(line, lineFormat[1], name, i1, valstring) == 3) {         *i2 = NO_INDEX;      } else if (sscanf(line, lineFormat[0], name, valstring) == 2) {         *i1 = NO_INDEX;         *i2 = NO_INDEX;      } else {         status = -2;      }   }   return status;}static voidSaveBlock(CptGroup *group, caddr_t addr, int size){   if (group->binfd < 0) {      OpenBinFile(CPT_SAVE, group);   }   write(group->binfd, addr, size);   group->binpos += size;}static intRestoreBlock(CptGroup *group, caddr_t addr, int pos, int size){   int cnt;   if (group->binfd < 0) {      OpenBinFile(CPT_RESTORE, group);   }   if(outputFD >= 0) {      pid_t retPid;      int   waitState;      CPUPrint("CPT: Waiting for death of child\n");      while (1) {         retPid = wait(&waitState);         if (retPid != compressPID) {            continue;         }         if (WIFSTOPPED(waitState)) {            CPUWarning("CPT: decompress process stopped by signal %d\nWaiting...\n",                       WSTOPSIG(waitState));            continue;         }         if (WIFEXITED(waitState) && (WEXITSTATUS(waitState)==0)) {            break;         }         CPUWarning("CPT: Decompress of checkpoint file failed\n");         if (WIFEXITED(waitState)) {            CPUWarning("CPT: Exit status of %d\n", WEXITSTATUS(waitState));         } else {            CPUWarning("CPT: Terminate by signal %d\n", WTERMSIG(waitState));         }          group->failure = TRUE;         return -1;      }      CloseBinFile(group);      return 0;   }   if (group->binpos != pos) {      /* Test for group->failure so this message is only given once */      if (!group->failure) {         CPUWarning("CPT: The binary file for %s was restored out of order\n",                     group->tag);         group->failure = TRUE;         return -1;      }   }   while (size > 0) {      cnt = read(group->binfd, addr, size);      if (cnt <= 0) {         /* Test for group->failure so this message is only given once */         if (!group->failure) {            perror("CPT: RestoreBlock");            CPUWarning("CPT: Error in reading the binary file for %s addr=%llx size=%llx \n",                        group->tag, (uint64)addr, (uint64)size);         }         group->failure = TRUE;         return -1;      }      group->binpos += cnt;      addr += cnt;      size -= cnt;   }   return 0;}/* Read checkpoint file, searching for the given entry and returning its value.   Any intervening values are placed on the entry list for the group */static CptEntry *FindEntryInFile(CptGroup *group, char *name, int i1, int i2){   while (TRUE) {      char fname[MAX_LENGTH];      char fvalstr[MAX_LENGTH];      int fi1, fi2;      int status = RestoreLine(group, fname, &fi1, &fi2, fvalstr);      if (status <= 0)         return NULL;      else {         CptEntry *entry;         cptlong ival;         cptlong pval;         char buf[MAX_LENGTH];         if (ParseInteger(fvalstr, &ival)) {            entry = NewEntry(fname, fi1, fi2, CPT_INTEGER);            entry->intval = ival;         } else if (ParseBlock(fvalstr, &pval, &ival)) {            entry = NewEntry(fname, fi1, fi2, CPT_BLOCK);            entry->ptrval = pval;            entry->intval = ival;         } else if (ParseString(fvalstr, buf)) {            ASSERT( strlen(buf) < MAX_LENGTH);            entry = NewEntry(fname, fi1, fi2, CPT_STRING);            entry->ptrval = (int64) PTR_TO_UINT64(SaveString(buf));         } else {            CPUWarning("CPT: Could not parse value %s\n", fvalstr);            continue;         }         if (!strcmp(name, fname) && (i1 == fi1) && (i2 == fi2)) {            /* Check to see if the entry is also resident in the in-memory list */            CptEntry *listEntry = FindEntryInList(group, name, i1, i2);            if (listEntry != NULL) {              if (listEntry->optional == FALSE)                CPUWarning("CPT: Entry %s [%d,%d] appears multiple times in file\n",name,i1,i2);            }            return entry;         } else            AddEntry(group, entry);      }   }   return NULL;}static FILE *OpenCompressedFile(CptMode mode, CptCompression c, FILE *fp){   int pfd[2];   int ffd = fileno(fp);      if (pipe(pfd) < 0) {      perror("pipe");      CPUWarning("CPT: Cannot create pipe to compress file.\n");   }   compressPID = fork();   if (compressPID == (pid_t) -1) {      perror("fork");      CPUWarning("CPT: Cannot fork compress process.\n");   } else if (compressPID == 0) {           /* Child process */      if (mode == CPT_SAVE) {         SIM_DEBUG(('g', "CPT: Using %s to compress file\n",                    compression[c].compress));         close(pfd[1]);         dup2(pfd[0], 0);         dup2(ffd, 1);         execlp(compression[c].compress, compression[c].compress, (char *) 0);      } else {         SIM_DEBUG(('g', "CPT: Using %s to decompress file\n"                    ,compression[c].decompress));         close(pfd[0]);         if (outputFD >= 0) {             dup2(outputFD, 1);         } else {             dup2(pfd[1], 1);         }         dup2(ffd, 0);         execlp(compression[c].decompress, compression[c].decompress,                 (char *) 0);      }      /* Should not return */      CPUError("execlp of compress/decompress returned\n");   } else {                    /* Parent process */      if (mode == CPT_SAVE) {         close(pfd[0]);         return fdopen(pfd[1], "w");      } else {         close(pfd[1]);         return fdopen(pfd[0], "r");      }   }   return NULL;}static CptCompressionGetCompression(char *filename, char *pathname){  CptCompression c;  for (c = NO_COMPRESSION; c < NUM_COMPRESS_TYPES; c++) {    bool found;    if (cptRemote) {      sprintf(pathname, "%s%s", filename, compression[c].extender);      found = Simrmt_access(pathname);    } else {       sprintf(pathname, "%s%s", filename, compression[c].extender);       found = (access(pathname, R_OK) == 0);    }    if (found)      break;  }  return c;}static FILE *OpenFile(CptMode mode, char *filename, CptCompression compress) {   FILE *fp;   char pathname[MAX_PATH_LENGTH];   if (mode == CPT_RESTORE) {     compress = GetCompression(filename, pathname);     if (compress == NUM_COMPRESS_TYPES) {         CPUError("Could not find checkpoint file %s -- "                  "all known extensions tried\n", filename);         return NULL;      }      if (cptRemote) {         CPUPrint("CPT: Reading %s from remote access server\n", pathname);         fp = Simrmt_fopen(pathname);      } else {         SIM_DEBUG(('g', "CPT: Reading from file %s....\n", pathname));         fp = fopen(pathname, "r");      }   } else {      if (cptRemote) {         CPUWarning("CPT: Not allowed to write checkpoint to remote access server\n");         return NULL;      } else {         sprintf(pathname, "%s/%s%s", cptSaveDir, filename,                 compression[compress].extender);         fp = fopen(pathname, "w");         SIM_DEBUG(('g', "CPT: Writing to file %s....\n", pathname));      }   }   if (fp == NULL) {      CPUWarning("CPT: Couldn't open checkpoint file %s.\n", filename);      return fp;   } else if ((compress == NO_COMPRESSION) && (outputFD < 0)) {      return fp;   } else {      FILE *cfp = OpenCompressedFile(mode, compress, fp);      fclose(fp);      return cfp;   }}static voidOpenBinFile(CptMode mode, CptGroup *group){   char filename[MAX_PATH_LENGTH];   /* Do not open if file is already open -- this is necessary to make      Simcpt_CheckpointRmtDisk work on the rmtaccess servers */   if (group->binfd >= 0) return;   sprintf(filename, "%s.%s.bin", cptName, group->tag);   group->binfd = fileno(OpenFile(mode, filename, group->compressBin[mode]));   group->binpos = 0;}static voidOpenCptFile(CptMode mode, CptGroup *group){   char filename[MAX_PATH_LENGTH];   int length;   /* Do not open if file is already open -- this is necessary to make      Simcpt_CheckpointRmtDisk work on the rmtaccess servers */   if (group->stream != NULL) return;   /* Strip the ending period off of the checkpoint name if it's there. */   length = strlen(cptName);   if (cptName[length-1] == '.') {      cptName[length-1] = '\000';   }   sprintf(filename, "%s.%s", cptName, group->tag);   group->stream = OpenFile(mode, filename, group->compressCpt[mode]);}static voidCloseBinFile(CptGroup *group){   close(group->binfd);   group->binfd = -1;   group->binpos = 0;}static voidCloseCptFile(CptGroup *group)

⌨️ 快捷键说明

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