📄 statrecord.c
字号:
ASSERT (statRecord.trashBucket); for (i=0;i<MAX_SWITCHES;i++) { statRecord.disableSnapshot->switches[i] = statRecord.trashBucket; } } statRecord.disableSnapshot->refCount++; return statRecord.disableSnapshot; } /* * Already set for that particular cpuNum */ if (statRecord.curSnapshot[cpuNum]) { snap = statRecord.curSnapshot[cpuNum]; snap->refCount++; return snap; } /* * Hash lookup (second chance) */ hash =0; for (i=0; i<statRecord.numDetails; i++) { hash = (hash<<4) + PTR_TO_UINT64(statRecord.cur[cpuNum].switches[i]); } hash += (hash<<4) + statRecord.cur[cpuNum].detailActive; hash = hash % SNAPSHOT_HASH; hashSnap = statRecord.hash[hash]; /* * Hash comparison */ if (hashSnap && (hashSnap->detailActive == statRecord.cur[cpuNum].detailActive)) { for (i=0; i<statRecord.numSwitches; i++) { if (hashSnap->switches[i] != statRecord.cur[cpuNum].switches[i]) { break; } } if (i == statRecord.numSwitches) { /* Finally, we have a match! */ hashSnap->refCount +=2; /* curSnapshot + returned */ statRecord.curSnapshot[cpuNum] = hashSnap; return hashSnap; } } /* * Keep reference count correcy */ if (hashSnap) { StatRecordFreeSnapshot(hashSnap); } /* * Allocate (or get from free pool) */ if (!List_IsEmpty(&statRecord.freeSnapshots)) { snap = (StatRecordSnapshot *) List_First(&statRecord.freeSnapshots); List_Remove((List_Links*)snap); } else { snap = (StatRecordSnapshot *)ZMALLOC(sizeof( StatRecordSnapshot),"StatRecord"); statRecord.snapshotAllocCount++; } bcopy((char*)&statRecord.cur[cpuNum],(char*)snap,sizeof( StatRecordSnapshot)); List_InitElement(((List_Links*)snap)); /* * return snap */ snap->refCount = 3; /* curSnapshot * hash entry * returned value */ statRecord.curSnapshot[cpuNum] = snap; statRecord.hash[hash] = snap; List_Insert((List_Links*)snap,&statRecord.listSnapshots); return snap;}void StatRecordFreeSnapshot( StatRecordSnapshot *snap){ ASSERT(snap); --snap->refCount; ASSERT( snap->refCount >= 0 ); if( snap->refCount == 0 ) { snap->refCount = -17; /* debug */ List_Remove((List_Links*)snap); List_Insert((List_Links*)snap,&statRecord.freeSnapshots); }}/* ********************************************************************* * StatRecordTransferBucket * called when a switch has changed to a new bucket and that the * contents of the previous transient bucket have been added to the * new switch. We want all snapshots that refer to that particular * bucket for that particular switch to be changed to a new switch. * ********************************************************************/static void StatRecordUpdateSnapshots(StatRecordSwitch *sw, StatRecordBucket *oldVal,StatRecordBucket *newVal) { int id = sw->id; List_Links *ptr; ASSERT(sw && oldVal && newVal); LIST_FORALL(&statRecord.listSnapshots,ptr) { StatRecordSnapshot *snap = (StatRecordSnapshot *)ptr; if( snap->switches[id]==oldVal) { snap->switches[id] = newVal; } }}void StatRecordTransferBucket(StatRecordSwitch *sw, StatRecordBucket *tmpBucket, StatRecordBucket *finalBucket){ ASSERT(sw && tmpBucket && finalBucket); StatRecordInc(finalBucket,tmpBucket); bzero((char*)tmpBucket,sizeof(StatRecordCounter)*statRecord.numFields); StatRecordUpdateSnapshots(sw,tmpBucket,finalBucket);}/**************************************************************** * StatRecordDisableCPU * ****************************************************************/void StatRecordDisableCPU(int cpuNum) { ASSERT (cpuNum>=0 && cpuNum < SIM_MAXCPUS); statRecord.disableCPU[cpuNum] = 1; CPUPrint("STATRECORD: Disable CPU %i \n",cpuNum);} /********************************************************************** * Incrementation routines **********************************************************************/void StatRecordEntry(int cpuNum, VA PC, VA vAddr, StatRecordFieldDesc field, int inc){ if (statRecord.disableCPU[cpuNum]) return; StatRecordIncrement(&statRecord.cur[cpuNum], PC, vAddr, field, inc);}voidStatRecordIncrement(StatRecordSnapshot *cur, VA PC, VA vAddr, StatRecordFieldDesc field, int inc){ int i; int index; ASSERT (field); index = field->index; ASSERT(index >= 0 && index < statRecord.numFields); ASSERT(cur); ASSERT(statRecord.initState == STATREC_EXEC ); /* Go through the switches */ for(i=0; i < statRecord.numSwitches; i++) { StatRecordCounter *ptr = (StatRecordCounter *)cur->switches[i]; ptr[index] += inc; } /* go through the detail */ for (i=0; i<statRecord.numDetails; i++) { void *bucketPtr = 0; int pos; if (!(cur->detailActive & (1<<i))) { continue; } if (statRecord.detailDesc[i].pos[index] < 0) { continue; } if (statRecord.detailDesc[i].isByPC) { ASSERT(PC); bucketPtr = SimRecBucketAddr(statRecord.detailDesc[i].table, PC); } else { ASSERT(vAddr); bucketPtr = SimRecBucketAddr(statRecord.detailDesc[i].table, vAddr); } pos = statRecord.detailDesc[i].pos[index]; ASSERT((pos >= 0) && (pos < statRecord.detailDesc[i].numCounters)); if (statRecord.detailDesc[i].counterSize == 4) { uint *ptr = (uint*)bucketPtr; ptr[ pos ] += inc; } if (statRecord.detailDesc[i].counterSize == 8) { uint64 *ptr = (uint64*)bucketPtr; ptr[ pos ] += inc; } }} /***************************************************************** * field names <-> field field desc ******************************************************************/StatRecordFieldDesc StatRecordDefineField(char *name, int flag){ int index; int i; ASSERT(statRecord.initState == STATREC_INIT); for (i=0; i<statRecord.numFields; i++) { if (!strcmp(statRecord.fieldDesc[i].fieldName, name)) { CPUError("StatRecordDefineField : '%s' redefined \n", name); } } index = statRecord.numFields++; ASSERT(index < MAX_FIELDS); ASSERT(!statRecord.fieldDesc[index].fieldName); statRecord.fieldDesc[index].index = index; statRecord.fieldDesc[index].fieldName = SaveString(name); statRecord.fieldDesc[index].fieldFlag = flag; return &(statRecord.fieldDesc[index]);} /*********************************************************************** * Utility functions: Operation of StatRecordBuckets! ***********************************************************************/void StatRecordDumpBucket(char *tag, StatRecordBucket *b, char *leader){ int i; StatRecordCounter *ptr = (StatRecordCounter *)b; char buf[32]; ASSERT( b); if( statRecord.initState == STATREC_INIT ) { statRecord.initState = STATREC_EXEC ; } SelectorCB(-1);#ifdef __alpha sprintf(buf, " %ld ",(uint64)CPUVec.CycleCount(CPUVec.CurrentCpuNum()));#else sprintf(buf, " %lld ",(uint64)CPUVec.CycleCount(CPUVec.CurrentCpuNum()));#endif Tcl_AppendResult(TCLInterp, leader, "SR_BUCKET ", tag, buf, NULL); for(i=0;i<statRecord.numFields;i++) {#ifdef __alpha sprintf(buf, "%ld ",(uint64)ptr[i]);#else sprintf(buf, "%lld ",(uint64)ptr[i]);#endif Tcl_AppendResult(TCLInterp, buf, NULL); } Tcl_AppendResult(TCLInterp, "\n", NULL);}void StatRecordDumpFields(void){ int i; if( statRecord.initState == STATREC_INIT ) { statRecord.initState = STATREC_EXEC ; } Tcl_AppendResult(TCLInterp, "SR_FIELDS bucketName time ", NULL); for(i=0;i<statRecord.numFields;i++) { Tcl_AppendResult(TCLInterp, statRecord.fieldDesc[i].fieldName, " ", NULL); } Tcl_AppendResult(TCLInterp, "\n", NULL);}/* Compute (binary) sum of memstate counters for one cpus */static void ComputeSingleSum( StatRecordCounter* s, StatRecordCounter* a, int size ){ int i; for(i=0;i<size;++i) { s[i] += a[i]; }}#define BUCKET_SIZE ( statRecord.numFields * sizeof(StatRecordCounter))void StatRecordCopy(StatRecordBucket *src,StatRecordBucket *dst){ ASSERT( dst && src ); bcopy((char*)src,(char*)dst,BUCKET_SIZE);}int64 StatRecordFieldValue(StatRecordBucket *b, char *field){ int i; ASSERT( b && field ); SelectorCB(-1); for(i=0;i<statRecord.numFields;i++) { if( !strcmp(field, statRecord.fieldDesc[i].fieldName)) { StatRecordCounter *ptr = (StatRecordCounter *)b; return (int64) ptr[i]; } }/* CPUError("StatRecordFieldValue '%s' not found\n",field); */ return -1; /* Changed to signal a field which doesn't exist */}int64 StatRecordFieldValueByIndex(StatRecordBucket *b, unsigned index) { StatRecordCounter *ptr = (StatRecordCounter *) b; ASSERT(index < statRecord.numFields); SelectorCB(-1); return (int64) ptr[index];}int StatRecordNumFields(void){ return statRecord.numFields;}int StatRecordDetailNumFields(StatRecordDetail *detail) { return detail->numFields;}char *StatRecordGetFieldName(unsigned index) { ASSERT(index < statRecord.numFields); return statRecord.fieldDesc[index].fieldName;}char *StatRecordDetailGetFieldName(StatRecordDetail *detail, unsigned index) { ASSERT(index < detail->numFields); return detail->fields[index];}void StatRecordInc(StatRecordBucket *a,StatRecordBucket *b){ ASSERT( a && b ); ComputeSingleSum((StatRecordCounter*)a, (StatRecordCounter*)b, statRecord.numFields);}void StatRecordComputeMin(StatRecordBucket *min, StatRecordBucket *a){ StatRecordCounter *cmin = (StatRecordCounter *)min; StatRecordCounter *ca = (StatRecordCounter *)a; int i; ASSERT( a && min ); for(i=0;i<statRecord.numFields;i++) { if( cmin[i] > ca[i] ) { cmin[i] = ca[i]; } }}void StatRecordComputeMax(StatRecordBucket *max, StatRecordBucket *a){ StatRecordCounter *cmax = (StatRecordCounter *)max; StatRecordCounter *ca = (StatRecordCounter *)a; int i; ASSERT( a && max ); for(i=0;i<statRecord.numFields;i++) { if( cmax[i] < ca[i] ) { cmax[i] = ca[i]; } }}void StatRecordZero(StatRecordBucket *b) { ASSERT( b ); bzero((char*)b,statRecord.numFields*sizeof(StatRecordCounter));}StatRecordBucket *StatRecordNewBucket(void){ if (statRecord.initState == STATREC_INIT) { statRecord.initState = STATREC_EXEC; } ASSERT(statRecord.numFields); return (StatRecordBucket *)ZMALLOC(statRecord.numFields * sizeof(StatRecordCounter),"StatRecord");}voidStatRecordFreeBucket(StatRecordBucket *bucket){ ASSERT(bucket); free(bucket);}int StatRecordBucketSize(void){ return statRecord.numFields * sizeof(StatRecordCounter);}static void SelectorCB(int cpuNum) { if (!CPUVec.CycleCount) return; if (cpuNum < 0) { for(cpuNum=0; cpuNum<TOTAL_CPUS; cpuNum++) { if (statRecord.lastChange[cpuNum] < CPUVec.CycleCount(cpuNum)) { if (CPUVec.SelectorChange) CPUVec.SelectorChange(cpuNum); statRecord.lastChange[cpuNum] = CPUVec.CycleCount(cpuNum); } } } else { if (statRecord.lastChange[cpuNum] < CPUVec.CycleCount(cpuNum)) { if (CPUVec.SelectorChange) CPUVec.SelectorChange(cpuNum); statRecord.lastChange[cpuNum] = CPUVec.CycleCount(cpuNum); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -