SIMLIB/C++  3.07
facility.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file facility.cc Implementation of Facility
3 //
4 // Copyright (c) 1991-2006 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 //
10 // class Facility implementation
11 //
12 
13 ////////////////////////////////////////////////////////////////////////////
14 // interface
15 //
16 
17 #include "simlib.h"
18 #include "internal.h"
19 
20 
21 ////////////////////////////////////////////////////////////////////////////
22 // implementation
23 //
24 
25 namespace simlib3 {
26 
28 
29 // don't change!!!
30 #define _OWNQ1 0x01
31 
32 #define CHECKQUEUE(qptr) if (!qptr) SIMLIB_error(QueueRefError)
33 #define CHECKENTITY(fptr) if (!fptr) SIMLIB_error(EntityRefError)
34 
35 ////////////////////////////////////////////////////////////////////////////
36 // constructors
37 //
39 {
40  Dprintf(("Facility::Facility()"));
41  _Qflag = 0;
42  Q1 = new Queue("Q1");
43  _Qflag |= _OWNQ1;
44  Q2 = new Queue("Q2");
45  in = NULL;
46 }
47 
48 Facility::Facility(const char *name)
49 {
50  Dprintf(("Facility::Facility(\"%s\")", name));
51  SetName(name);
52  _Qflag = 0;
53  Q1 = new Queue("Q1");
54  _Qflag |= _OWNQ1;
55  Q2 = new Queue("Q2");
56  in = NULL;
57 }
58 
60 {
61  Dprintf(("Facility::Facility(%s)", queue->Name().c_str()));
62  _Qflag = 0;
63  CHECKQUEUE(queue);
64  Q1 = queue;
65  Q2 = new Queue("Q2");
66  in = NULL;
67 }
68 
69 Facility::Facility(const char *name, Queue * queue)
70 {
71  Dprintf(("Facility::Facility(\"%s\",%s)", name, queue->Name().c_str()));
72  SetName(name);
73  _Qflag = 0;
74  CHECKQUEUE(queue);
75  Q1 = queue;
76  Q2 = new Queue("Q2");
77  in = NULL;
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////
81 // destructor
82 //
84 {
85  Dprintf(("Facility::~Facility() // \"%s\" ", Name().c_str()));
86  Clear();
87  if (OwnQueue())
88  delete Q1; // delete input queue
89  delete Q2;
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////
93 // SetQueue
94 //
96 {
97  CHECKQUEUE(queue);
98  if (OwnQueue()) {
99  if (QueueLen() > 0)
101  delete Q1; // delete internal input queue
102  _Qflag &= ~_OWNQ1;
103  }
104  Q1 = queue;
105 }
106 ////////////////////////////////////////////////////////////////////////////
107 // Seize -- seize facility by entity e
108 //
109 // possible waiting in queue
110 //
112 {
113 //
114 // TODO: remove parameter e, use Current
115 //
116  Dprintf(("%s.Seize(%s,%u)", Name().c_str(), e->Name().c_str(), (unsigned) sp));
117  CHECKENTITY(e);
118  if (e != Current)
120  e->_SPrio = sp;
121  if (!Busy()) {
122  in = e; // seize by entity
123  tstat(1); // update statistics
124  return;
125  }
126  if (sp > in->_SPrio) { // special case: service interrupted
127  Dprintf((" service interrupt "));
128  if (in->Idle()) // currently serviced entity is not scheduled
130  // compute the remaining service time
132  QueueIn2(*in); // insert interrupted entity into queue2
133  in->Passivate(); // wait in queue2 =====================
134  in = e; // seize by entity
135  tstat(1); // update statistics
136  } else { // go into main queue
137  QueueIn(e, sp); // insert in priority queue
138  e->Passivate(); // wait in queue, activated by Release()
139  // =======================================================
140  // continue after activation
141  Dprintf(("%s.Seize(%s,%u) from Q1", Name().c_str(), e->Name().c_str(),
142  (unsigned) sp));
143  }
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////
147 // Release -- release fafility by entity e
148 //
149 // release causes Seize if queues not empty
150 //
152 {
153 //
154 // TODO: remove parameter e, use Current
155 //
156  Dprintf(("%s.Release(%s)", Name().c_str(), e->Name().c_str()));
157  CHECKENTITY(e);
158  if (!in)
159  SIMLIB_error(ReleaseNotSeized); // not seized
160  if (e != in)
161  SIMLIB_error(ReleaseError); // seized by other entity
162  in = NULL; // empty
163  tstat(0); // record
164  tstat.n--; // correction !!
165 
166  bool flag = false; // correction: 5.12.91, bool:1998/08/10
167  if (!(Q1->empty() || Q2->empty())) {
168  flag =
169  (static_cast<Entity *>(Q1->front())->_SPrio >
170  static_cast<Entity *>(Q2->front())->_SPrio);
171  }
172 
173  if (!flag && !Q2->empty()) // interrupt queue not empty
174  { // seize from interrupt queue...
175 // TODO: this is old implementation -- error in statistics, problems
176  Entity *ent;
177  ent = static_cast<Entity *>(Q2->GetFirst()); // remove from queue
178  Dprintf(("%s.Seize(%s,%u) from Q2",
179  Name().c_str(), ent->Name().c_str(), (unsigned) ent->_SPrio));
180  in = ent; // seize again
181  tstat(1);
182  tstat.n--; // correction !!!
183  ent->Activate(Time + ent->_RemainingTime); // schedule end of service
184  return;
185  }
186  if (!Q1->empty()) { // input queue not empty -- seize from Q1
187  Entity *ent;
188  ent = Q1->front(); // points to first entity in queue
189  ent->Out(); // remove from queue
190  in = ent; // seize by entity [should be here]
191  tstat(1); // update statistics
192  ent->Activate(); // activation of entity behavior
193  return;
194  }
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////
198 // QueueIn -- go into input queue
199 //
201 {
202 //
203 // TODO: remove parameter e, use Current ???
204 //
205  Dprintf((" %s --> Q1 of %s ", e->Name().c_str(), Name().c_str()));
206  CHECKENTITY(e);
207  e->_SPrio = sp;
208 #if 0 // _INS_FROM_BEGIN_SLOWER ?
209  Queue::iterator p = Q1->begin();
210  Queue::iterator end = Q1->end();
211  ServicePriority_t Sprio = e->_SPrio;
212  for (; p != end && static_cast<Entity *>(*p)->_SPrio > Sprio; // higher service priority first
213  ++p);
214  ServicePriority_t prio = e->Priority;
215  for (; p != end && static_cast<Entity *>(*p)->_SPrio == Sprio && static_cast<Entity *>(*p)->Priority >= prio; // higher priority first
216  ++p);
217 #else
218  Queue::iterator begin = Q1->begin();
219  Queue::iterator p = Q1->end();
220  ServicePriority_t Sprio = e->_SPrio;
221  while (p != begin) {
222  Queue::iterator q = p;
223  --p;
224  if (static_cast<Entity *>(*p)->_SPrio >= Sprio) { // higher service priority first
225  p = q;
226  break;
227  }
228  }
229  ServicePriority_t prio = e->Priority;
230  while (p != begin) {
231  Queue::iterator q = p;
232  --p;
233  if (static_cast<Entity *>(*p)->_SPrio > Sprio ||
234  static_cast<Entity *>(*p)->Priority >= prio) { // higher priority first
235  p = q;
236  break;
237  }
238  }
239 #endif
240  Q1->PredIns(e, p);
241 }
242 
243 ////////////////////////////////////////////////////////////////////////////
244 // go into interrupt queue
245 //
247 {
248  Dprintf((" %s --> Q2 of %s", e->Name().c_str(), Name().c_str()));
249  ServicePriority_t ps = e->_SPrio;
250  Queue::iterator p = Q2->begin();
251  for (; p != Q2->end()
252  && static_cast<Entity *>(*p)->_SPrio > ps; // higher service priority first
253  ++p) { /*empty*/ }
254  ServicePriority_t prio = e->Priority;
255  for (; p != Q2->end()
256  && static_cast<Entity *>(*p)->_SPrio == ps
257  && static_cast<Entity *>(*p)->Priority >= prio; // higher priority first
258  ++p) { /*empty*/ }
259  // next sorting -- _RestTime? FIXME ###
260  Q2->PredIns(e, p);
261 }
262 
263 ////////////////////////////////////////////////////////////////////////////
264 // initialization
265 //
267 {
268  Dprintf(("%s.Clear()", Name().c_str()));
269  // FIXME needs checking
270  // clean only own queues!
271  if (OwnQueue())
272  Q1->Clear();
273  Q2->Clear();
274  tstat.Clear();
275  in = NULL; // empty
276 }
277 
278 
279 ////////////////////////////////////////////////////////////////////////////
280 // have own queue?
281 //
282 bool Facility::OwnQueue() const
283 {
284  return (_Qflag & _OWNQ1) != 0;
285 }
286 
287 }
288 // end
289 
iterator begin()
Definition: simlib.h:699
virtual void Out() override
remove entity from queue
Definition: entity.cc:90
virtual void QueueIn2(Entity *e)
Definition: facility.cc:246
Queue * Q1
Input queue.
Definition: simlib.h:757
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
unsigned long n
Definition: simlib.h:601
unsigned char ServicePriority_t
Service priority (see Facility::Seize)
Definition: simlib.h:365
#define CHECKENTITY(fptr)
Definition: facility.cc:33
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
unsigned QueueLen() const
Definition: simlib.h:772
Priority_t Priority
priority of the entity (scheduling,queues)
Definition: simlib.h:399
void Clear()
Definition: simlib.h:706
bool OwnQueue() const
test for default queue
Definition: facility.cc:282
bool Busy() const
in service
Definition: simlib.h:770
void SetQueue(Queue *queue1)
change input queue
Definition: facility.cc:95
virtual void Passivate()
deactivation
Definition: entity.cc:68
virtual void Seize(Entity *e, ServicePriority_t sp=DEFAULT_PRIORITY)
Definition: facility.cc:111
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
void SIMLIB_warning(const enum _ErrEnum N)
print warning message and continue
Definition: error.cc:74
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
Entity *const & Current
pointer to active (now running) entity
Definition: run.cc:54
virtual void Clear()
initialize
Definition: facility.cc:266
const double & Time
model time (is NOT the block)
Definition: run.cc:48
static bool flag
Definition: waitunti.cc:89
virtual void Release(Entity *e)
Definition: facility.cc:151
double ActivationTime()
get activation time of entity - iff scheduled it is here, because Entity has no knowledge of calend...
Definition: calendar.cc:1358
unsigned char _Qflag
true if facility is owner of input queue
Definition: simlib.h:754
iterator end()
Definition: simlib.h:700
Entity * front()
Definition: simlib.h:701
bool empty()
Definition: simlib.h:676
Internal header file for SIMLIB/C++.
#define _OWNQ1
Definition: facility.cc:30
#define CHECKQUEUE(qptr)
Definition: facility.cc:32
Main SIMLIB/C++ interface.
virtual std::string Name() const
get object name
Definition: object.cc:134
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
bool Idle()
entity activation is not scheduled in calendar
Definition: simlib.h:412
double _RemainingTime
Definition: simlib.h:390
Queue * Q2
Interrupted requests queue.
Definition: simlib.h:758
virtual void QueueIn(Entity *e, ServicePriority_t sp)
Definition: facility.cc:200
void Activate()
activate now
Definition: simlib.h:408
virtual ~Facility()
Definition: facility.cc:83
Entity * GetFirst()
Definition: queue.cc:113
#define Dprintf(f)
Definition: internal.h:100
priority queue
Definition: simlib.h:685
ServicePriority_t _SPrio
priority of service in Facility
Definition: simlib.h:393
TStat tstat
usage statistics
Definition: simlib.h:759
void PredIns(Entity *e, iterator pos)
Definition: queue.cc:102
Entity * in
Entity currently in service.
Definition: simlib.h:756
virtual void Clear(double initval=0.0)
initialize
Definition: tstat.cc:83