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

📄 simutil.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * 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.  * *//***************************************************************** * simutil.c * * Random generic utilities * * $Author: bosch $ * $Date: 1998/02/10 00:28:42 $ ****************************************************************/#include <errno.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/mman.h>#include <sys/time.h>#include <unistd.h>#include <ctype.h>#include "syslimits.h"#include "sim_error.h"#include "machine_params.h"#include "simutil.h"#include "cpu_interface.h"char *simName[NUM_CPU_TYPES] = SIM_NAME_INIT;/***************************************************************** * GetLineFromFile -- * Read a line from the specified file into a buffer. * * Results: * The length of the line in characters: -1 on error, 0 on end of file. * *****************************************************************/intGetLineFromFile(FILE *f, char *buffer, int bufsize){        int i;    int n;     for (i = 0; i < bufsize-1; i++) {       n = fgetc(f);       if (n == EOF) {          if (i != 0) break;          return 0;       }       buffer[i] = n;       if (n == '\n') break;    }    if (i== bufsize-1) {        CPUError("GetLineFromFile: buffer too small \n");    }    buffer[i] = '\000';    return i+1;}/* ********************************************************************* * Numerical functions  * *********************************************************************/int GetLog2(int x){   int i;   int r=0;   for(i=1;i<x;i*=2)      r++;   if( i !=  x ) {       CPUError("Warning: GetLog2(%i) is undefined \n",x);   }   return r;}SimTime NanoSecsToCycles(SimTime time){   int clock = CPU_CLOCK;   SimTime retval;   if (!clock) {       CPUError("NanoSecsToCycles: CpuClock must have a non-zero value\n");   }    retval =  time /*nano*/ * clock /* Mhz */ / 1000;   return retval;}SimTime CyclesToNanoSecs(SimTime cycles){   int clock = CPU_CLOCK;   SimTime retval;   ASSERT(clock != 0);   retval =  (cycles / clock) * 1000;   return retval;}void SaveTimeDelay(TimeDelay *t,SimTime delay){   if( !delay ) {       t->count++;      t->zerocount++;   } else {       if( t->count==t->zerocount ) {          t->min = delay;         t->max = delay;       } else {         if( t->min > delay ) t->min = delay;         if( t->max < delay ) t->max = delay;      }      t->count++;      t->total += delay;      t->total2 += (uint64) delay*(uint64) delay;   }}void PrintTimeDelay(FILE *f,char *s,TimeDelay *t){   char out[128];   SubstituteLLx(out, "%s=(%lld,%lld,%lld,%lld,%lld,%lld) ", 128);   fprintf(f,out,           s,           (uint64)t->count,           (uint64)t->min,           (uint64)t->max,           (uint64)t->total,           (uint64)t->total2,           (uint64)t->zerocount);}/* ******************************************************************** * MallocShared can only be called before the processes are forked. It is  * called by the original process to allocated shared backdoor space.  * **********************************************************************/void *MallocShared(unsigned size,  char *name){    int pagesize = getpagesize();    char *retval, *start;    int num_pages, zfd;    num_pages = (size+pagesize-1)/pagesize;    retval = MemAlign(pagesize, num_pages*pagesize);    if (retval == NULL) {        CPUError("MallocShared: Out of shared space\n");    }    zfd = open("/dev/zero",O_RDWR,0);        start = (char *) mmap((void *)retval,num_pages*pagesize,                           PROT_READ|PROT_WRITE,                          MAP_SHARED|MAP_FIXED, zfd, 0);    if (start != retval) {        CPUError("Mallocshared: mmap failed\n");    }    close(zfd);    return retval;}char *SaveString(char *name) {    char *retval;        retval = (char *) ckalloc(strlen(name) + 1);    if (retval == NULL) {      CPUError("Couldn't malloc space in SaveString\n");    }    strcpy(retval, name);    return retval;}void *MemAlign(int alignment, int size){#ifdef __alpha   void *ptr = malloc(alignment + size);   uint64 x = PTR_TO_UINT64(ptr);   x = x + (alignment -1);   x = (x/alignment) * alignment;   return UINT64_TO_PTR(x);#else    return memalign(alignment,size);#endif}/*************************** * file name manipulation **************************/char *StripPath(char *string){   char *p;   char *ret = string;      for (p=string; *p; p++) {      if (*p == '/') {         ret = p + 1;      }   }   return ret;}#ifdef __alphavoid SubstituteLLx(char *out, const char *text, int maxlen){   char *ptr = (char *)text;   char *optr = out;   char *tok;   int len;   while ((ptr != NULL) && ((ptr - text) < maxlen)) {     tok = strstr(ptr, "ll");     if (tok == NULL) {       /* no more lls */       strcpy(optr, ptr);       return;     }     len = tok - ptr;     strncpy(optr, ptr, len);     ptr = tok;     optr += len;     if (tok != text) {       /* have to discount a starting ll */       tok--;       while ((*tok != '%') && (tok != text)) {         if (((*tok >= '0') && (*tok <= '9'))             || (*tok == '.') || (*tok == '+')             || (*tok == '-')) {           /* acceptable token */           tok--;         } else {           break;         }       }     }     ptr += 2;     if ((*tok == '%') &&         ((*ptr   == 'd') || (*ptr == 'x')            || (*ptr == 'u') || (*ptr=='i'))) {         /* make the substitution */         *optr = 'l';         optr++;     } else {       *optr = 'l';       optr++;       *optr = 'l';       optr++;     }   }} #elsevoid SubstituteLLx(char *out, const char *text, int maxlen){   int i;   for(i=0;i<maxlen &&text[i];i++) {      out[i] = text[i];   }   out[i] = text[i];}#endif/* * belong in simutil.c */int PrintLLD(char *string,int64 val){#ifdef __alpha   return sprintf(string,"%ld",(long)val);#else   return sprintf(string,"%lld",val);#endif} int PrintLLU(char *string,uint64 val){#ifdef __alpha   return sprintf(string,"%lu",(long)val);#else   return sprintf(string,"%llu",val);#endif}     int PrintLLX(char *string, int64 val){#ifdef __alpha   return sprintf(string,"0x%lx",(long)val);#else   return sprintf(string,"0x%llx",val);#endif}   /***************************************************************** * Print the current real-life time. This can be used for timing * simulation events. It will simply print out seconds since 1970 in * the log.  *****************************************************************/void PrintRealTime(char *string) {    struct timeval t;    gettimeofday(&t, (struct timezone*)0);     CPUPrint("%s: %ld s %ld us\n", string, t.tv_sec, t.tv_usec);}int OpenTmpFile(char * name){   extern char *MemFileDir;   int fd;   char nameBuf[256];      sprintf(nameBuf, "%s/.%s_XXXXXX",           MemFileDir,name);   mktemp(nameBuf);   if((fd =  open(nameBuf, O_RDWR|O_CREAT|O_TRUNC , 0)) == -1) {      CPUError("Could not open shadow file %s\n", nameBuf);      return -1;   }      unlink(nameBuf);   CPUPrint("OpenTmpFile %s \n",nameBuf);   return fd;}/* *************************************************************************** * AllocZeroMem & InitZeroMem *  * This is called by ZALLOC_PERM in the case where we want to map /dev/zero * to allocate initialized storememory without having to allocate the backing * store.  * ***************************************************************************/#define SIMUTIL_ALLOC_UNIT (512*1024)static struct {   /*     * parameters set by InitZeroMem     */   char *startAddr;   char *endAddr;   int   redzone;      char *cur;   char *nextPageAddrToAlloc;   int   zfd;} zeroMem;void InitZeroMem(char * start,char * end, int redzone){   int pageSzLessOne = getpagesize()-1;   zeroMem.startAddr  = start;   zeroMem.endAddr    = (char *) UINT64_TO_PTR((PTR_TO_UINT64(end) + pageSzLessOne) & ~pageSzLessOne);   zeroMem.redzone    = redzone;   zeroMem.cur        = (char *)0;}void *AllocZeroMem(int memSize, char *name)  {   int len, flags;   char *memPtr, *memEndPtr;   long offset = 0;#ifdef SIMOS_PURE   /*    * Should never be called in this case    */   CPUError("Cannot use AllocZeroMem with SIMOS_PURE defined! \n");#endif#ifdef __alpha_not   if (memSize > 1024 *1024) {      /*       * gross hack. Assume that this will be clean (zero) memory       */      memPtr = malloc(memSize);      if (!memPtr) {         perror("AllocZeroMem::malloc");         CPUError("AllocZeroMem (malloc) of %lld bytes failed \n",memSize);      }      return memPtr;   }#endif    /* Initialization needed ? */   if (!zeroMem.cur) {       int pageSize = getpagesize()-1;      ASSERT (zeroMem.startAddr);      zeroMem.cur = zeroMem.startAddr;      zeroMem.nextPageAddrToAlloc = zeroMem.startAddr;#ifdef __alpha      zeroMem.zfd = -1;      /* zeroMem.zfd = OpenTmpFile("zeromem"); */#else      zeroMem.zfd = open("/dev/zero", O_RDWR, 0);      if (zeroMem.zfd <= 0) {         CPUWarning("opening /dev/zero in AlloczeroMem failed");         ASSERT(0);      }#endif      /*        * redzone the end of the mappable region. This is        * to prevent the stack to grow below the end of the       * mappable region.        * Note that this only has an effect if the allocator       * is used. Hence the delay.       */      if (zeroMem.redzone) {         if( mmap( (void*)zeroMem.endAddr, pageSize,                   PROT_NONE ,MAP_PRIVATE|MAP_FIXED,                   zeroMem.zfd,0) != (void*)zeroMem.endAddr){            perror("Redzoning Stack Failed");            ASSERT (0);         }      }   }   memPtr = zeroMem.cur;   memEndPtr = memPtr + memSize - 1;    CPUPrint("ZeroMem: %-20s 0x%x - 0x%x size=%8d\n",name,memPtr,memEndPtr,memSize);   if (memEndPtr > zeroMem.endAddr) {      CPUError("ZeroMem overflow. Move the memory file down \n ");   }   if (memEndPtr < zeroMem.nextPageAddrToAlloc) {      zeroMem.cur = memPtr + memSize;      return (void*)memPtr;   }   /* allocate next chunk */   for (len = 0; len < memSize; len +=SIMUTIL_ALLOC_UNIT)      continue;   if (zeroMem.nextPageAddrToAlloc+ len >= zeroMem.endAddr) {      len = zeroMem.endAddr - zeroMem.nextPageAddrToAlloc;   }   flags =  MAP_PRIVATE|MAP_FIXED;#ifdef sgi   flags |= MAP_AUTORESRV;  /* Improve startup time on sgi. */#endif#ifdef __alpha   if (zeroMem.zfd >0) {      long checkOffset;      char foobar[2];      flags &= ~MAP_PRIVATE;      flags |= MAP_FILE|MAP_SHARED;      offset = zeroMem.nextPageAddrToAlloc - zeroMem.startAddr;      checkOffset = lseek(zeroMem.zfd,zeroMem.nextPageAddrToAlloc - zeroMem.startAddr + len,SEEK_SET);      ASSERT( checkOffset == zeroMem.nextPageAddrToAlloc - zeroMem.startAddr + len);      foobar[0] = '\0';      write(zeroMem.zfd,foobar,1);   } else {      flags |= MAP_ANONYMOUS;   }#endif   if (mmap(zeroMem.nextPageAddrToAlloc, len,             PROT_READ|PROT_WRITE, flags,            zeroMem.zfd, offset)  != zeroMem.nextPageAddrToAlloc) {       perror("AllocZeroMem");      CPUError("Can't allocate memory in AlloczeroMem addr=0x%llx len=0x%llx\n ",               zeroMem.nextPageAddrToAlloc,                len);   } else {         CPUPrint("zeroMem: Mapping /dev/zero at 0x%llx for %ld KB fd=%d offset=%d \n",                  zeroMem.nextPageAddrToAlloc,                  len / 1024, zeroMem.zfd, offset);         *(char *) zeroMem.nextPageAddrToAlloc = '\0';    }     zeroMem.nextPageAddrToAlloc += len;   zeroMem.cur = memPtr + memSize;   return (void*)memPtr;}voidtoLowerStr(char *dest, char *src){   int	len;   int	i;      len = strlen(src);      for (i = 0; i <= len; i++)      dest[i] = tolower(src[i]);}voidtoUpperStr(char *dest, char *src){   int	len;   int	i;      len = strlen(src);      for (i = 0; i <= len; i++)      dest[i] = toupper(src[i]);}uint64 EndianSwapDouble(uint64 x){   uint64 val64 = x;   char  *ptr = (char *) &val64;   char out[8];   int i;   for (i=0;i<8;i++) {       out[i] = ptr[7-i];   }   return (uint64) *(uint64 *)out;}#ifdef for_some_platforms_onlyintgetpagesize(void) {  return (int)sysconf (_SC_PAGESIZE);} /* getpagesize () */#endif/****************************************************************************//* zero-filled file operations *//* * Create a file in the specified directory, of the specified length containing * all zeros, and optionally unlink the file. */intMakeFile(char *directoryname, char *filename, int length, int unlinkit){      int fd;   static char namebuf[1024];   static int nextid = 0;      if (filename == NULL) {       sprintf(namebuf, "%s/%d.%d.%d", directoryname, (int)getpid(), (int)time(0), nextid++);      filename = namebuf;   }   /*    * Create the file, we set the permissions so only the owner can access    * it. This is necessary due to a bug in NFS that prohibits    * ftruncates() on files that the user doesn't have write perimission    * on.    */      fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0700);   if (fd < 0) {      perror( filename);      return -1;   }      /*    * Remove the directory entry. This means that when we exit or crash    * the file is deleted.    */   if (unlinkit && (unlink(filename) < 0)) {      perror( filename);      /* Let this error pass. */   }   if (length > 0) {       /*       * Grow the file to the specified size.       */      if (lseek(fd, (int)length-1, SEEK_SET) != (int)(length-1)) {     perror( filename);     (void) close(fd);     return -1;      }      if (write(fd, "\000", 1) != 1) {     perror( filename);     (void) close(fd);     return -1;      }       }      return fd;}

⌨️ 快捷键说明

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