MADARA  3.4.1
Barrier.cpp
Go to the documentation of this file.
1 
2 #include <sstream>
3 
4 #include "Barrier.h"
7 
9  const KnowledgeUpdateSettings& settings)
10  : BaseContainer("", settings), context_(0), id_(0), participants_(1),
11  last_failed_check_(0)
12 {
13 }
14 
17  : BaseContainer(name, settings),
18  context_(&(knowledge.get_context())),
19  id_(0),
20  participants_(1),
21  last_failed_check_(0)
22 {
24 }
25 
28  : BaseContainer(name, settings),
29  context_(knowledge.get_context()),
30  id_(0),
31  participants_(1),
32  last_failed_check_(0)
33 {
35 }
36 
38  KnowledgeBase& knowledge, int id, int participants,
39  const KnowledgeUpdateSettings& settings)
40  : BaseContainer(name, settings),
41  context_(&(knowledge.get_context())),
42  id_(id),
43  participants_(participants),
44  last_failed_check_(0)
45 {
47 }
48 
50  Variables& knowledge, int id, int participants,
51  const KnowledgeUpdateSettings& settings)
52  : BaseContainer(name, settings),
53  context_(knowledge.get_context()),
54  id_(id),
55  participants_(participants),
56  last_failed_check_(0)
57 {
59 }
60 
62  : BaseContainer(rhs),
63  context_(rhs.context_),
64  id_(rhs.id_),
65  participants_(rhs.participants_),
66  last_failed_check_(rhs.last_failed_check_),
67  barrier_(rhs.barrier_)
68 {
69 }
70 
72 
74 {
75  if (this != &rhs)
76  {
77  MADARA_GUARD_TYPE guard(mutex_), guard2(rhs.mutex_);
78 
79  this->context_ = rhs.context_;
80  this->name_ = rhs.name_;
81  this->id_ = rhs.id_;
82  this->participants_ = rhs.participants_;
83  this->settings_ = rhs.settings_;
84  this->barrier_ = rhs.barrier_;
85  last_failed_check_ = rhs.last_failed_check_;
86  }
87 }
88 
90 {
91  if (context_ && name_ != "")
92  {
93  ContextGuard context_guard(*context_);
94  MADARA_GUARD_TYPE guard(mutex_);
95 
96  barrier_.resize(participants_);
97 
98  // add all other barrierer variables
99  for (size_t i = 0; i < participants_; ++i)
100  {
101  std::stringstream buffer;
102  buffer << name_;
103  buffer << ".";
104  buffer << i;
105 
106  barrier_[i].set_name(buffer.str(), *context_);
107  }
108 
109  barrier_[id_] = 0;
110  barrier_[id_].write();
111 
113  "Barrier::build_aggregate_barrier: built %d member barrier\n",
114  (int)participants_);
115  }
116  else if (name_ == "")
117  {
118  context_->print("ERROR: containers::Barrier needs a name.\n", 0);
119  }
120  else if (!context_)
121  {
123  logger::LOG_ERROR, "ERROR: containers::Barrier needs a context.\n");
124  }
125 }
126 
128 {
129  MADARA_GUARD_TYPE guard(mutex_);
130  return id_;
131 }
132 
134 {
135  MADARA_GUARD_TYPE guard(mutex_);
136  return participants_;
137 }
138 
140  const std::string& var_name, KnowledgeBase& knowledge, int id,
141  int participants)
142 {
143  KnowledgeUpdateSettings keep_local(true);
144  context_ = &(knowledge.get_context());
145 
146  ContextGuard context_guard(*context_);
147  MADARA_GUARD_TYPE guard(mutex_);
148 
149  name_ = var_name;
150  id_ = id;
151  participants_ = participants;
152  last_failed_check_ = 0;
153 
154  this->build_aggregate_barrier();
155 }
156 
158  const std::string& var_name, Variables& knowledge, int id, int participants)
159 {
160  KnowledgeUpdateSettings keep_local(true);
161  context_ = knowledge.get_context();
162 
163  ContextGuard context_guard(*context_);
164  MADARA_GUARD_TYPE guard(mutex_);
165 
166  name_ = var_name;
167  id_ = id;
168  participants_ = participants;
169  last_failed_check_ = 0;
170 
171  this->build_aggregate_barrier();
172 }
173 
175  const std::string& var_name, ThreadSafeContext& knowledge, int id,
176  int participants)
177 {
178  KnowledgeUpdateSettings keep_local(true);
179  context_ = &knowledge;
180 
181  ContextGuard context_guard(*context_);
182  MADARA_GUARD_TYPE guard(mutex_);
183 
184  name_ = var_name;
185  id_ = id;
186  participants_ = participants;
187  last_failed_check_ = 0;
188 
189  this->build_aggregate_barrier();
190 }
191 
193  size_t id, size_t participants)
194 {
195  if (context_)
196  {
197  ContextGuard context_guard(*context_);
198  MADARA_GUARD_TYPE guard(mutex_);
199 
200  id_ = id;
201  participants_ = participants;
202  last_failed_check_ = 0;
203 
204  this->build_aggregate_barrier();
205  }
206 }
207 
210 {
211  if (context_)
212  {
213  ContextGuard context_guard(*context_);
214  MADARA_GUARD_TYPE guard(mutex_);
215  // context_->set(variable_, value, settings_);
216  barrier_[id_] = value;
217 
218  last_failed_check_ = 0;
219  }
220 
221  return value;
222 }
223 
226 {
228 
229  if (context_)
230  {
231  result = *barrier_[id_];
232  }
233 
234  return result;
235 }
236 
239 {
241 
242  if (context_)
243  {
244  result = *barrier_[id_];
245  }
246 
247  return result;
248 }
249 
251 {
252  if (context_)
253  {
254  ++barrier_[id_];
255  last_failed_check_ = 0;
256  barrier_[id_].write();
257  }
258 }
259 
261 {
262  bool result = false;
263 
264  if (context_ && name_ != "")
265  {
266  ContextGuard context_guard(*context_);
267  MADARA_GUARD_TYPE guard(mutex_);
268 
270  "Barrier::is_done: checking barrier result for done\n");
271 
272  result = barrier_result() == 1;
273 
274  if (!result)
275  {
277  "Barrier::is_true: barrier is not true, remarking barrier "
278  "variable\n");
279 
280  barrier_[id_].write();
281 
283  }
284  else
285  {
287  "Barrier::is_true: barrier is true\n");
288  }
289  }
290 
291  return result;
292 }
293 
295 {
296  if (context_ && name_ != "")
297  {
298  barrier_[id_] = value;
299  }
300 }
301 
303 {
304  if (context_ && name_ != "")
305  {
306  barrier_[id_].write();
307  }
308 }
309 
311 {
312  std::stringstream result;
313 
314  result << "Barrier: ";
315 
316  // if at all possible, do not try to touch the KB with any locks
317  if (context_)
318  {
319  // note that because the variables are staged, we should only
320  for (size_t i = 0; i < participants_; ++i)
321  {
322  // we could speed this up by creating unsafe versions of functions like
323  // get name that do not lock the vars local mutex, but this should be
324  // reasonable
325  result << barrier_[i].get_name();
326  result << "={";
327  result << *barrier_[i];
328  result << "}\n";
329  }
330  }
331 
332  return result.str();
333 }
334 
336 {
337  modify();
338 }
339 
341 {
342  return get_debug_info();
343 }
344 
347 {
348  return new Barrier(*this);
349 }
350 
352 {
353  double result(0.0);
354 
355  if (context_)
356  {
357  result = barrier_[id_].to_double();
358  }
359 
360  return result;
361 }
362 
364 {
365  std::string result;
366 
367  if (context_)
368  {
369  result = barrier_[id_].to_string();
370  }
371 
372  return result;
373 }
374 
376  uint32_t quality, const KnowledgeReferenceSettings& settings)
377 {
378  if (context_)
379  {
380  barrier_[id_].set_quality(quality, settings);
381  }
382 }
383 
385 {
386  bool result(false);
387 
389  "Barrier::is_true: checking barrier result for truth\n");
390 
391  if (context_)
392  {
393  // this could be dangerous in that if someone changes barrier name in
394  // the middle of this, we're not thread safe. However, this is an
395  // optimization decision that is extremely performant in comparison.
396  // and it would be weird if someone wanted to change the barrier name
397  result = barrier_result() == 1;
398  }
399 
401  "Barrier::is_true: final result is %d\n", (int)result);
402 
403  return result;
404 }
405 
407 {
408  return !is_true();
409 }
410 
412 {
413  return is_true();
414 }
415 
417 {
418  return is_false();
419 }
#define madara_logger_log(loggering, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
const ThreadSafeContext * context_
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:24
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
This class encapsulates an entry in a KnowledgeBase.
Settings for applying knowledge updates.
Settings for applying knowledge updates.
This class stores variables and their values for use by any entity needing state information in a thr...
Provides an interface for external functions into the MADARA KaRL variable settings.
Definition: Variables.h:53
This class stores an integer within a variable context.
Definition: Barrier.h:33
knowledge::KnowledgeRecord to_record(void) const
Returns the barrier round number as a knowledge::KnowledgeRecord.
Definition: Barrier.cpp:225
size_t get_id(void) const
Returns the id of the barrier in the barrier ring.
Definition: Barrier.cpp:127
knowledge::KnowledgeRecord::Integer to_integer(void) const
Returns the barrier round number as an integer (same as *)
Definition: Barrier.cpp:238
bool is_false(void) const
Determines if the barrier is false.
Definition: Barrier.cpp:406
size_t get_participants(void) const
Returns the number of participants in the barrier ring.
Definition: Barrier.cpp:133
size_t last_failed_check_
id of this barrier in the barrier ring
Definition: Barrier.h:354
std::string to_string(void) const
Returns the barrier round number as a string.
Definition: Barrier.cpp:363
void resize(size_t id=0, size_t participants=1)
Resizes the barrier, usually when number of participants change.
Definition: Barrier.cpp:192
virtual bool is_false_(void) const
Polymorphic is false method which can be used to determine if at least one value in the container is ...
Definition: Barrier.cpp:416
double to_double(void) const
Returns the barrier round number as a double.
Definition: Barrier.cpp:351
knowledge::KnowledgeRecord::Integer type
trait that describes the value type
Definition: Barrier.h:36
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
Definition: Barrier.cpp:310
void set_quality(uint32_t quality, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Sets the quality of writing to the barrier variables.
Definition: Barrier.cpp:375
size_t participants_
the number of participants in the barrier ring
Definition: Barrier.h:349
void next(void)
Goes to the next barrier round.
Definition: Barrier.cpp:250
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true.
Definition: Barrier.cpp:411
std::vector< IntegerStaged > barrier_
Definition: Barrier.h:356
virtual void modify_(void)
Polymorphic modify method used by collection containers.
Definition: Barrier.cpp:335
size_t id_
id of this barrier in the barrier ring
Definition: Barrier.h:344
void set(type value)
Sets the barrier to a specific round.
Definition: Barrier.cpp:294
virtual BaseContainer * clone(void) const
Clones this container.
Definition: Barrier.cpp:346
void modify(void)
Mark the value as modified.
Definition: Barrier.cpp:302
Barrier(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Default constructor.
Definition: Barrier.cpp:8
void build_aggregate_barrier(void)
Builds the aggregate barrier logic.
Definition: Barrier.cpp:89
bool is_true(void) const
Determines if the barrier is true.
Definition: Barrier.cpp:384
bool is_done(void)
Wait for all other participants to reach your barrier round.
Definition: Barrier.cpp:260
void set_name(const std::string &var_name, KnowledgeBase &knowledge, int id, int participants)
Sets the variable name that this refers to.
Definition: Barrier.cpp:139
ThreadSafeContext * context_
Variable context that we are modifying.
Definition: Barrier.h:339
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
Definition: Barrier.cpp:340
void operator=(const Barrier &rhs)
Assignment operator.
Definition: Barrier.cpp:73
This class is an abstract base class for all containers.
Definition: BaseContainer.h:34
KnowledgeUpdateSettings settings_
Settings for modifications.
std::string name_
Prefix of variable.
MADARA_LOCK_TYPE mutex_
guard for access and changes
constexpr string_t string
Provides functions and classes for the distributed knowledge base.
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger