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

📄 memstat.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
         if (interest(pAddr)) {              CPUWarning("%10lld L1 Ref cpu=%i pAddr=%08x type=%#x state=%#x\n",                       CPUVec.CycleCount(cpuNum), cpuNum, pAddr, missType,                        MSCacheState(cpuNum, pAddr));         }#endif      }      return -1;   }    if ((missType & E_L2) && (missType & E_UPGRADE)) {      if (memStat.init &&           NO_RACE_CONDITION &&           MSCacheState(cpuNum,pAddr) != CACHE_INCACHE) {         CPUError("MemStat: %10lld  cpu=%i pAddr=0x%08x UPGRADE NOT IN CACHE \n",                  CPUVec.CycleCount(cpuNum), cpuNum, pAddr);      }      STAT_RECORD(dUpgrade,1);      STAT_RECORD(dUpgradeStall, stallTime);      if (!(missType & E_CAUSED_INVAL)) {         STAT_RECORD(dUpgradeNoInval,1);      }      if (missType & E_SC_UPGRADE) {          STAT_RECORD(dUpgradeSC, 1);      }      if (missType & E_REMOTE) {         STAT_RECORD_I(dL2RemoteMiss,1);         STAT_RECORD_I(dL2RemoteStall,stallTime);      }#ifdef DEBUGGING      if (interest(pAddr)) {          CPUWarning("%10lld L2-upgrade cpu=%i pAddr=%08x type=%#x state=%#x\n",                    CPUVec.CycleCount(cpuNum), cpuNum, pAddr, missType,                     MSCacheState(cpuNum, pAddr));      }#endif      return -1;   }        /* L2 cache Miss */   ASSERT(missType & E_L2);   STAT_RECORD(dL2Miss, 1);   STAT_RECORD(dL2Stall, stallTime);   if (missType & E_FOUND_IN_CACHE) {      STAT_RECORD(dL2DirtyMiss,1);      STAT_RECORD(dL2DirtyStall,stallTime);         }   if (missType & E_REMOTE) {      STAT_RECORD_I(dL2RemoteMiss,1);      STAT_RECORD_I(dL2RemoteStall,stallTime);   }   if (memStat.trackL1) {      /*       * clear the capacity bits in the L1 cache        */      for(i=0; i<SCACHE_LINE_SIZE; i+= DCACHE_LINE_SIZE) {         uint L1pA = (pAddr & ~(SCACHE_LINE_SIZE-1)) + i;         int l1Line = mcpu * MEM_L1D_LINE(MEM_SIZE(machine)) +             MEM_L1D_LINE(L1pA);          int l1Index = l1Line /32;         int l1Pos   = l1Line %32;          memStat.l1DtrPtr[machine][l1Index] &=  ~(1<<l1Pos);      }   }   if (!memStat.init) return -1;   ASSERT(categ >= 0);   if (interest(pAddr)) {      CPUWarning("%10lld CacheTrmiss : %i\n",CPUVec.CycleCount(cpuNum),categ);   }   if (missType & E_WRITE) {      StatRecordEntry(cpuNum, pc, vAddr, memStatBucket.write[categ], 1);   } else  {       StatRecordEntry(cpuNum, pc, vAddr, memStatBucket.read[categ], 1);   }   return missType;}void  MemStatCacheTrans(int cpuNum, PA pAddr, int type, VA evictorAddr, int isUserMode){   unsigned int index,pos,state,off;   int machine;   int mcpu;   if (!memStat.init) return;   machine = M_FROM_CPU(cpuNum);   mcpu = MCPU_FROM_CPU(cpuNum);   /* debug */   if (interest(pAddr)) {      char c[5];      c[0] = 't';      if ((type & E_L1) && (type & E_I)) {          c[1] = 'i';      }      else if ((type & E_L1) && (type & E_D)) {          c[1] = 'd';      }      else if (type & E_L2) {         c[1] = '2';      }      else          ASSERT(0);            if ((!(type & E_EXTERNAL)) && (!(type & E_FAKE_EXTERNAL))) {         /* Line was replaced */         c[2] = 'r';      }      else if (type & E_EXTERNAL) {          c[2] = 'X';      }      else if (type & E_FAKE_EXTERNAL) {          c[2] = 'F';      }      else          ASSERT(0);            if (type & E_WRITEBACK) {          c[3] = 'W';      }      else if (type & E_FLUSH_CLEAN) {          c[3] = 'C';      }      else if (type & E_DOWNGRADE) {          c[3] = 'D';      }      else          c[3]='X';      c[4] = '\0';      ITRACE(c);    }      /* for now we only measure transitions in the L2 cache  */      if (type & E_L1) return;   ASSERT (type & E_L2);      pAddr &= ~(SCACHE_LINE_SIZE-1);   ASSERT(pAddr < MEM_SIZE(machine));      pos = memStat.bitsPerState *( memStat.trNumCPUs[machine] *                                 MEM_LINE(pAddr) + mcpu);   off = pos % 32;   index = pos / 32;   ASSERT(index*4<memStat.lastAddr[machine]); /* range check */   /* get current state */   state = ( memStat.trPtr[machine][index] >> off ) & memStat.cacheMask;   /*    * REPLACEMENT:    * The line was in the cache and should be in the cache and is replaced.     */   if ((!(type & E_EXTERNAL)) && (!(type & E_FAKE_EXTERNAL))) {        /* evict your own line */      if (state != CACHE_INCACHE) {         /* you better be in the cache! */         if (NO_RACE_CONDITION) {            CPUError("MS 0x%08x %10lld MemStat: EVICT, cpu=%i state=%i type=%i\n",                     pAddr,CPUVec.CycleCount(cpuNum),cpuNum,state,type);         }         ++(memStat.trWarnings[machine]);      }      if (isUserMode) {         type |= E_USER_REPLACED;      } else {         type |= E_KERN_REPLACED;      }      ASSERT(type & (E_KERN_REPLACED|E_USER_REPLACED));      if (type & E_USER_REPLACED) {         uint newState;         if (memStat.pidTable[machine][MS_pid(cpuNum)] == -1) {             memStat.pidTable[machine][MS_pid(cpuNum)]                = memStat.pidCount[machine]++;            ASSERT(memStat.pidCount[machine] < MS_MAXPID);         }          if( memStat.trackPID ) {             newState = (memStat.pidTable[machine]                        [MS_pid(cpuNum)]<<PIDOFFSET)|CACHE_REPLACED_U;         } else {             newState = CACHE_REPLACED_U;         }         if (interest(pAddr)) {            LogEntry("newstate",cpuNum,"pAddr=%08x newstate=%i\n",                      pAddr,newState);         }         memStat.trPtr[machine][index] &= ~(memStat.cacheMask<<off);         memStat.trPtr[machine][index] |=(newState<<off);       } else {         if (interest(pAddr)) {             LogEntry("newstate",cpuNum,"pAddr=%08x newstate=%i\n",                      pAddr,CACHE_REPLACED_K);         }         memStat.trPtr[machine][index] &= ~(memStat.cacheMask<<off);         memStat.trPtr[machine][index] |= CACHE_REPLACED_K<<off;      }      return ;   }   if (type & E_DOWNGRADE) {      return;    /* no transition on a writeback */   }   if (type & E_EXTERNAL) {      ASSERT(type & (E_WRITEBACK | E_FLUSH_CLEAN));      /* you better be in the cache! */      if (state != CACHE_INCACHE) {         if (NO_RACE_CONDITION) {            CPUError("MemStat 0x%08x %10lld EXTERNAL cpuNum=%i state=%i type=%i\n",                     pAddr,(uint64)CPUVec.CycleCount(cpuNum),cpuNum,state,type);         }         ++(memStat.trWarnings[machine]);      }      state = CACHE_INVALIDATED;   }   if (type & E_FAKE_EXTERNAL) {      switch(state) {      case CACHE_REPLACED_K:         state = CACHE_REPL_INV;         break;      case CACHE_INCACHE:         if (NO_RACE_CONDITION) {            CPUError("MemStat %08x %10lld FAKE_EXTERNAL, cpuNum=%i\n",                     pAddr,CPUVec.CycleCount(cpuNum), cpuNum);         }         ++(memStat.trWarnings[machine]);         break;      case CACHE_COLD:         break;      default:         if ((state&0xf)==CACHE_REPLACED_U)            state=CACHE_REPL_INV;                 }   }   if (interest(pAddr)) {      LogEntry("newstate",cpuNum,"pAddr=%08x newstate=%i\n",               pAddr,state);   }   /* record new state */   memStat.trPtr[machine][index] &= ~(memStat.cacheMask<<off);   memStat.trPtr[machine][index] |= (state <<off);}void MemStatPrefetchNoMiss (int cpuNum, PA pAddr, int way) {   if (interest(pAddr)) {      LogEntry("prefetch",cpuNum,"pAddr=0x%x, way=%i \n",               pAddr,way);   }   if (memStat.init) {      int categ = CacheTrMiss(cpuNum,pAddr);      FalseSharingDefineOffset(cpuNum,pAddr,way,categ);   }} /***************************************************************** * CacheTrMiss *  * This is called when a line goes back into the cache * to maintain the correct state machine. *****************************************************************/static intCacheTrMiss(int cpuNum, PA pAddr){   int state,i;   unsigned int pos,index,off;   int retval = -1;   int machine;   int mcpu;   if (!memStat.init) return 0;   machine = M_FROM_CPU(cpuNum);   mcpu = MCPU_FROM_CPU(cpuNum);#ifdef DEBUGGING   if (interest(pAddr)) {       CPUWarning("%10lld trMiss\n",CPUVec.CycleCount(cpuNum));   }#endif   pAddr &=~(SCACHE_LINE_SIZE-1);   ASSERT( memStat.trPtr[machine] );   if (pAddr >= MEM_SIZE(machine)) {      CPUError("MemStat::CacheTrMiss. pAddr=0x%llx > MEM_SIZE=0x%llx\n",               (uint64)pAddr, (uint64)MEM_SIZE(machine));   }   pos = memStat.bitsPerState * (memStat.trNumCPUs[machine] *                                 MEM_LINE(pAddr) + mcpu);   off = pos% 32;   index = pos / 32;   ASSERT( index*4< memStat.lastAddr[machine] );   /* get old state */   state = (memStat.trPtr[machine][index] >> off ) & memStat.cacheMask;   switch( state ) {   case CACHE_COLD:        retval= CATEG_ice;      break;   case CACHE_REPLACED_K:      if (memStat.trackPID) {         retval = CATEG_Kcap;      } else {          retval = CATEG_cap;      }      break;   case CACHE_INVALIDATED:      retval = CATEG_inv;      break;   case CACHE_REPL_INV:      retval = CATEG_capinv;      break;   case CACHE_WARMED:       retval = CATEG_cold;      break;   case CACHE_INCACHE:      if( NO_RACE_CONDITION ) {         CPUError("%10lld MemStat CacheTrMiss, state=%i pAddr=%08x\n",                  CPUVec.CycleCount(cpuNum), state, pAddr);      }      ++(memStat.trWarnings[machine]);      break;   default:       ASSERT( (state&0xf)== CACHE_REPLACED_U );      if( memStat.trackPID) {         if (memStat.pidTable[machine][MS_pid(cpuNum)] == -1) {             memStat.pidTable[machine][MS_pid(cpuNum)]                = memStat.pidCount[machine]++;            ASSERT(memStat.pidCount[machine] < MS_MAXPID);         }            if (state>>PIDOFFSET == memStat.pidTable[machine][MS_pid(cpuNum)])            retval = CATEG_SelfCap;         else            retval = CATEG_OtherCap;        } else {         retval = CATEG_cap;      }   }   memStat.trPtr[machine][index] &= ~(memStat.cacheMask <<off);   memStat.trPtr[machine][index] |= CACHE_INCACHE<<off; /* it is back in the cache */      if (interest(pAddr)) {      LogEntry("newstate",cpuNum,"pAddr=%08x newstate=IN_CACHE\n",               pAddr);   }   if (state == CACHE_COLD) {      pos = memStat.bitsPerState * (memStat.trNumCPUs[machine] *                                    MEM_LINE(pAddr) );      off = pos % 32;      index = pos / 32;      for(i=0;i<memStat.trNumCPUs[machine];++i) {         if( i != mcpu ) {            memStat.trPtr[machine][index] &= ~(memStat.cacheMask <<off);            memStat.trPtr[machine][index] |= (CACHE_WARMED<<off);         }         off += memStat.bitsPerState;         if( off >= 32 ) {            off -=32;            index ++;         }        }   }   if (interest(pAddr)) {      ITRACE("Cache");   }   return retval;}int  MemStatInitialized(void){   return( memStat.init );}/***************************************************************************** * Support routines for MemStat ****************************************************************************/void MemStatLog(FILE *f,char *tag, SimTime time, char *desc, char *text,...){   va_list ap;   if (f) {       if (time) {         fprintf(f,"%-6s ",tag);         va_start(ap,text);         vfprintf(f,text,ap);         va_end(ap);         fprintf(f,"\n");      } else {         fprintf(f,"DEF %-6s %s\n",tag,desc);      }   } }/***************************************************************** * Very useful debugging procedures *****************************************************************/intinterest( PA pAddr ) {#ifdef DEBUGGING#define INTERESTING_LINE  0x67460d80#define SET_PROBLEM 1   if( (pAddr  & ~(SCACHE_LINE_SIZE-1))==        ( INTERESTING_LINE  &~(SCACHE_LINE_SIZE-1))  ) {      CPU_nop();      return 1;   }    if( SET_PROBLEM ) {       if( ((pAddr >> log2SCACHE_LINE_SIZE) & (SCACHE_INDEX-1))          == ((INTERESTING_LINE>>log2SCACHE_LINE_SIZE) & (SCACHE_INDEX-1)) ) {         CPU_nop();         return 1;      }   }#endif   return 0;} intMSCacheState(int cpu, PA pAddr) {   int pos, off, index;   int machine;   int mcpu;   if (!memStat.init) return -1;   machine = M_FROM_CPU(cpu);   mcpu = MCPU_FROM_CPU(cpu);   pos = memStat.bitsPerState *( memStat.trNumCPUs[machine] *                                 MEM_LINE(pAddr) + mcpu);   off = pos % 32;   index = pos / 32;   ASSERT(index*4<memStat.lastAddr[machine]); /* range check */   /* get current state */   return ( memStat.trPtr[machine][index] >> off ) & memStat.cacheMask;}

⌨️ 快捷键说明

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