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

📄 evlst.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
字号:
/* * Copyright (c) 2002 The Board of Trustees of the University of Illinois and *                    William Marsh Rice University * Copyright (c) 2002 The University of Utah * Copyright (c) 2002 The University of Notre Dame du Lac * * All rights reserved. * * Based on RSIM 1.0, developed by: *   Professor Sarita Adve's RSIM research group *   University of Illinois at Urbana-Champaign and     William Marsh Rice University *   http://www.cs.uiuc.edu/rsim and http://www.ece.rice.edu/~rsim/dist.html * ML-RSIM/URSIM extensions by: *   The Impulse Research Group, University of Utah *   http://www.cs.utah.edu/impulse *   Lambert Schaelicke, University of Utah and University of Notre Dame du Lac *   http://www.cse.nd.edu/~lambert *   Mike Parker, University of Utah *   http://www.cs.utah.edu/~map * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal with the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimers.  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimers in the *    documentation and/or other materials provided with the distribution. * 3. Neither the names of Professor Sarita Adve's RSIM research group, *    the University of Illinois at Urbana-Champaign, William Marsh Rice *    University, nor the names of its contributors may be used to endorse *    or promote products derived from this Software without specific prior *    written permission.  * 4. Neither the names of the ML-RSIM project, the URSIM project, the *    Impulse research group, the University of Utah, the University of *    Notre Dame du Lac, nor the names of its contributors may be used to *    endorse or promote products derived from this software without specific *    prior written permission.  * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS WITH THE SOFTWARE.  *//* * evlst.c * * This file contains functions associated with maintaining * the simulator event list. */#include <stdio.h>#include <string.h>#include "sim_main/simsys.h"#include "sim_main/tr.evlst.h"#include "sim_main/tr.act.h"/*****************************************************************************//* EVENT LIST Operations: There are two implementations of the eventlist:    *//* a calendar queue and a simple linear list.  The choice of which list      *//* to use is determined by a command line argument or by the operation       *//* EventListSelect().  The implementaton of the calendar queue algorithm     *//* follows the description in "Calendar Queues: A Fast O(1) Priority         *//* Queue Implementation for the Simulation Event Set Problem," by Randy      *//* Brown, Comm. ACM, Oct. 1988, pp. 1220-1227.                               *//*****************************************************************************/STATREC *lengthstat = 0;           /* For collecting queue length statistics *//*  * Variables used when the event List is implemented as a * simple linear list  */EVENT *head;                  /* Pointer to the first element of the queue   */EVENT *tail;                  /* Pointer to the last element of the queue    */int   size;                   /* Number of elements in the queue             *//*  * Creates & returns pointer to an event  */EVENT *NewEvent(const char *ename, func bodyname, int dflag, int etype){  EVENT *eptr;  PSDELAY;  /* Get the activity descriptor */  eptr             = (EVENT*) YS__PoolGetObj(&YS__EventPool);       eptr->id         = YS__idctr++;         /* System assigned unique ID       */  strncpy(eptr->name, ename, 31);         /* Copy the name                   */  eptr->name[31]   = '\0';                /* Limited to 31 characters        */  eptr->next       = NULL;  eptr->argptr     = 0;  eptr->argsize    = 0;  eptr->time       = 0.0;  eptr->status     = LIMBO;  eptr->scheduled  = UNSCHEDULED;  eptr->blkflg     = INDEPENDENT;  eptr->timeleft   = 0.0;  eptr->enterque   = 0.0;  eptr->body       = bodyname;  eptr->deleteflag = dflag;  eptr->state      = 0;    TRACE_EVENT_event;                      /* Creating event ...              */  return eptr;}/* * Initializes the event list */void YS__EventListInit(void){  TRACE_EVLST_init2;  head = 0;  tail = 0;  size = 0;}/*  * Returns the system defined ID or 0 if TraceIDs is 0  */int YS__EventId(EVENT *vptr)      {  if (TraceIDs)    {  /* TraceIDs must be set to get IDs printed in traces */      if (vptr)	return vptr->id;       /* vptr points to something */      else if (YS__ActEvnt)	return YS__ActEvnt->id;/* Called from an active event */      else	YS__errmsg(0, "Null Event Referenced");      return 0;    }  else    return 0;}/* * Inserts an element into the event list */void YS__EventListInsert(EVENT *vptr){  int i;  EVENT *tp1;  EVENT *tp2;  TRACE_EVLST_insert;  size++;  if (head == 0)    {       /* The queue is empty */      head = vptr;      tail = vptr;      vptr->next = 0;    }  else    {      if (vptr->time < head->time)	{	  /* Put the new element at head of queue */	  vptr->next = (QE *) head;	  head = vptr;	}      else	{	  if (vptr->time >= tail->time)	    {	      /* Put new element at tail of queue */	      tail->next = (QE *) vptr;	      vptr->next = 0;	      tail = vptr;	    }	  else	    {	      /* put element in middle of queue */	      tp1 = head;	      /* Find position */	      while (vptr->time >= ((EVENT *) (tp1->next))->time)		tp1 = (EVENT *) (tp1->next);	      	      vptr->next = tp1->next;	      tp1->next = (QE *) vptr;	    }	}    }#ifdef DEBUG_EVENT  if (lengthstat)   /* Queue length statistics collected */    StatrecUpdate(lengthstat, (double) size, 1.0);#endif  TRACE_EVLST_show;}/* * Removes an element from the event list */void YS__EventListRemove(EVENT *vptr){  EVENT *e, *p;  if (head == vptr)    {      head = (EVENT*)vptr->next;    }  else    {      e = head;      while ((e != NULL) &&	     (e->next != NULL) &&	     (e->next != (QE*)vptr))	e = (EVENT*)e->next;      e->next = vptr->next;      if (tail == vptr)	tail = e;    }}/* * Returns the head of the event list */EVENT *YS__EventListGetHead(void){  EVENT *retptr;  if (head != 0)    {     /* Queue not empty */      size--;                          /* One fewer element in the queue */      retptr = head;                   /* Get the head element */      head = (EVENT *) (retptr->next);      retptr->next = 0;         /* Clear next pointer of removed element */      retptr->scheduled = UNSCHEDULED;      if (head == 0)	tail = 0;               /* Queue now empty */#ifdef DEBUG_EVENT       if (lengthstat)           /* Queue length statistics collectd */	StatrecUpdate(lengthstat, (double) size, 1.0);#endif            TRACE_EVLST_gethead2;    }  else    { /* Queue empty */      retptr = 0; /* Return NULL */      TRACE_EVLST_gethead1;    }  TRACE_EVLST_show;  return retptr;}/*  * Schedules an activity in the future  */void EventSchedTime(EVENT *actptr, double timeinc, int bflg)        {  EVENT *vptr;  PSDELAY;    if (actptr)    vptr = actptr;    /* actptr points to an activity, use it */  else if (YS__ActEvnt)    {      /* or an event is rescheduling itself */      if (YS__ActEvnt->deleteflag == DELETE)	YS__errmsg(0, "Can not reschedule a deleting event %s", actptr->name);      vptr = (EVENT *) YS__ActEvnt;    }  else    YS__errmsg(0, "Null Event Referenced");   /* or there is a mistake */  TRACE_EVENT_schedule1;    /* Scheduling activity to occur in "timeinc"			       time units */  vptr->blkflg = bflg;    if (vptr->status != RUNNING && vptr->status != LIMBO)    YS__errmsg(0, "Can not reschedule a pending event %s", vptr->name);#ifdef DEBUG  if (vptr->blkflg != INDEPENDENT)    YS__errmsg(0,	       "Only Independent block-flag supported for "	       "EventSchedTime in this version");#endif    if (timeinc == 0.0)    {        /* Schedule immediately */      vptr->time = YS__Simtime;      YS__RdyListAppend(vptr);    }  else if (timeinc > 0.0)    {    /* Schedule in the future */      vptr->time = YS__Simtime + timeinc;      vptr->status = DELAYED;      YS__EventListInsert(vptr);    }  else    YS__errmsg(0,	       "Can not schedule an activity to occur in the past %s",	       vptr->name);}/*  * Sets the argument pointer of an activity  */void EventSetArg(EVENT *vptr, void *arptr, int arsize)     {  PSDELAY;  if (vptr)    {          /* vptr points to an activity */      TRACE_EVENT_setarg;    /* Setting argument for activity ... */      vptr->argptr = arptr;     /* Set its argument */      vptr->argsize = arsize;    }   else if (YS__ActEvnt)     {          /* Called from an active event */       YS__ActEvnt->argptr = arptr;  /* It is setting its own argument */       YS__ActEvnt->argsize = arsize;     }  else    YS__errmsg(0, "Null Event Referenced");}/*  * Returns the argument pointer of an activity  */char *EventGetArg(EVENT *vptr) {  PSDELAY;  if (vptr)    {          /* vptr points to an activity */      TRACE_EVENT_getarg;    /* Getting argument from activity ... */      return vptr->argptr;    }  else if (YS__ActEvnt)    return YS__ActEvnt->argptr;       /* Active event or process */  else    YS__errmsg(0, "Null Event Referenced");  return NULL;}/*  * Returns the state set by EventSetState()  */int EventGetState(void){                         PSDELAY;  if (YS__ActEvnt)    return YS__ActEvnt->state;  else    YS__errmsg(0,	       "EventGetState() must be called from within an active event");  return 0;}/*  * Sets state used to designate a return point  */void EventSetState(EVENT *eptr, int st)         {  PSDELAY;  if (eptr == NULL)    /* Called from within the event */    if (YS__ActEvnt)      YS__ActEvnt->state = st;    else      YS__errmsg(0,		 "EventSetState() has NULL pointer, but not called from "		 "an event");  else    eptr->state = st;}#if 0/* * Returns the time value of the event list head */double YS__EventListHeadval(void){  double retval;  if (head != 0)    retval = (head)->time;  else    retval = -1.0;  TRACE_EVLST_headval;  return retval;}#endifvoid Evlst_dump(int nid){  EVENT *ev;  YS__logmsg(nid, "\n====== EVENT LIST ======\n");  for (ev = head; ev != NULL; ev = (EVENT*)ev->next)    {      YS__logmsg(nid, "Event %i: %s\n", ev->id, ev->name);      YS__logmsg(nid, "  enterque(%lf), time(%lf), status(%d), scheduled(%d)\n",		 ev->enterque, ev->time, ev->status, ev->scheduled);    }       }

⌨️ 快捷键说明

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