v14i069: SILO: An event-based simulation platform
S Manoharan
sam at lfcs.ed.ac.uk
Thu Aug 30 08:48:05 AEST 1990
Posting-number: Volume 14, Issue 69
Submitted-by: sam at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at lfcs.edinburgh.ac.uk */
X
X/* Reference --
X at 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
More information about the Comp.sources.misc
mailing list