SSim C++ API documentation (v. 1.5.0)

Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | Examples

ssim.h

Go to the documentation of this file.
00001 // -*-C++-*-
00002 //
00003 //  This file is part of the Siena Simulator, a simple discrete-event
00004 //  simulator used with the Siena project.  See
00005 //  http://www.cs.colorado.edu/serl/siena/
00006 //
00007 //  Author: Antonio Carzaniga <carzanig@cs.colorado.edu>
00008 //  See the file AUTHORS for full details. 
00009 //
00010 //  Copyright (C) 1998-2004 University of Colorado
00011 //
00012 //  This program is free software; you can redistribute it and/or
00013 //  modify it under the terms of the GNU General Public License
00014 //  as published by the Free Software Foundation; either version 2
00015 //  of the License, or (at your option) any later version.
00016 //
00017 //  This program is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU General Public License
00023 //  along with this program; if not, write to the Free Software
00024 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
00025 //  USA, or send email to serl@cs.colorado.edu.
00026 //
00027 //
00028 // $Id: ssim.h,v 1.13 2004/01/06 17:51:38 carzanig Exp $
00029 //
00030 #ifndef _ssim_h
00031 #define _ssim_h
00032 
00033 #include <vector>
00034 #include <map>
00035 
00036 using std::multimap;
00037 using std::map;
00038 using std::vector;
00039 
00060 namespace ssim {
00061 
00064 extern const char *     Version;
00065 
00068 typedef int             ProcessId;
00069 
00072 const ProcessId         NULL_PROCESSID = -1;
00073 
00088 typedef unsigned long   Time;
00089 
00092 const Time              INIT_TIME = 0;
00093 
00120 class Event {
00121  public:
00122                         Event();
00123     virtual             ~Event();
00124 
00125  private:
00126     mutable unsigned refcount;
00127     friend class Sim;
00128 };
00129 
00135 class Process {
00136  public:
00137     virtual             ~Process();
00138 
00147     virtual void        init(void);
00148 
00203     virtual void        process_event(const Event * msg);
00204 
00212     virtual void        stop(void);
00213 };
00214 
00221 class ProcessWithPId : public Process {
00222  public:
00234     ProcessId           activate();
00235 
00242     ProcessId           pid() const;
00243 
00244     ProcessWithPId();
00245 
00246  private:
00247     ProcessId process_id;
00248 };
00249 
00256 class Sim {
00257 public:
00267     static ProcessId    create_process(Process *);
00268 
00270     static int          stop_process(ProcessId);
00272     static void         stop_process();
00273 
00284     static void         clear();
00285 
00295     static void         self_signal_event(const Event *) throw();
00296 
00305     static void         self_signal_event(const Event *, Time delay) throw();
00306 
00319     static int          signal_event(ProcessId, const Event *) throw();
00331     static int          signal_event(ProcessId, const Event *, Time) throw();
00332 
00403     static void         advance_delay(Time);
00404     
00426     static ProcessId    this_process();
00427 
00445     static Time         clock();
00446     
00448     static void         run_simulation();
00450     static void         stop_simulation();
00451 
00464     static void         set_stop_time(Time t = INIT_TIME);
00465 
00466 private:
00471     static Time         current_time;
00473     static Time         stop_time;
00475     static ProcessId    current_process;
00477     static Time         current_delay;
00479     static bool         running;
00480 
00481     enum ActionType { A_Event, A_Init, A_Stop };
00482     
00483     struct Action {
00484         ActionType      type;
00485         ProcessId       pid;
00486         const Event *   event;
00487         
00488                         Action(ActionType, ProcessId);
00489                         Action(ActionType, ProcessId, const Event *);
00490 
00491                         Action(const Action &);
00492         Action &        operator = (const Action &);
00493     };
00494 
00495     typedef multimap<Time, Action>      ActionsTable;
00496     static ActionsTable                 actions;
00497 
00498     static void         schedule(const Action &, Time);
00499     static void         schedule_now(const Action &);
00500 
00501     struct PDescr {
00502         Process *       process;
00503         bool            terminated;
00504         Time            available_at;
00505 
00506         PDescr(Process * p);
00507     };
00508 
00509     typedef vector<PDescr> PsTable;
00510     static PsTable processes;
00511 };
00512 
00513 //
00514 // inline implementations
00515 //
00516 inline Event::Event(): refcount(0) {};
00517 inline Event::~Event() {};
00518 
00519 inline Process::~Process() {};
00520 
00521 inline void Process::init(void) {};
00522 inline void Process::stop(void) {};
00523 inline void Process::process_event(const Event *) {};
00524 
00525 inline Sim::PDescr::PDescr(Process * p)
00526     : process(p), terminated(false), available_at(INIT_TIME) {}
00527 
00528 inline Sim::Action::Action(ActionType i, ProcessId p, const Event *e)
00529     : type(i), pid(p), event(e) {}
00530 
00531 inline Sim::Action::Action(ActionType i, ProcessId p)
00532     : type(i), pid(p), event((Event*)0) {}
00533 
00534 inline Sim::Action::Action(const Action &a):
00535     type(a.type), pid(a.pid), event(a.event) {}
00536 
00537 inline Sim::Action & Sim::Action::operator = (const Action &a) {
00538     type = a.type; pid = a.pid; event = a.event;
00539     return *this;
00540 }
00541 
00542 inline void Sim::set_stop_time(Time t) {
00543     stop_time = t;
00544 }
00545 
00546 inline void Sim::stop_process() {
00547     schedule_now(Action(A_Stop, current_process)); 
00548 }
00549 
00550 inline int Sim::stop_process(ProcessId pid) {
00551     if (processes[pid].terminated) return -1;
00552     schedule_now(Action(A_Stop, pid)); 
00553     return 0;
00554 }
00555 
00556 inline void Sim::stop_simulation() {
00557     running = false;
00558 }
00559 
00560 inline void Sim::advance_delay(Time delay) {
00561     if (!running) return;
00562     current_delay += delay;
00563 }
00564 
00565 inline ProcessId Sim::this_process() {
00566     return current_process;
00567 }
00568 
00569 inline Time Sim::clock() {
00570     return current_time + current_delay;
00571 }
00572 
00573 inline void Sim::self_signal_event(const Event * e) throw() {
00574     schedule_now(Action(A_Event, current_process, e));
00575 }
00576 
00577 inline void Sim::self_signal_event(const Event * e, Time delay) throw() {
00578     schedule(Action(A_Event, current_process, e), delay);
00579 }
00580 
00581 inline int Sim::signal_event(ProcessId pid, const Event * e) throw() {
00582     PDescr & pd = processes[current_process];
00583     if (pd.terminated) return -1;
00584     if (pd.available_at <= clock()) {
00585         schedule_now(Action(A_Event, pid, e));
00586     }
00587     return 0;
00588 }
00589 
00590 inline int Sim::signal_event(ProcessId pid, const Event * e, Time d) throw() {
00591     PDescr & pd = processes[current_process];
00592     if (pd.terminated) return -1;
00593     if (pd.available_at <= clock() + d) {
00594         schedule(Action(A_Event, pid, e), d);
00595     }
00596     return 0;
00597 }
00598 
00599 inline void Sim::schedule(const Action & action, Time t) {
00600     if (action.event != 0) { action.event->refcount++; }
00601     actions.insert(ActionsTable::value_type(clock() + t, action));
00602 }
00603 
00604 inline void Sim::schedule_now(const Action & action) {
00605     if (action.event != 0) { action.event->refcount++; }
00606     actions.insert(actions.begin(), ActionsTable::value_type(clock(), action));
00607 }
00608 
00609 inline ProcessId ProcessWithPId::activate() {
00610     if (process_id == NULL_PROCESSID) {
00611         return process_id = Sim::create_process(this);
00612     } else {
00613         return NULL_PROCESSID;
00614     }
00615 }
00616 
00617 inline ProcessWithPId::ProcessWithPId(): process_id(NULL_PROCESSID) {};
00618 
00619 inline ProcessId ProcessWithPId::pid() const {
00620         return process_id;
00621 }
00622 
00623 }; // end namespace ssim
00624 
00625 #endif /* _ssim_h */
00626 

Copyright © 2002-2004 University of Colorado.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". This documentation is authored and maintained by Antonio Carzaniga