SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
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
25namespace 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
48Facility::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
69Facility::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()));
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//
283{
284 return (_Qflag & _OWNQ1) != 0;
285}
286
287}
288// end
289
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
bool Idle()
entity activation is not scheduled in calendar
Definition: simlib.h:412
void Activate()
activate now
Definition: simlib.h:408
Priority_t Priority
priority of the entity (scheduling,queues)
Definition: simlib.h:399
double ActivationTime()
get activation time of entity - iff scheduled it is here, because Entity has no knowledge of calend...
Definition: calendar.cc:1358
ServicePriority_t _SPrio
priority of service in Facility
Definition: simlib.h:393
virtual void Out() override
remove entity from queue
Definition: entity.cc:90
virtual void Passivate()
deactivation
Definition: entity.cc:68
double _RemainingTime
Definition: simlib.h:390
virtual ~Facility()
Definition: facility.cc:83
virtual void QueueIn2(Entity *e)
Definition: facility.cc:246
virtual void QueueIn(Entity *e, ServicePriority_t sp)
Definition: facility.cc:200
bool Busy() const
in service
Definition: simlib.h:770
virtual void Seize(Entity *e, ServicePriority_t sp=DEFAULT_PRIORITY)
Definition: facility.cc:111
virtual void Release(Entity *e)
Definition: facility.cc:151
unsigned char _Qflag
true if facility is owner of input queue
Definition: simlib.h:754
virtual void Clear()
initialize
Definition: facility.cc:266
TStat tstat
usage statistics
Definition: simlib.h:759
Queue * Q1
Input queue.
Definition: simlib.h:757
Queue * Q2
Interrupted requests queue.
Definition: simlib.h:758
Entity * in
Entity currently in service.
Definition: simlib.h:756
bool OwnQueue() const
test for default queue
Definition: facility.cc:282
void SetQueue(Queue *queue1)
change input queue
Definition: facility.cc:95
unsigned QueueLen() const
Definition: simlib.h:772
bool empty()
Definition: simlib.h:676
priority queue
Definition: simlib.h:685
iterator end()
Definition: simlib.h:700
Entity * GetFirst()
Definition: queue.cc:113
void PredIns(Entity *e, iterator pos)
Definition: queue.cc:102
iterator begin()
Definition: simlib.h:699
Entity * front()
Definition: simlib.h:701
void Clear()
Definition: simlib.h:706
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
virtual std::string Name() const
get object name
Definition: object.cc:134
unsigned long n
Definition: simlib.h:601
virtual void Clear(double initval=0.0)
initialize
Definition: tstat.cc:83
@ SetQueueError
Definition: errors.h:51
@ ReleaseError
Definition: errors.h:46
@ ReleaseNotSeized
Definition: errors.h:47
@ EntityRefError
Definition: errors.h:38
@ FacInterruptError
Definition: errors.h:45
#define CHECKENTITY(fptr)
Definition: facility.cc:33
#define CHECKQUEUE(qptr)
Definition: facility.cc:32
#define _OWNQ1
Definition: facility.cc:30
Internal header file for SIMLIB/C++.
#define Dprintf(f)
Definition: internal.h:100
Implementation of class CalendarList interface is static - using global functions in SQS namespace.
Definition: algloop.cc:32
const double & Time
model time (is NOT the block)
Definition: run.cc:48
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
static bool flag
Definition: waitunti.cc:89
unsigned char ServicePriority_t
Service priority (see Facility::Seize)
Definition: simlib.h:365
void SIMLIB_warning(const enum _ErrEnum N)
print warning message and continue
Definition: error.cc:74
Entity *const & Current
pointer to active (now running) entity
Definition: run.cc:54
Main SIMLIB/C++ interface.