📄 eventcallback.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 + -