sam@lfcs.ed.ac.uk (S Manoharan) (08/30/90)
Posting-number: Volume 14, Issue 69 Submitted-by: sam@lfcs.ed.ac.uk (S Manoharan) Archive-name: silo/part01 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Bin.h # Counter.h # Debug.h # Entity.h # Event.h # Resource.h # Sim.h # SimEntityList.h # SimEventList.h # Bin.c # Debug.c # Entity.c # Event.c # Resource.c # Sim.c # SimEntityList.c # SimEventList.c # Test.c # This archive created: Tue Aug 21 20:17:38 1990 # sam@lfcs.edinburgh.ac.uk export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else sed 's/^X//' << \SHAR_EOF > 'README' X/* $Author: sam $ $Date: 90/07/20 11:15:00 $ $Revision: 1.1 $ */ X X SILO : An event-based simulation platform. X ---- X S. Manoharan sam@lfcs.edinburgh.ac.uk X X XSILO is a library of C++ classes that provides building blocks Xfor constructing event-based discrete event simulations. It Xprovides four basic classes: Entity, Event, Resource and Bin. X XRefer to X@book{MacDo87, X author = "M H MacDougall", X year = "1987", X publisher = "MIT Press", X title = "Simulating Computer Systems: Techniques and Tools" X} Xfor a discussion on event-based simulations and a C implementaion. XSILO closely follows the description of [MacDo87]. X XClass Bin is a FIFO buffer of size infinity. Method `give' adds to Xthe buffer; `take' removes from the buffer. `take' blocks when the Xbuffer is empty. X XEvent *cause ( void ); X returns the event with the earliest time from the event list. Xshort cancel ( const int eid ); X cancels the event with the event id eid; returns 1 if success; Xdouble simtime ( void ); X returns the current simulation time; X XNotes: X----- X1. Use g++ version 1.37.1 or greater. The g++ class library provides Xclasses to generate random numbers. X X2. SILO is tested under g++ 1.37.1. Test.c provides an example Xexplained in [MacDo87]. X SHAR_EOF fi if test -f 'Bin.h' then echo shar: "will not over-write existing file 'Bin.h'" else sed 's/^X//' << \SHAR_EOF > 'Bin.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:17 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Bin_H X#define Bin_H X X#include "Entity.h" X#include "SimEntityList.h" X Xclass Bin { Xprivate: X char *bin_name; X int available; X short bin_used; X SimEntityList blockedQ; Xpublic: X Bin(const int = 0, char *const s = 0); X virtual ~Bin() { } X X virtual void set(const int sz); X virtual short status() { return available == 0; } X X virtual short take(Entity *const bywho, const int event_type); X virtual void give(); X}; X Xinline XBin::Bin(const int sz, char *const s) X{ X available = sz; X bin_name = s; X bin_used = 0; X} X X#endif Bin_H SHAR_EOF fi if test -f 'Counter.h' then echo shar: "will not over-write existing file 'Counter.h'" else sed 's/^X//' << \SHAR_EOF > 'Counter.h' X/* $Author: sam $ $Date: 90/07/11 13:31:58 $ $Revision: 1.1 $ */ X X#ifndef Counter_H X#define Counter_H X Xclass Counter { Xprivate: X double current; X double cycle; Xpublic: X Counter(double init = 0, double tck = 1); X X void set(const double t) { current = t; } X void tick(const double t) { cycle = t; } X X double operator () () const { return current; } X void operator += (const double inc) { current += inc; } X void operator -= (const double dec) { current -= dec; } X void operator -- () { current -= cycle; } X void operator ++ () { current += cycle; } X X double tick() const { return cycle; } X}; X Xinline XCounter::Counter(double init, double tck) X{ X current = init, cycle = tck; X} X X#endif Counter_H X SHAR_EOF fi if test -f 'Debug.h' then echo shar: "will not over-write existing file 'Debug.h'" else sed 's/^X//' << \SHAR_EOF > 'Debug.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:21 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Debug_H X#define Debug_H X X#include <std.h> X#include <stream.h> X Xextern int debug_flag; /* global debug flag */ X Xinline int Xdebug_level(const int level) X{ X return ( ::debug_flag > 0 && ::debug_flag <= level ); X} X Xextern void freeStoreException(); X X#endif Debug_H SHAR_EOF fi if test -f 'Entity.h' then echo shar: "will not over-write existing file 'Entity.h'" else sed 's/^X//' << \SHAR_EOF > 'Entity.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:23 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Entity_H X#define Entity_H X Xclass Event; class Entity; X Xclass Entity { Xfriend class Resource; Xprivate: X int entity_id; X int prio; X char *entity_name; X int current_event; X double afterTime; Xprotected: Xpublic: X Entity(char *const s = 0); X virtual ~Entity() { } X X int id() const { return entity_id; } X virtual void name(char *const s) { entity_name = s; } X virtual char *name() const { return entity_name; } X X virtual void currentEvent(const int e) { current_event = e; } X virtual int currentEvent() const { return current_event; } X virtual void priority(const int p) { prio = p; } X virtual int priority() const { return prio; } X X virtual void schedule(const double delay, Event *const ev); X}; X X#endif Entity_H SHAR_EOF fi if test -f 'Event.h' then echo shar: "will not over-write existing file 'Event.h'" else sed 's/^X//' << \SHAR_EOF > 'Event.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:26 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Event_H X#define Event_H X Xclass Event; class Entity; X Xclass Event { Xprivate: X int event_id; X int event_type; X double etime; X Entity *bywho; Xprotected: Xpublic: X Event(const int ev_type = 0); X virtual ~Event() { } X X virtual int id() const { return event_id; } X virtual void type(const int n) { event_type = n; } X virtual int type() const { return event_type; } X virtual void eventTime(const double t) { etime = t; } X virtual double eventTime() const { return etime; } X virtual void scheduled_by(Entity *const who) { bywho = who; } X virtual Entity *scheduled_by() const { return bywho; } X}; X X#endif Event_H SHAR_EOF fi if test -f 'Resource.h' then echo shar: "will not over-write existing file 'Resource.h'" else sed 's/^X//' << \SHAR_EOF > 'Resource.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:29 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Resource_H X#define Resource_H X X// X// An entity can reserve a resource for an event of type event_type. X// Reserved or preempted resources can later be released. Reserve, X// if unsuccessful, places the entity in blockedQ and returns 0. X// A release examines the blockedQ for blocked entities, removes X// the head of the Q and re-schedules the event during which the entity X// got blocked. X// X X#include "Entity.h" X#include "SimEntityList.h" X Xclass Resource { Xprivate: X char *resource_name; X int available; X short resource_used; X SimEntityList blockedQ, servedQ; Xpublic: X Resource(const int = 1, char *const s = 0); X virtual ~Resource() { } X X virtual void set(const int sz); X virtual short status() { return available == 0; } X X virtual short reserve(Entity *const bywho, const int event_type); X virtual short preempt(Entity *const bywho, const int event_type); X virtual void release(Entity *const bywho); X}; X Xinline XResource::Resource(const int sz, char *const s) X{ X available = sz; X resource_name = s; X resource_used = 0; X} X X#endif Resource_H SHAR_EOF fi if test -f 'Sim.h' then echo shar: "will not over-write existing file 'Sim.h'" else sed 's/^X//' << \SHAR_EOF > 'Sim.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:32 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef Sim_H X#define Sim_H X X#include <std.h> X#include <stream.h> X X#include "Debug.h" X#include "Event.h" X#include "Entity.h" X#include "Resource.h" X#include "Bin.h" X XEvent *cause ( void ); Xshort cancel ( const int eid ); Xdouble simtime ( void ); X X X#endif Sim_H X SHAR_EOF fi if test -f 'SimEntityList.h' then echo shar: "will not over-write existing file 'SimEntityList.h'" else sed 's/^X//' << \SHAR_EOF > 'SimEntityList.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:36 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef SimEntityList_H X#define SimEntityList_H X X#include "Entity.h" X Xclass SimEntityList; X Xclass SimEntityItem { X friend class SimEntityList; Xprivate: X SimEntityItem *next; X SimEntityItem *prev; X Entity * entity; X X SimEntityItem(Entity *const v = 0) X { entity = v; next = prev = 0; } X}; X Xclass SimEntityList { Xprivate: X SimEntityItem *head; X SimEntityItem *tail; X char *listname; Xpublic: X SimEntityList(char *const s = 0) X { head = tail = 0; listname = s; } X SimEntityList(Entity *const entity, char *const s) X { head = new SimEntityItem(entity); listname = s; } X virtual ~SimEntityList(); X X void name(char *const s) { listname = s; } X char *name() const { return listname; } X short is_empty() { return head == 0; } X void print(); X X int min_entity_id(); X int max_entity_id(); X X Entity *get() { return remove(max_entity_id()); } X Entity *remove(const int eid); X X void insert(Entity *const); X void append(Entity *const); X}; X X X X#endif SimEntityList_H SHAR_EOF fi if test -f 'SimEventList.h' then echo shar: "will not over-write existing file 'SimEventList.h'" else sed 's/^X//' << \SHAR_EOF > 'SimEventList.h' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:43 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#ifndef SimEventList_H X#define SimEventList_H X X#include "Event.h" X Xclass SimEventList; X Xclass SimEventItem { X friend class SimEventList; Xprivate: X SimEventItem *next; X SimEventItem *prev; X Event * event; X X SimEventItem(Event *const v = 0) X { event = v; next = prev = 0; } X}; X Xclass SimEventList { Xprivate: X SimEventItem *head; X SimEventItem *tail; X char *listname; Xpublic: X SimEventList(char *const s = 0) X { head = tail = 0; listname = s; } X SimEventList(Event *const event, char *const s) X { head = new SimEventItem(event); listname = s; } X virtual ~SimEventList(); X X void name(char *const s) { listname = s; } X char *name() const { return listname; } X short is_empty() { return head == 0; } X void print(); X X int min_event_id(); X int max_event_id(); X X Event *get() { return remove(min_event_id()); } X Event *remove(const int eid); X Event *remove(Entity *const ent); X X void insert(Event *const); X void append(Event *const); X}; X X X X#endif SimEventList_H SHAR_EOF fi if test -f 'Bin.c' then echo shar: "will not over-write existing file 'Bin.c'" else sed 's/^X//' << \SHAR_EOF > 'Bin.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:38 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include "Bin.h" X#include "Sim.h" X X Xshort XBin::take(Entity *bywho, const int event_type) X{ X bin_used = 1; X X if ( bywho == 0 ) X cout << form("** Error: take by null entity\n"); X X if ( available > 0 ) { X --available; X bywho->currentEvent(event_type); X return 1; X } X else { X bywho->currentEvent(event_type); X blockedQ.append(bywho); X return 0; X } X} X Xvoid XBin::give() X{ X Entity *entity; X X if ( debug_level(1) ) { X cout << form("Releasing bin %s\n", bin_name); X cout << "\n---Begin{blockedQ}\n"; X blockedQ.print(); X cout << "\n---End{blockedQ}\n"; X } X X if ( ( entity = blockedQ.get() ) != 0 ) { X Event *event = new Event(entity->currentEvent()); X entity->schedule(0, event); X } X ++available; X} X Xvoid XBin::set(const int sz) X{ X if ( bin_used ) { X cout << form("%s: bin already used. cannot set size\n", X bin_name); X exit(-1); X } X available = sz; X} X SHAR_EOF fi if test -f 'Debug.c' then echo shar: "will not over-write existing file 'Debug.c'" else sed 's/^X//' << \SHAR_EOF > 'Debug.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:43 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include <std.h> X#include <stream.h> X X#include "Debug.h" X Xint debug_flag = 0; /* global debug flag */ X Xvoid XfreeStoreException() X{ X cout << form("Baby, You're cored.\n"); X exit(-1); X} X SHAR_EOF fi if test -f 'Entity.c' then echo shar: "will not over-write existing file 'Entity.c'" else sed 's/^X//' << \SHAR_EOF > 'Entity.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:49 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include "Entity.h" X#include "SimEventList.h" X#include "Debug.h" X X#include "Counter.h" X Xstatic Counter timer; XSimEventList eventlist; X XEvent *cause() X{ X if ( debug_level(1) ) { X cout << "\n---Begin{eventlist}\n"; X ::eventlist.print(); X cout << "\n---End{eventlist}\n"; X } X X X Event *ev = ::eventlist.get(); X if ( ev == 0 ) return 0; X X if ( ev->eventTime() > ::timer() ) X ::timer.set(ev->eventTime()); X X return ev; X} X Xshort cancel(const int eid) X{ X Event *ev = ::eventlist.remove(eid); X X if ( ev == 0 ) return 0; X else { X delete ev; X return 1; X } X} X Xdouble simtime() X{ X return timer(); X} X XEntity::Entity(char *const s) X{ X static int eid = 0; X X entity_name = s, entity_id = eid++; X} X Xvoid XEntity::schedule(const double delay, Event *const ev) X{ X if ( delay < 0 ) { X cout << form("%s: invalid delay %g\n", entity_name, delay); X exit(-1); X } X ev->scheduled_by(this); X ev->eventTime(::timer() + delay); X X ::eventlist.append(ev); X} X SHAR_EOF fi if test -f 'Event.c' then echo shar: "will not over-write existing file 'Event.c'" else sed 's/^X//' << \SHAR_EOF > 'Event.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:53 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include "Event.h" X XEvent::Event(const int ev_type) X{ X static int e_id = 0; X X event_type = ev_type; event_id = e_id++; X} X SHAR_EOF fi if test -f 'Resource.c' then echo shar: "will not over-write existing file 'Resource.c'" else sed 's/^X//' << \SHAR_EOF > 'Resource.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:56 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include "Resource.h" X#include "Sim.h" X#include "SimEventList.h" X Xextern SimEventList eventlist; X Xshort XResource::reserve(Entity *bywho, const int event_type) X{ X resource_used = 1; X X if ( bywho == 0 ) X cout << form("** Error: reserve by null entity\n"); X X bywho->currentEvent(event_type); X bywho->afterTime = 0; X X if ( available > 0 ) { X --available; X servedQ.append(bywho); X return 1; X } X else { X blockedQ.append(bywho); X return 0; X } X} X Xshort XResource::preempt(Entity *bywho, const int event_type) X{ X resource_used = 1; X X if ( bywho == 0 ) X cout << form("** Error: preempt by null entity\n"); X X bywho->currentEvent(event_type); X bywho->afterTime = 0; X X if ( available > 0 ) { X --available; X servedQ.append(bywho); X return 1; X } X else { X Entity *minPrioEnt = servedQ.remove(servedQ.min_entity_id()); X if ( minPrioEnt->priority() >= bywho->priority() ) { // no preempt X blockedQ.append(bywho); X servedQ.append(minPrioEnt); X return 0; X } X else { // preempt X servedQ.append(bywho); X Event *stopped = ::eventlist.remove(minPrioEnt); X if ( stopped == 0 ) { X cout << form("** Error: no events for preempted entity\n"); X return 0; X } X minPrioEnt->afterTime = stopped->eventTime() - simtime(); X minPrioEnt->currentEvent(stopped->type()); X blockedQ.insert(minPrioEnt); X return 1; X } X } X} X Xvoid XResource::release(Entity *const bywho) X{ X Entity *entity; X X if ( bywho == 0 ) X cout << form("** Error: release by null entity\n"); X X if ( debug_level(1) ) { X cout << form("Releasing resource %s\n", resource_name); X cout << "\n---Begin{blockedQ}\n"; X blockedQ.print(); X cout << "\n---End{blockedQ}\n"; X } X X if ( servedQ.remove(bywho->id()) == 0 ) X cout << form("** Error: release without reserve\n"); X X if ( ( entity = blockedQ.get() ) != 0 ) { X Event *event = new Event(entity->currentEvent()); X entity->schedule(entity->afterTime, event); X } X ++available; X} X Xvoid XResource::set(const int sz) X{ X if ( resource_used ) { X cout << form("%s: resource already used. cannot set size\n", X resource_name); X exit(-1); X } X available = sz; X} X SHAR_EOF fi if test -f 'Sim.c' then echo shar: "will not over-write existing file 'Sim.c'" else sed 's/^X//' << \SHAR_EOF > 'Sim.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:45:59 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include "Counter.h" X X#include "Sim.h" X#include "SimEventList.h" X X Xstatic Counter timer; Xstatic SimEventList eventlist; X XEvent *cause() X{ X if ( debug_level(1) ) { X cout << "\n---Begin{eventlist}\n"; X ::eventlist.print(); X cout << "\n---End{eventlist}\n"; X } X X X Event *ev = ::eventlist.get(); X if ( ev == 0 ) return 0; X X if ( ev->eventTime() > ::timer() ) X ::timer.set(ev->eventTime()); X X return ev; X} X Xshort cancel(const int eid) X{ X Event *ev = ::eventlist.remove(eid); X X if ( ev == 0 ) return 0; X else { X delete ev; X return 1; X } X} X Xdouble simtime() X{ X return timer(); X} X XEntity::Entity(char *const s) X{ X static int eid = 0; X X entity_name = s, entity_id = eid++; X} X Xvoid XEntity::schedule(const double delay, Event *const ev) X{ X if ( delay < 0 ) { X cout << form("%s: invalid delay %g\n", entity_name, delay); X exit(-1); X } X ev->scheduled_by(this); X ev->eventTime(::timer() + delay); X X ::eventlist.append(ev); X} X Xshort XResource::reserve(Entity *bywho, const int event_type) X{ X resource_used = 1; X X if ( bywho == 0 ) X cout << form("** Error: reserve by null entity\n"); X X bywho->currentEvent(event_type); X bywho->afterTime = 0; X X if ( available > 0 ) { X --available; X servedQ.append(bywho); X return 1; X } X else { X blockedQ.append(bywho); X return 0; X } X} X Xshort XResource::preempt(Entity *bywho, const int event_type) X{ X resource_used = 1; X X if ( bywho == 0 ) X cout << form("** Error: preempt by null entity\n"); X X bywho->currentEvent(event_type); X bywho->afterTime = 0; X X if ( available > 0 ) { X --available; X servedQ.append(bywho); X return 1; X } X else { X Entity *minPrioEnt = servedQ.remove(servedQ.min_entity_id()); X if ( minPrioEnt->priority() >= bywho->priority() ) { // no preempt X blockedQ.append(bywho); X servedQ.append(minPrioEnt); X return 0; X } X else { // preempt X servedQ.append(bywho); X Event *stopped = ::eventlist.remove(minPrioEnt); X if ( stopped == 0 ) { X cout << form("** Error: no events for preempted entity\n"); X return 0; X } X minPrioEnt->afterTime = stopped->eventTime() - simtime(); X minPrioEnt->currentEvent(stopped->type()); X blockedQ.insert(minPrioEnt); X delete stopped; X return 1; X } X } X} X Xvoid XResource::release(Entity *const bywho) X{ X Entity *entity; X X if ( bywho == 0 ) X cout << form("** Error: release by null entity\n"); X X if ( debug_level(1) ) { X cout << form("Releasing resource %s\n", resource_name); X cout << "\n---Begin{blockedQ}\n"; X blockedQ.print(); X cout << "\n---End{blockedQ}\n"; X } X X if ( servedQ.remove(bywho->id()) == 0 ) X cout << form("** Error: release without reserve\n"); X X if ( ( entity = blockedQ.get() ) != 0 ) { X Event *event = new Event(entity->currentEvent()); X entity->schedule(entity->afterTime, event); X if ( entity->afterTime == 0 ) ++available; X } X else ++available; X} X Xvoid XResource::set(const int sz) X{ X if ( resource_used ) { X cout << form("%s: resource already used. cannot set size\n", X resource_name); X exit(-1); X } X available = sz; X} X SHAR_EOF fi if test -f 'SimEntityList.c' then echo shar: "will not over-write existing file 'SimEntityList.c'" else sed 's/^X//' << \SHAR_EOF > 'SimEntityList.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:03 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include <stream.h> X X#include "SimEntityList.h" X X XSimEntityList::~SimEntityList() X{ X SimEntityItem *listnode = head; X X while ( listnode ) { X SimEntityItem *temp = listnode; X X listnode = listnode->next; X delete temp; X } X head = tail = 0; X} X Xvoid XSimEntityList::insert(Entity *const entity) X{ X SimEntityItem *listnode = new SimEntityItem(entity); X listnode->next = head; X if ( head ) head->prev = listnode; X else tail = listnode; X head = listnode; X} X Xvoid XSimEntityList::append(Entity *const entity) X{ X SimEntityItem *listnode = new SimEntityItem(entity); X listnode->prev = tail; X if ( tail ) tail->next = listnode; X else head = listnode; X tail = listnode; X} X XEntity * XSimEntityList::remove(const int eid) X{ X SimEntityItem *listnode = head; X SimEntityItem *temp; X Entity * gotcha = 0; X X while ( listnode ) { X if ( (listnode->entity)->id() == eid ) { X gotcha = listnode->entity; X temp = listnode; X if ( listnode->prev != 0 ) X (listnode->prev)->next = listnode->next; X else head = listnode->next; X if ( listnode->next != 0 ) X (listnode->next)->prev = listnode->prev; X else tail = listnode->prev; X listnode = listnode->next; X delete temp; X break; X } X else listnode = listnode->next; X } X return gotcha; X} X Xint XSimEntityList::max_entity_id() X{ X SimEntityItem *listnode = head; X X if ( head == 0 ) return 0; X X int max = (head->entity)->priority(); X int eid = (head->entity)->id(); X while ( listnode ) { X if ( (listnode->entity)->priority() > max ) { X max = (listnode->entity)->priority(); X eid = (listnode->entity)->id(); X } X listnode = listnode->next; X } X return eid; X} X Xint XSimEntityList::min_entity_id() X{ X SimEntityItem *listnode = head; X X if ( head == 0 ) return 0; X X int min = (head->entity)->priority(); X int eid = (head->entity)->id(); X while ( listnode ) { X if ( (listnode->entity)->priority() < min ) { X min = (listnode->entity)->priority(); X eid = (listnode->entity)->id(); X } X listnode = listnode->next; X } X return eid; X} X Xvoid XSimEntityList::print() X{ X if ( listname != 0 ) cout << listname << ":\n"; X X if ( head == 0 ) { X cout << "[ empty ]\n"; X return; X } X X cout << "[ "; X X SimEntityItem *listnode = head; X const int lineLength = 16; X int cnt = 0; X while ( listnode != 0 ) { X if ( ++cnt % lineLength == 1 && cnt != 1 ) X cout << "\n "; X /* print list->entry at this point */ X cout << form("0x%x (%g) ", X (listnode->entity)->id(), (listnode->entity)->priority()); X listnode = listnode->next; X } X cout << "]\n"; X} X SHAR_EOF fi if test -f 'SimEventList.c' then echo shar: "will not over-write existing file 'SimEventList.c'" else sed 's/^X//' << \SHAR_EOF > 'SimEventList.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:06 $ $Revision: 1.1 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X#include <stream.h> X X#include "SimEventList.h" X X XSimEventList::~SimEventList() X{ X SimEventItem *listnode = head; X X while ( listnode ) { X SimEventItem *temp = listnode; X X listnode = listnode->next; X delete temp; X } X head = tail = 0; X} X Xvoid XSimEventList::insert(Event *const event) X{ X SimEventItem *listnode = new SimEventItem(event); X listnode->next = head; X if ( head ) head->prev = listnode; X else tail = listnode; X head = listnode; X} X Xvoid XSimEventList::append(Event *const event) X{ X SimEventItem *listnode = new SimEventItem(event); X listnode->prev = tail; X if ( tail ) tail->next = listnode; X else head = listnode; X tail = listnode; X} X XEvent * XSimEventList::remove(const int eid) X{ X SimEventItem *listnode = head; X SimEventItem *temp; X Event * gotcha = 0; X X while ( listnode ) { X if ( (listnode->event)->id() == eid ) { X gotcha = listnode->event; X temp = listnode; X if ( listnode->prev != 0 ) X (listnode->prev)->next = listnode->next; X else head = listnode->next; X if ( listnode->next != 0 ) X (listnode->next)->prev = listnode->prev; X else tail = listnode->prev; X listnode = listnode->next; X delete temp; X break; X } X else listnode = listnode->next; X } X return gotcha; X} X XEvent * XSimEventList::remove(Entity *const ent) X{ X SimEventItem *listnode = head; X SimEventItem *temp; X Event * gotcha = 0; X X while ( listnode ) { X if ( (listnode->event)->scheduled_by() == ent ) { X gotcha = listnode->event; X temp = listnode; X if ( listnode->prev != 0 ) X (listnode->prev)->next = listnode->next; X else head = listnode->next; X if ( listnode->next != 0 ) X (listnode->next)->prev = listnode->prev; X else tail = listnode->prev; X listnode = listnode->next; X delete temp; X break; X } X else listnode = listnode->next; X } X return gotcha; X} X Xint XSimEventList::min_event_id() X{ X SimEventItem *listnode = head; X X if ( head == 0 ) return 0; X X double min = (head->event)->eventTime(); X int eid = (head->event)->id(); X while ( listnode ) { X if ( (listnode->event)->eventTime() < min ) { X min = (listnode->event)->eventTime(); X eid = (listnode->event)->id(); X } X listnode = listnode->next; X } X return eid; X} X Xint XSimEventList::max_event_id() X{ X SimEventItem *listnode = head; X X if ( head == 0 ) return 0; X X double max = (head->event)->eventTime(); X int eid = (head->event)->id(); X while ( listnode ) { X if ( (listnode->event)->eventTime() > max ) { X max = (listnode->event)->eventTime(); X eid = (listnode->event)->id(); X } X listnode = listnode->next; X } X return eid; X} X Xvoid XSimEventList::print() X{ X if ( listname != 0 ) cout << listname << ":\n"; X X if ( head == 0 ) { X cout << "[ empty ]\n"; X return; X } X X cout << "[ "; X X SimEventItem *listnode = head; X const int lineLength = 16; X int cnt = 0; X while ( listnode != 0 ) { X if ( ++cnt % lineLength == 1 && cnt != 1 ) X cout << "\n "; X /* print list->entry at this point */ X cout << form("0x%x (%g) ", X (listnode->event)->id(), (listnode->event)->eventTime()); X listnode = listnode->next; X } X cout << "]\n"; X} X SHAR_EOF fi if test -f 'Test.c' then echo shar: "will not over-write existing file 'Test.c'" else sed 's/^X//' << \SHAR_EOF > 'Test.c' X/* $Author: ecsv38 $ $Date: 90/08/21 14:46:11 $ $Revision: 1.2 $ */ X/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */ X X/* Reference -- X@book{MacDo87, X author = "M H MacDougall", X year = "1987", X publisher = "MIT Press", X title = "Simulating Computer Systems: Techniques and Tools" X} X-- */ X X X#include "Sim.h" X X#include <std.h> X#include <new.h> X#include <MLCG.h> X#include <DiscreteUniform.h> X X Xint main(int argc, char **argv) X{ X MLCG gen; X DiscreteUniform sample(0, 20, &gen); X X int Debug_flag = 0; X X X set_new_handler(freeStoreException); X X const double MAXTIME = 500; X X Resource server(1, "Server"); X Entity customer("Customer"); X const int ARRIVAL = 1; X const int DEPART = 2; X const int RESERVE = 3; X X double delay, inst; Event *event; X X Event *ev = new Event(ARRIVAL); X customer.schedule(0, ev); X while ( simtime() < MAXTIME ) { X event = cause(); inst = simtime(); X if ( event == 0 ) { X cout << form("%s: no more events to process\n", argv[0]); X exit(0); X } X else cout << form("[%g]\t** event %d (id %d) caused\n", X inst, event->type(), event->id()); X X switch ( event->type() ) { X case ARRIVAL : X cout << form("[%g]\tArrival\n", inst); X X ev = new Event(RESERVE); X cout << form("[%g]\tscheduling a RESERVE\n", inst); X customer.schedule(0, ev); X X ev = new Event(ARRIVAL); X delay = sample(); X cout << form("[%g]\tscheduling an ARRIVAL after %g\n", X inst, delay); X customer.schedule(delay, ev); X X break; X case RESERVE : X cout << form("[%g]\tReserve\n", inst); X if ( server.reserve(&customer, event->type()) ) { X ev = new Event(DEPART); X delay = sample(); X cout << form("[%g]\tscheduling a DEPART after %g\n", X inst, delay); X customer.schedule(delay, ev); X } X else X cout << form("[%g]\tserver busy now\n", inst); X break; X case DEPART : X cout << form("[%g]\tDepart\n", inst); X server.release(&customer); X break; X default : X cout << form("%s: invalid event %d detected\n", X argv[0], event->type()); X break; X } X X delete event; X } X X return 0; X} SHAR_EOF fi exit 0 # End of shell archive