SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
waitunti.cc
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//! \file waitunti.cc Process::WaitUntil implementation
3//
4// Copyright (c) 1991-2004 Petr Peringer
5//
6// This library is licensed under GNU Library GPL. See the file COPYING.
7//
8
9//
10// class WaitUntilList --- not good implementation
11// (uses list of waiting processes, and checks conditions after each
12// activated event)
13// better implementation will use objects in WUexpressions
14//
15// 199808 updated: uses standard list<>
16
17////////////////////////////////////////////////////////////////////////////
18// interface
19//
20#include "simlib.h"
21#include "internal.h"
22#include <list>
23
24
25////////////////////////////////////////////////////////////////////////////
26// implementation
27//
28
29namespace simlib3 {
30
32
33////////////////////////////////////////////////////////////////////////////
34// class WaitUntilList --- singleton
35//
37 typedef std::list<Process *> container_t;
39 static WaitUntilList *instance; // unique list
40 public:
41 typedef container_t::iterator iterator;
42 static iterator begin() { return instance->l.begin(); }
43 static iterator end() { return instance->l.end(); }
44 static bool empty() { return instance->l.empty(); }
45 static void InsertCurrent(); // insert current process into list
46 static void GetCurrent(); // get current process
47 static void WU_hook(); // active: next process in WUlist or 0
48 static void Remove(Process *p) { // find and remove p
49 Dprintf(("WaitUntil::Remove(Process#%ld)", p->id()));
50 instance->l.remove(p); // should be in list
51 }
52 static void clear(); // empty
53 static void create() { // create single instance
54 if(instance==0) instance = new WaitUntilList;
55 else SIMLIB_internal_error(); // called twice
57 SIMLIB_atexit(destroy); // last SIMLIB module cleanup calls this
58 }
59 static void destroy() { // destroy single instance
60 clear(); // remove all contents
61 delete instance;
62 instance = 0;
63 }
64 private:
65 WaitUntilList() { Dprintf(("WaitUntilList::WaitUntilList()")); }
66 ~WaitUntilList() { Dprintf(("WaitUntilList::~WaitUntilList()")); }
67 // destructor never called ###???
69#ifndef NDEBUG
70 friend void WU_print();
71#endif
72};
73
74#ifndef NDEBUG
75 void WU_print() {
76 _Print("WaitUntilList:\n");
77 if(WaitUntilList::instance == 0) { _Print("none\n"); return; }
79 for( int n=0 ; i!=WaitUntilList::end() ; ++i, ++n )
80 _Print(" [%d] Process#%ld\n", n, (*i)->id() );
81 }
82#endif
83
84// WaitUntilList single instance
87
88////////////////////////////////////////////////////////////////////////////
89static bool flag = false; // valid iterator in WUList
90////////////////////////////////////////////////////////////////////////////
91// main WUlist interface function
92void WaitUntilList::WU_hook() { // get ptr to next process in WUlist or 0
93 Dprintf(("WaitUntilList::WU_hook"));
94 // PRECONDITION: WUList not empty
95 if(WaitUntilList::empty()) // this should never happen
97
98 if(!flag) { // start processing, (first call or after remove)
99 current = WaitUntilList::begin(); // reset to first process
100 flag = true;
101 // loop_count++;
102 // if(loop_count>LIMIT) error("waituntil-loop");
103 SIMLIB_Current = *current; // always OK
104 return;
105 }
106 ++current; // next waiting process
107 if( current != WaitUntilList::end() ) { // not end
109 return;
110 }
111 flag = false; // no next process --- end of WaitUntil processing
112 // loop_count = 0;
113 SIMLIB_Current = 0; // not needed ???###
114 return;
115}
116
117////////////////////////////////////////////////////////////////////////////
118// Process::
119////////////////////////////////////////////////////////////////////////////
120// _WaitUntil --- wait to condition
121// this is hidden by macro WaitUntil(b), useable in Process::Behavior
122//
123bool Process::_WaitUntil(bool test)
124{
125 Dprintf(("Process#%ld._WaitUntil(%s)", id(), test?"true":"false" ));
126 if(test) { // true --- end of wait
127 WaitUntilList::GetCurrent(); // ***** remove from WUList
128 _wait_until = false; // not in WUlist
129 return false; // continue checking WaitUntil condition
130 } else { // false --- wait
132 WaitUntilList::InsertCurrent(); // ***** insert into WUList
133 _wait_until = true; // is in WUlist
134 Passivate(); // deactivation = wait
135 return true; // repeat test (after activation)
136 }
137}
138
139////////////////////////////////////////////////////////////////////////////
140// _WaitUntilRemove() --- remove process from WUlist (called from destructor)
141//
143 if(_wait_until)
145 _wait_until = false; // is not in WUlist
146}
147
148
149////////////////////////////////////////////////////////////////////////////
150// InsertCurrent --- insert current process reference into WUlist
151// (only called from Process::_WaitUntil)
152//
154{
155 if(flag) return; // is in WUlist
156 //CONDITION: current process is not in WUlist
157 Process *e = static_cast<Process*>(SIMLIB_Current); // TODO: dynamic_cast ?
158 Dprintf(("WaitUntilList.Insert(Process#%ld)", e->id()));
159 if(instance==0)
160 create(); // create singleton instance
161 if(empty()) // it was empty (FIXME: why not at creation time?)
162 INSTALL_HOOK(WUget_next, WaitUntilList::WU_hook); // install hook
163 iterator pos;
164 for( pos = begin(); // find place from beginning
165 pos != end() && (*pos)->Priority >= e->Priority; // higher first
166 ++pos ) { /*empty*/ }
167 instance->l.insert(pos,e); // insert at position
168 //e->_wait_until = true; // mark process as inserted
169}
170
171////////////////////////////////////////////////////////////////////////////
172// GetCurrent --- get selected process from WUlist
173// (called from Process::* )
174//
176{
177 if(!flag) return; // process is not in WUlist
178 //PRECONDITION: WUlist is initialized, not empty
179 Process *p = *current;
180 Dprintf(("WaitUntilList.Get(); // \"Process#%ld\" ", p->id()));
181 instance->l.erase(current); // remove item pointed by iterator (fast)
182 if(empty())
183 INSTALL_HOOK(WUget_next, 0); // uninstall hook if last item removed
184 flag = false; // iterator invalid, start from beginning
185}
186
187////////////////////////////////////////////////////////////////////////////
188// clear --- remove all records (called from Init())
189//
191{
192 if(instance==0) return;
193 // remove all processes in WaitUntilList
194 // we can do this, because all processes in list are passivated
195 iterator i=begin();
196 while(i!=end()) { // destroy all processes in WUlist
197 Process *p = *i;
198 ++i;
199 p->_WaitUntilRemove(); // unmark and remove process
200 if( p->isAllocated() ) delete p; // the same behavior as Calendar###???
201 }
202 if(!instance->l.empty())
203 SIMLIB_internal_error(); // for sure
204 INSTALL_HOOK(WUget_next, 0); // uninstall hook if empty
205}
206
207
208} // end
209
unsigned long id() const
Definition: simlib.h:396
Priority_t Priority
priority of the entity (scheduling,queues)
Definition: simlib.h:399
Abstract base class for all simulation processesProcess behavior is specified by Behavior method and ...
Definition: simlib.h:440
bool _WaitUntil(bool test)
wait for condition (slow!)
Definition: waitunti.cc:123
void _WaitUntilRemove()
Definition: waitunti.cc:142
virtual void Passivate() override
process deactivation (sleep)
Definition: process.cc:314
bool _wait_until
Definition: simlib.h:454
bool isAllocated() const
Definition: simlib.h:318
static void clear()
Definition: waitunti.cc:190
static bool empty()
Definition: waitunti.cc:44
static void InsertCurrent()
Definition: waitunti.cc:153
container_t::iterator iterator
Definition: waitunti.cc:41
static iterator current
Definition: waitunti.cc:68
std::list< Process * > container_t
Definition: waitunti.cc:37
friend void WU_print()
Definition: waitunti.cc:75
static iterator end()
Definition: waitunti.cc:43
static void destroy()
Definition: waitunti.cc:59
static iterator begin()
Definition: waitunti.cc:42
static WaitUntilList * instance
Definition: waitunti.cc:39
static void GetCurrent()
Definition: waitunti.cc:175
static void Remove(Process *p)
Definition: waitunti.cc:48
static void WU_hook()
Definition: waitunti.cc:92
static void create()
Definition: waitunti.cc:53
Internal header file for SIMLIB/C++.
#define Dprintf(f)
Definition: internal.h:100
#define SIMLIB_internal_error()
Definition: internal.h:167
#define INSTALL_HOOK(name, function)
Definition: internal.h:255
Implementation of class CalendarList interface is static - using global functions in SQS namespace.
Definition: algloop.cc:32
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
Entity * SIMLIB_Current
Definition: run.cc:53
static bool flag
Definition: waitunti.cc:89
void SIMLIB_atexit(SIMLIB_atexit_function_t p)
Definition: atexit.cc:26
int _Print(const char *fmt,...)
output of messages to stdout, too
Definition: print.cc:68
void WU_print()
Definition: waitunti.cc:75
Main SIMLIB/C++ interface.