SIMLIB/C++  3.07
barrier.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file barrier.cc Barrier synchronization
3 //
4 // Copyright (c) 1991-2007 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 //
10 // class Barrier implementation
11 //
12 // TODO add method to set activation order - FIFO/LIFO
13 
14 ////////////////////////////////////////////////////////////////////////////
15 // interface
16 //
17 
18 #include "simlib.h"
19 #include "internal.h"
20 
21 ////////////////////////////////////////////////////////////////////////////
22 // implementation
23 //
24 
25 namespace simlib3 {
26 
28 
29 ////////////////////////////////////////////////////////////////////////////
30 /// constructor
31 //
32 Barrier::Barrier(unsigned height):
33  waiting(0), n(0), maxn(height)
34 {
35  Dprintf(("Barrier::Barrier()"));
36  Init();
37 }
38 
39 ////////////////////////////////////////////////////////////////////////////
40 /// constructor with name parameter
41 //
42 Barrier::Barrier(const char *name, unsigned height):
43  waiting(0), n(0), maxn(height)
44 {
45  Dprintf(("Barrier::Barrier(\"%s\")", name));
46  SetName(name);
47  Init();
48 }
49 
50 
51 ////////////////////////////////////////////////////////////////////////////
52 /// destructor
53 //
55  Dprintf(("Barrier::~Barrier() // \"%s\" ", Name().c_str()));
56  delete[] waiting;
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////
60 /// enter the barrier
61 //
62 void Barrier::Enter(Entity * e) //TODO without parameter: use Current?
63 {
64  Dprintf(("Barrier\"%s\".Enter(%s)", Name().c_str(), e->Name().c_str()));
65  if (n < maxn - 1) { // all waiting processes
66  waiting[n++] = e;
67  e->Passivate();
68  } else { // last process which breaks barrier
69  Break();
70  Current->Activate(); // re-activation of last process - FIFO order
71  }
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////
75 /// Wait or break the barrier
76 /// returns: true for last process breaking the barrier, else false
77 //
79 {
80  Dprintf(("Barrier\"%s\".Wait() for %s", Name().c_str(), Current->Name().c_str()));
81  if (n < maxn - 1) { // all waiting processes
82  waiting[n++] = Current;
83  Current->Passivate();
84  return false;
85  } else { // last process which breaks barrier
86  Break();
87  Current->Activate(Time); // re-activation of last process - FIFO order
88  return true;
89  }
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////
93 /// Activate all processes waiting on the barrier
94 /// returns: number of activated entities
95 /// Warning: can be called only by process not already waiting on barrier
96 //
98  int ret = n;
99  if (n == 0) // nothing to do
100  return ret;
101  for (unsigned i = 0; i < n; i++) // FIFO order of activation
102  {
103  waiting[i]->Activate();
104  waiting[i] = 0;
105  }
106  n = 0;
107  return ret;
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////
111 /// Barrier initializtion
112 //
114  Dprintf(("%s.Init()", Name().c_str()));
115  if (maxn < 1)
116  Error("Barrier size less than 1");
117  waiting = new Entity *[maxn]; // allocation maxn-1 ???
118 // if(!waiting) SIMLIB_error(MemoryError); // if without exceptions
119  Clear();
120 }
121 
122 ////////////////////////////////////////////////////////////////////////////
123 /// Change the height of barrier
124 //
125 void Barrier::ChangeHeight(unsigned new_height) {
126  Dprintf(("%s.ChangeHeight(%u)", Name().c_str(), new_height));
127  if (new_height < n || new_height < 1)
128  Error("Barrier height can not be changed");
129  Entity **new_w = new Entity *[new_height]; // allocation
130 // if(!new_w) SIMLIB_error(MemoryError); // if compiled without exceptions
131  for (unsigned i = 0; i < n; i++) // copy
132  new_w[i] = waiting[i];
133  delete [] waiting; // free old array
134  waiting = new_w;
135  maxn = new_height; // new size
136  for (unsigned i = n; i < maxn; i++) // zero all non-used items
137  new_w[i] = 0;
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////
141 /// Barrier re-initializtion
142 /// TODO: what to do with currently waiting passive processes?
143 //
145  Dprintf(("%s.Clear()", Name().c_str()));
146  for (unsigned i = 0; i < maxn; i++)
147  waiting[i] = nullptr;
148  n = 0;
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////
152 /// Print barrier status
153 //
154 void Barrier::Output() const {
155  Print("Barrier: %s\n", Name().c_str());
156  for (unsigned i = 0; i < maxn; i++)
157  if (waiting[i])
158  Print("%3d: %s\n", i, waiting[i]->Name().c_str());
159  else
160  Print("%3d: empty\n", i);
161  Print("\n");
162 }
163 
164 } // namespace
165 
void ChangeHeight(unsigned new_maxn)
change size
Definition: barrier.cc:125
unsigned n
current number of waiting entities
Definition: simlib.h:1779
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
virtual void Enter(Entity *e)
wait for barrier break TODO: remove/rename
Definition: barrier.cc:62
virtual void Passivate()
deactivation
Definition: entity.cc:68
int Print(const char *fmt,...)
for Output methods, can be redirected
Definition: print.cc:92
Barrier(unsigned N)
constructor
Definition: barrier.cc:32
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
virtual void Output() const override
print status
Definition: barrier.cc:154
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 int Break()
activate all waiting entities
Definition: barrier.cc:97
const double & Time
model time (is NOT the block)
Definition: run.cc:48
void Error(const char *fmt,...)
print message and terminate program
Definition: print.cc:123
void Clear()
initialization
Definition: barrier.cc:144
virtual bool Wait()
wait for barrier break (Current)
Definition: barrier.cc:78
Internal header file for SIMLIB/C++.
unsigned maxn
barrier height/size
Definition: simlib.h:1780
Main SIMLIB/C++ interface.
virtual std::string Name() const
get object name
Definition: object.cc:134
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
Entity ** waiting
array of waiting entities (fixed size)
Definition: simlib.h:1778
void Activate()
activate now
Definition: simlib.h:408
#define Dprintf(f)
Definition: internal.h:100
void Init()
initialization
Definition: barrier.cc:113
virtual ~Barrier()
destructor
Definition: barrier.cc:54