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

📄 clock.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
          count++;          ASSERT( count < MAX_INTERRUPT_CALLBACKS  );          clockState->rotor = (clockState->rotor+1)% MAX_INTERRUPT_CALLBACKS;       }       event = &clockState->interrupts[ clockState->rotor];       EventDoCallback(cpuNum,EmbraInterruptCallback,event,(void *)(int)intrtoset,delay);    }}void Embra_Deliver_SIPS( int cpuNum, int chan, SimTime delay ){        int count = 0;    EventCallbackHdr *event;    clockState->rotor = (clockState->rotor+1)%MAX_INTERRUPT_CALLBACKS;    while( EventCallbackActive(&clockState->interrupts[clockState->rotor]) ){        count++;        ASSERT( count < MAX_INTERRUPT_CALLBACKS  );        clockState->rotor = (clockState->rotor+1)% MAX_INTERRUPT_CALLBACKS;    }    event = &clockState->interrupts[ clockState->rotor];    EventDoCallback(cpuNum,EmbraDeliverSIPSCallback,event,(void *)chan,delay);}static void StatCallback(int cpuNum, EventCallbackHdr *hdr,void *arg){   Print_Recent_Stats(cpuNum);   EventDoCallback(cpuNum,StatCallback,hdr,0,embra.statInterval);}static void PeriodicCallback(int cpuNum, EventCallbackHdr *hdr,void *arg){#if 0    CPUPrint("callback %i %lld\n",cpuNum,CPUVec.CpuCycleCount(cpuNum));#endif    EventDoCallback(cpuNum,PeriodicCallback,hdr,0,embra.miscCheckInterval);    EmbraPollSigUsr(cpuNum);    if( sim_misc.myCPUType != sim_misc.enterThisCPU) {       EmbraExit(sim_misc.enterThisCPU);    }}static void PeriodicAnnotationCallback(int cpuNum, EventCallbackHdr *hdr,void *arg){   ASSERT(cpuNum == 0);   EventDoCallback(0,PeriodicAnnotationCallback,hdr,0,embra.periodicAnnInterval);   PERIODIC_EVENT;}/* **************************************************************** * Periodic_Callout is called very frequently. Keep it as short as  * possible.  * ****************************************************************/void IncCC(int cpuNum, int inc){   EMP[cpuNum].cycleCount += EMP[cpuNum].timeQuantum;}/*#define DEBUG_EVENTPOLL*/#ifdef DEBUG_EVENTPOLLstatic struct {   uint cycleCountdown;   uint PC;   uint64 cycleCount;   uint stalled;} debug_evpoll[SIM_MAXCPUS];static SimTime last_call;#endifvoid GeneralEmEventPoll(int cpuNum){   /*CPUPrint("%d GeneralEmEventPoll\n", cpuNum);*/   ASSERT(cpuNum < TOTAL_CPUS);#ifdef notdef#ifdef STALL_BY_REMOVING_FROM_LOOP   /* This needs justification */   /*EMP[TOTAL_CPUS].cycleCount += EMP[0].timeQuantum;*/   /*EventPollSingleQueue(EMP[TOTAL_CPUS].cycleCount);*/#else   ASSERT(cpuNum == 0 );#endif#endif /* notdef */   /* Value passed to EventPoll is a hint telling it how far down the      callback queue to look.  We know all cycle counts are within 1      quantum, so this should suffice */#ifdef DEBUG_EVENTPOLL   ASSERT( EmbraCpuCycleCount(0) + 4*EMP[0].timeQuantum > last_call);#endif   EventPollSingleQueue(EmbraCpuCycleCount(0) + 4*EMP[0].timeQuantum);#ifdef DEBUG_EVENTPOLL   debug_evpoll[cpuNum].cycleCountdown = EMP[cpuNum].cycleCountdown;   debug_evpoll[cpuNum].PC = EMP[cpuNum].PC;   debug_evpoll[cpuNum].cycleCount = EMP[cpuNum].cycleCount;   debug_evpoll[cpuNum].stalled = EMP[cpuNum].stalled;   last_call = EmbraCpuCycleCount(0) + 4*EMP[0].timeQuantum;#endif   /* some event hung off the cycle count may have    * changed memory (eg. the debugger).  This checks that.    */   FlushTCIfNecessary(cpuNum);   ReenterTC(EMP[TOTAL_CPUS].next);   /* NOT REACHED */}/* This is called when a single event queue is used TOTAL_CPUS == 1 || MPinUP */EmbraState* CEmEventPoll(void){   /* Value passed to EventPoll is a hint telling it how far down the      callback queue to look.  We know all cycle counts are within 1      quantum, so this should suffice */   SimTime now_ish = EmbraCpuCycleCount(0);   if (eventQueues->calltime + 100000 < now_ish) {      CPUWarning("CEmEventPoll missing callouts calltime=%lld, nowish=%lld \n",                 eventQueues->calltime, now_ish);   }            #ifdef DEBUG_EVENTPOLL   ASSERT( now_ish >= last_call );#endif   if( EventPendingSingleQueue(now_ish) ) {      EventProcessSingleQueue( now_ish );      /* Code is written to assume that this will happen because         exceptions can be raised in a callback */      ReenterTC( &EMP[0] );      /* NOT REACHED */   }#ifdef DEBUG_EVENTPOLL   debug_evpoll[cpuNum].cycleCountdown = EMP[cpuNum].cycleCountdown;   debug_evpoll[cpuNum].PC = EMP[cpuNum].PC;   debug_evpoll[cpuNum].cycleCount = EMP[cpuNum].cycleCount;   debug_evpoll[cpuNum].stalled = EMP[cpuNum].stalled;   last_call = EmbraCpuCycleCount(0) + 4*EMP[0].timeQuantum;#endif   /* ReenterTC(EMP[TOTAL_CPUS].next);*/   /* NOT REACHED */   return &EMP[0];}void NonReturningProcReturned(void){   VASSERT(0,("Non-returning procedure returned.  This is bad.\n"));}SimTime EmbraReadTime( void ){   if( embra.MPinUP ) {      return EmbraCpuCycleCount(0);   } else {      return EmbraCpuCycleCount(CURR_CPU);   }}/*#define DEBUG_CLOCK*/#ifdef DEBUG_CLOCKstatic struct {   uint cycleCountdown;   uint PC;   uint64 cycleCount;   uint clock_val;} debug_clock[SIM_MAXCPUS];#endifSimTime EmbraCpuCycleCount(int cpuNum){   static SimTime last_returned_value;   SimTime new_value;   new_value = EMP[cpuNum].cycleCount +       ( (int64)(EMP[cpuNum].timeQuantum -                     EMP[cpuNum].cycleCountdown ) );   #ifdef DEBUG_CLOCK   if (new_value < debug_clock[cpuNum].clock_val) {      CPUWarning("cpu %d retrograde clock %lld->%lld, staying at max\n",                 cpuNum, debug_clock[cpuNum].clock_val, new_value);      new_value = debug_clock[cpuNum].clock_val;   }      debug_clock[cpuNum].cycleCountdown = EMP[cpuNum].cycleCountdown;   debug_clock[cpuNum].cycleCount = EMP[cpuNum].cycleCount;   debug_clock[cpuNum].PC = EMP[cpuNum].PC;   debug_clock[cpuNum].clock_val = new_value;#endif   return new_value;}/* Make the .cycleCount field the actual current time */void EmbraFixCycleCounts(void){   int cpuNum;   SimTime maxTime = 0;   for (cpuNum=0;cpuNum<TOTAL_CPUS;cpuNum++) {       EMP[cpuNum].cycleCount += EMP[cpuNum].timeQuantum -          EMP[cpuNum].cycleCountdown;      EMP[cpuNum].cycleCountdown = EMP[cpuNum].timeQuantum;      if ( EMP[cpuNum].cycleCount > maxTime) {          maxTime = EMP[cpuNum].cycleCount;      }   }   for (cpuNum=0;cpuNum<TOTAL_CPUS;cpuNum++) {       EMP[cpuNum].cycleCount = maxTime;   }}void EmbraClockInit(void){    if( !clockState ) {        clockState = MallocShared(sizeof(ClockSharedState),"EmClock");    }    ASSERT( clockState );}/****************************************************************** * Write a call to the system call exit on the user's stack.  Then  * jump to it *****************************************************************/void EmbraMakeProcExit(int cpuNum){   EmbraState *P = &EMP[cpuNum];   uint *pPtr;   VA vSP;   /* Insure that we are not writting over a page boundary by using */   /* the beginning of the page*/     vSP = FORM_ADDR( PAGE_NUMBER(P->R[REG_SP]), 0 );   pPtr = (uint*) non_excepting_tv( cpuNum, vSP );   if( !pPtr ) {      CPUWarning("Failure to translate stack addr in MakeProcExit\n");      return;   }   CPUWarning("PROCexit: CPU %d smashing address %#x\n", P->myNum, vSP);   *pPtr++ = CIi( addiu_op, A0, G0, 0 ); /* li a0, 0 */   *pPtr++ = CIi( addiu_op, V0, G0, 1001 ); /* li v0, 1001 */   /* This trick won't work in base mode both because of this opcode */   /* because we are not flushing the data cache*/   *pPtr++ = CIs( syscall_op, 0, 0, 0); /* syscall */   P->PC = vSP;   return;}

⌨️ 快捷键说明

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