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

📄 eventcallback.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.  * *//**************************************************************** * eventcallback.c *  * Generic callback mechanism.  *  * $Author: bosch $ * $Date: 1998/02/10 00:28:21 $ *****************************************************************/#include <stdio.h>#include <stdlib.h>#include "simutil.h"#include "simtypes.h"#include "sim_error.h"#include "eventcallback.h"#include "cpu_interface.h"#include "machine_params.h"/* Keep the asserts happy */#define DEBUGLINE "%10u %-20s: rout %#x elm %#x arg %#x\n"#ifdef notdef#define EVENT_LOCK(_x)   { if( !CPUVec.singleEventQueue ) Simcp0Lock(  &(_x->lock)); }#define EVENT_UNLOCK(_x) { if( !CPUVec.singleEventQueue ) Simcp0Unlock(&(_x->lock)); } #else#define EVENT_LOCK(_x)#define EVENT_UNLOCK(_x)#endifEventQueue *eventQueues = 0;/***************************************************************** * EventDoCallback *****************************************************************/void EventDoCallback(int cpuNum, void (*rout)(int,EventCallbackHdr *,void*),		     EventCallbackHdr *elm, void *arg, SimTime timeInFuture) {    SimTime when;    EventCallbackHdr *next;     EventQueue *queue;   ASSERT( elm && CPUVec.CycleCount );   ASSERT( !elm->active );   ASSERT( (int64)timeInFuture >= 0);   when = CPUVec.CycleCount(cpuNum) + timeInFuture;   elm->rout = rout;   elm->arg = arg;   elm->active = TRUE;   elm->cpuNum = cpuNum;   if (CPUVec.singleEventQueue) {       queue = eventQueues;   } else {       queue = eventQueues + cpuNum;   }   /*    * This can happen in Embra MPinUP if the cycle counts    * are off my more that the timeInFuture    */   if (when <= queue->lastCall && timeInFuture > 0) {      when = queue->lastCall +1;   }   if (when < queue->lastCall && timeInFuture == 0) {      when = queue->lastCall;   }      elm->when = when;   ASSERT(when < SIM_MAX_TIME);   EVENT_LOCK(queue);   next = &queue->sentinel;   while (1) {      ASSERT( next->next );      if (when < next->next->when) {         elm->next = next->next;         next->next = elm;         break;      } else {          next = next->next;      }   }   queue->calltime = queue->sentinel.next->when;   EVENT_UNLOCK(queue);}/***************************************************************** * EventProcess * cpuNum is ignored if all events are in the same queue *****************************************************************/voidEventProcess(int cpuNum, SimTime now) {    EventQueue *queue;    EventCallbackHdr *h;    if (CPUVec.singleEventQueue ) {       queue = eventQueues;       ASSERT( cpuNum < 0 );    } else {       queue = eventQueues + cpuNum;       ASSERT( cpuNum >= 0 && cpuNum < TOTAL_CPUS );    }    h = &queue->sentinel;    EVENT_LOCK(queue);    ASSERT(h);    if (queue->lastCall >=  now) {        CPUPrint("EventCallback: processing events at %lld. Prev time: %lld\n",                (uint64)now, (uint64)queue->lastCall);    }    while (h->next->when <= now) {       EventCallbackHdr *elm = h->next;       /*        * Make sure that the time is also up for the        * particular CPU. If not, bypass the callback        */       if (elm->when  <= CPUVec.CycleCount(elm->cpuNum)) {          h->next = h->next->next;           elm->active = FALSE;          EVENT_UNLOCK(queue);          elm->rout(elm->cpuNum, elm, elm->arg);          EVENT_LOCK(queue);          /*            * Restart from the top of the queue. Event might have been            * inserted during the processing           */          h = &queue->sentinel;          /*           * moved this here, so that it is updated only if           * an event for the correct CPU is found            */           queue->lastCall = now;       } else {          h=h->next;       }    }    queue->calltime = queue->sentinel.next->when;    EVENT_UNLOCK(queue);}/***************************************************************** * EventCallbackWaiting *****************************************************************/boolEventCallbackWaiting(EventCallbackHdr * event){   return event->active;}/***************************************************************** * EventCallbackUpdate *  *****************************************************************/voidEventCallbackUpdate(EventCallbackHdr * event, SimTime newtime){   int cpuNum = event->cpuNum;   ASSERT(event->active);   ASSERT(newtime < event->when);      EventCallbackRemove(event);   EventDoCallback(cpuNum,event->rout,event, event->arg, newtime -                    CPUVec.CycleCount(cpuNum));   }/***************************************************************** * EventCallbackRemove * *****************************************************************/voidEventCallbackRemove(EventCallbackHdr * event){   EventQueue *queue;   int cpuNum = event->cpuNum;   EventCallbackHdr *next;      if (CPUVec.singleEventQueue ) {      queue = eventQueues;   } else {       queue = eventQueues+cpuNum;   }   EVENT_LOCK(queue);   next = &queue->sentinel;   while (next->next) {      if( next->next ==  &queue->sentinel ) break;      if (next->next == event) {         next->next = event->next;         event->active = FALSE;         queue->calltime = queue->sentinel.next->when;         EVENT_UNLOCK(queue);         return;      }      next = next->next;   }   CPUWarning("EventCallbackRemove called on event not on list\n");}void EventCallbackInit(int numCPUs){   int i;   if (!eventQueues) {      eventQueues = ZMALLOC(sizeof(EventQueue)*numCPUs,"EventCallback");      ASSERT( eventQueues );   }   for(i=0;i<numCPUs;i++) {      eventQueues[i].sentinel.next =  & eventQueues[i].sentinel;      eventQueues[i].sentinel.when = SIM_MAX_TIME;   }}

⌨️ 快捷键说明

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