SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
store.cc
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//! \file store.cc Store implementation
3//
4// Copyright (c) 1991-2018 Petr Peringer
5//
6// This library is licensed under GNU Library GPL. See the file COPYING.
7//
8
9//
10// implementation of store class (SOL-like)
11//
12
13////////////////////////////////////////////////////////////////////////////
14// interface
15//
16
17#include "simlib.h"
18#include "internal.h"
19
20#include <cstdio>
21
22
23////////////////////////////////////////////////////////////////////////////
24// implementation
25//
26
27namespace simlib3 {
28
30
31#define _OWNQ 0x01
32
33#define CHECKQUEUE(qptr) do { if (!qptr) SIMLIB_error(QueueRefError); }while(0)
34
35////////////////////////////////////////////////////////////////////////////
36// constructors
37//
39 _Qflag(_OWNQ),
40 capacity(1L),
41 used(0L),
42 Q(new Queue("Q"))
43{
44 Dprintf(("Store::Store()"));
45}
46
47Store::Store(unsigned long _capacity) :
48 _Qflag(_OWNQ),
49 capacity(_capacity),
50 used(0L),
51 Q(new Queue("Q"))
52{
53 Dprintf(("Store::Store(%lu)",_capacity));
54}
55
56Store::Store(const char * name, unsigned long _capacity) :
57 _Qflag(_OWNQ),
58 capacity(_capacity),
59 used(0L),
60 Q(new Queue("Q"))
61{
62 Dprintf(("Store::Store(\"%s\",%lu)",name,_capacity));
63 ::SetName(this,name);
64}
65
66Store::Store(unsigned long _capacity, Queue *queue) :
67 _Qflag(0),
68 capacity(_capacity),
69 used(0L),
70 Q(queue)
71{
72 CHECKQUEUE(queue);
73 Dprintf(("Store::Store(%lu,%s)",_capacity,queue->Name().c_str()));
74}
75
76Store::Store(const char *name, unsigned long _capacity, Queue *queue) :
77 _Qflag(0),
78 capacity(_capacity),
79 used(0L),
80 Q(queue)
81{
82 CHECKQUEUE(queue);
83 Dprintf(("Store::Store(\"%s\",%lu, Queue\"%s\")",
84 name, _capacity, queue->Name().c_str()));
85 ::SetName(this, name);
86}
87
88
89////////////////////////////////////////////////////////////////////////////
90// destructor
91//
93{
94 Dprintf(("Store::~Store() // \"%s\" ",Name().c_str()));
95 Clear();
96 if (OwnQueue()) delete Q;
97}
98
99////////////////////////////////////////////////////////////////////////////
100/// SetCapacity
101/// - change capacity of store
102void Store::SetCapacity(unsigned long newcapacity)
103{
104 if (capacity<newcapacity ||
105 (QueueLen()==0 && used<=newcapacity)
106 ) capacity = newcapacity;
108}
109
110////////////////////////////////////////////////////////////////////////////
111/// SetQueue
112/// - use another queue
114{
115 CHECKQUEUE(queue);
116 if (OwnQueue())
117 {
119 delete Q; // delete internal queue
120 _Qflag &= ~_OWNQ;
121 }
122 Q = queue;
123}
124
125////////////////////////////////////////////////////////////////////////////
126/// Enter
127/// - allocate requested capacity
128void Store::Enter(Entity *e, unsigned long rcap)
129{
130// TODO: remove parameter e, use Current
131 Dprintf(("%s.Enter(%s,%lu)",Name().c_str(),e->Name().c_str(),rcap));
132
133 if (e != Current)
134 SIMLIB_error(EntityRefError); // current process only
135
137 if (Free() < rcap) // not enough space in store
138 {
139 QueueIn(e,rcap); // isert into queue
140 e->Passivate(); // wait to activation from Leave()
141 // REACTIVATION
142 // FIXME: should be re-activated only from Leave() -- add checking?
143 return; // after activation is already allocated!
144 }
145 used += rcap; // allocate capacity
146 tstat(used); // update statistics
147}
148
149////////////////////////////////////////////////////////////////////////////
150/// Leave
151/// - free requested capacity
152void Store::Leave(unsigned long rcap)
153{
154 Dprintf(("%s.Leave(%lu)", Name().c_str(), rcap));
155 if (used<rcap)
157 used -= rcap ; // free capacity
158 tstat(used); tstat.n--; // fix: correction
159 if(Q->empty())
160 return;
161 // satisfy entities waiting in queue (starting from begin)
162 Queue::iterator pp = Q->begin(); // first item in queue
163 while( pp != Q->end() && !Full() ) {
164 Entity *p = ((Entity*)(*pp)); // FIXME: use dynamic_cast?
165 ++pp; // step forward (next action invalidates iterator)
166 if (p->_RequiredCapacity > Free())
167 continue; // skip if request can't be satisfied
168 p->Out(); // remove from queue
169 Dprintf(("%s.Enter(%s,%lu) from queue",
170 Name().c_str(), p->Name().c_str(), p->_RequiredCapacity));
171 used += p->_RequiredCapacity; // allocate capacity
172 tstat(used); // update statistics
173 p->Activate(); // reactivate now
174 // will go to Store::Enter REACTIVATION
175 } // while
176}
177
178////////////////////////////////////////////////////////////////////////////
179/// QueueIn
180/// - insert entity into priority queue
181void Store::QueueIn(Entity *e, unsigned long c)
182{
183 Dprintf(("%s --> input queue of %s ",e->Name().c_str(),Name().c_str()));
184 e->_RequiredCapacity = c; // mark requested capacity
185 Q->Insert(e); // insert
186}
187
188////////////////////////////////////////////////////////////////////////////
189/// Clear
190/// - store (re-)initialization, including internal queue
192{
193 Dprintf(("%s.Clear()", Name().c_str()));
194 used = 0; // empty store
195 // FIXME: clear unconditionally? (what to do for shared queue?)
196 if (OwnQueue()) Q->Clear(); // clear input queue if owned
197 tstat.Clear(); // clear store statistics
198}
199
200////////////////////////////////////////////////////////////////////////////
201/// OwnQueue
202/// - check if store owns internal queue
203bool Store::OwnQueue() const
204{
205 return (_Qflag & _OWNQ) != 0;
206}
207
208}
209
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
void Activate()
activate now
Definition: simlib.h:408
unsigned long _RequiredCapacity
Definition: simlib.h:391
virtual void Out() override
remove entity from queue
Definition: entity.cc:90
virtual void Passivate()
deactivation
Definition: entity.cc:68
bool empty()
Definition: simlib.h:676
priority queue
Definition: simlib.h:685
iterator end()
Definition: simlib.h:700
virtual void Insert(Entity *e)
Definition: queue.cc:50
iterator begin()
Definition: simlib.h:699
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
void SetQueue(Queue *queue)
change input queue
Definition: store.cc:113
void SetCapacity(unsigned long _capacity)
change the capacity
Definition: store.cc:102
unsigned char _Qflag
true if store is owner of input queue
Definition: simlib.h:786
bool Full() const
store is full
Definition: simlib.h:806
virtual void Leave(unsigned long rcap)
deallocate capacity
Definition: store.cc:152
unsigned long capacity
Capacity of store.
Definition: simlib.h:788
virtual void Enter(Entity *e, unsigned long rcap)
allocate capacity
Definition: store.cc:128
bool OwnQueue() const
OwnQueue.
Definition: store.cc:203
unsigned long Free() const
free capacity
Definition: simlib.h:803
TStat tstat
usage statistics
Definition: simlib.h:791
Queue * Q
input queue
Definition: simlib.h:790
unsigned QueueLen() const
Definition: simlib.h:809
virtual ~Store()
Definition: store.cc:92
virtual void Clear()
initialize
Definition: store.cc:191
unsigned long used
Currently used capacity.
Definition: simlib.h:789
virtual void QueueIn(Entity *e, unsigned long c)
insert entity into queue
Definition: store.cc:181
unsigned long n
Definition: simlib.h:601
virtual void Clear(double initval=0.0)
initialize
Definition: tstat.cc:83
@ LeaveManyError
Definition: errors.h:49
@ SetQueueError
Definition: errors.h:51
@ EnterCapError
Definition: errors.h:48
@ EntityRefError
Definition: errors.h:38
@ SetCapacityError
Definition: errors.h:50
#define CHECKQUEUE(qptr)
Definition: facility.cc:32
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
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
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.
#define _OWNQ
Definition: store.cc:31