SIMLIB/C++  3.07
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 
27 namespace 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 
47 Store::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 
56 Store::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 
66 Store::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 
76 Store::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
102 void 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
113 void Store::SetQueue(Queue *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
128 void 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
152 void 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
181 void 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
203 bool Store::OwnQueue() const
204 {
205  return (_Qflag & _OWNQ) != 0;
206 }
207 
208 }
209 
iterator begin()
Definition: simlib.h:699
void SetQueue(Queue *queue)
change input queue
Definition: store.cc:113
unsigned QueueLen() const
Definition: simlib.h:809
unsigned long _RequiredCapacity
Definition: simlib.h:391
virtual void Out() override
remove entity from queue
Definition: entity.cc:90
virtual void Clear()
initialize
Definition: store.cc:191
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
unsigned long n
Definition: simlib.h:601
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
bool Full() const
store is full
Definition: simlib.h:806
void Clear()
Definition: simlib.h:706
unsigned long used
Currently used capacity.
Definition: simlib.h:789
virtual void Passivate()
deactivation
Definition: entity.cc:68
unsigned char _Qflag
true if store is owner of input queue
Definition: simlib.h:786
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 ~Store()
Definition: store.cc:92
iterator end()
Definition: simlib.h:700
bool empty()
Definition: simlib.h:676
virtual void Enter(Entity *e, unsigned long rcap)
allocate capacity
Definition: store.cc:128
virtual void Leave(unsigned long rcap)
deallocate capacity
Definition: store.cc:152
TStat tstat
usage statistics
Definition: simlib.h:791
Internal header file for SIMLIB/C++.
Queue * Q
input queue
Definition: simlib.h:790
#define CHECKQUEUE(qptr)
Definition: store.cc:33
Main SIMLIB/C++ interface.
virtual std::string Name() const
get object name
Definition: object.cc:134
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
#define _OWNQ
Definition: store.cc:31
virtual void QueueIn(Entity *e, unsigned long c)
insert entity into queue
Definition: store.cc:181
void Activate()
activate now
Definition: simlib.h:408
#define Dprintf(f)
Definition: internal.h:100
priority queue
Definition: simlib.h:685
bool OwnQueue() const
OwnQueue.
Definition: store.cc:203
unsigned long capacity
Capacity of store.
Definition: simlib.h:788
unsigned long Free() const
free capacity
Definition: simlib.h:803
virtual void Insert(Entity *e)
Definition: queue.cc:50
virtual void Clear(double initval=0.0)
initialize
Definition: tstat.cc:83
void SetCapacity(unsigned long _capacity)
change the capacity
Definition: store.cc:102