Fawkes API  Fawkes Development Version
syncpoint.cpp
1 /***************************************************************************
2  * syncpoint.cpp - Fawkes SyncPoint
3  *
4  * Created: Thu Jan 09 12:35:57 2014
5  * Copyright 2014-2018 Till Hofmann
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include <core/threading/mutex_locker.h>
23 #include <syncpoint/exceptions.h>
24 #include <syncpoint/syncpoint.h>
25 #include <utils/time/time.h>
26 
27 #include <pthread.h>
28 #include <string.h>
29 
30 using namespace std;
31 
32 namespace fawkes {
33 
34 /** @class SyncPoint <syncpoint/syncpoint.h>
35  * The SyncPoint class.
36  * This class is used for dynamic synchronization of threads which depend
37  * on each other, e.g. threads which are part of a processing chain.
38  *
39  * As an example, thread E generates data which is needed by thread W.
40  * Therefore, both threads share a SyncPoint.
41  * Thread W wait()s for the SyncPoint to be emitted.
42  * Once thread E is done, it emit()s the SyncPoint, which wakes up thread W.
43  *
44  * @author Till Hofmann
45  * @see SyncPointManager
46  */
47 
48 /** Constructor.
49  * @param identifier The identifier of the SyncPoint. This must be in absolute
50  * path style, e.g. '/some/syncpoint'.
51  * @param logger The logger to use for error messages.
52  * @param max_waittime_sec the maximum number of seconds to wait until a timeout
53  * is triggered
54  * @param max_waittime_nsec the maximum number of nanoseconds to wait until a
55  * timeout is triggered
56  */
57 SyncPoint::SyncPoint(string identifier,
58  MultiLogger *logger,
59  uint max_waittime_sec /* = 0 */,
60  uint max_waittime_nsec /* = 0 */)
61 : identifier_(identifier),
62  emit_calls_(CircularBuffer<SyncPointCall>(1000)),
63  wait_for_one_calls_(CircularBuffer<SyncPointCall>(1000)),
64  wait_for_all_calls_(CircularBuffer<SyncPointCall>(1000)),
65  creation_time_(Time()),
66  mutex_(new Mutex()),
67  mutex_next_wait_(new Mutex()),
68  cond_next_wait_(new WaitCondition(mutex_next_wait_)),
69  mutex_wait_for_one_(new Mutex()),
70  cond_wait_for_one_(new WaitCondition(mutex_wait_for_one_)),
71  mutex_wait_for_all_(new Mutex()),
72  cond_wait_for_all_(new WaitCondition(mutex_wait_for_all_)),
73  wait_for_all_timer_running_(false),
74  max_waittime_sec_(max_waittime_sec),
75  max_waittime_nsec_(max_waittime_nsec),
76  logger_(logger),
77  last_emitter_reset_(Time(0l))
78 {
79  if (identifier.empty()) {
80  cleanup();
81  throw SyncPointInvalidIdentifierException(identifier.c_str());
82  }
83  if (identifier.compare(0, 1, "/")) {
84  cleanup();
85  throw SyncPointInvalidIdentifierException(identifier.c_str());
86  }
87  // check if last charater is '/'
88  // The identifier may only end in '/' if '/' is the complete identifier.
89  // '/' is allowed, '/some/' is not allowed
90  if (identifier != "/" && !identifier.compare(identifier.size() - 1, 1, "/")) {
91  cleanup();
92  throw SyncPointInvalidIdentifierException(identifier.c_str());
93  }
94 }
95 
96 SyncPoint::~SyncPoint()
97 {
98  cleanup();
99 }
100 
101 /**
102  * @return the identifier of the SyncPoint
103  */
104 string
106 {
107  return identifier_;
108 }
109 
110 /** EqualOperator.
111  * Two SyncPoints are considered equal iff they have the same identifier
112  * @param other The other SyncPoint
113  * @return true if the identifiers of the SyncPoints are equal
114  */
115 bool
116 SyncPoint::operator==(const SyncPoint &other) const
117 {
118  return identifier_ == other.get_identifier();
119 }
120 
121 /** EqualOperator.
122  * A SyncPoint is equal to a given string iff the string is equal to the
123  * SyncPoint's identifier.
124  * @param other the string to compare
125  * @return true if the identifier of the SyncPoint matches the given string
126  */
127 bool
128 SyncPoint::operator==(const string &other) const
129 {
130  return identifier_ == other;
131 }
132 
133 /** LessThan Operator.
134  * Compare two SyncPoints using their identifiers.
135  * @param other The other SyncPoint
136  * @return true if strcmp returns a value < 0 for the identifiers
137  */
138 bool
139 SyncPoint::operator<(const SyncPoint &other) const
140 {
141  return identifier_ < other.get_identifier();
142 }
143 
144 /** Wake up all components which are waiting for this SyncPoint
145  * @param component The identifier of the component emitting the SyncPoint
146  */
147 void
148 SyncPoint::emit(const std::string &component)
149 {
150  emit(component, true);
151 }
152 
153 /** Wake up all components which are waiting for this SyncPoint
154  * @param component The identifier of the component emitting the SyncPoint
155  * @param remove_from_pending if set to true, the component will be removed
156  * from the pending emitters for this syncpoint
157  */
158 void
159 SyncPoint::emit(const std::string &component, bool remove_from_pending)
160 {
162  if (!emit_locker_.empty()) {
164  }
166  MutexLocker ml(mutex_);
167  if (!watchers_.count(component)) {
168  throw SyncPointNonWatcherCalledEmitException(component.c_str(), get_identifier().c_str());
169  }
170 
171  // unlock all wait_for_one waiters
172  watchers_wait_for_one_.clear();
176 
177  if (!emitters_.count(component)) {
178  throw SyncPointNonEmitterCalledEmitException(component.c_str(), get_identifier().c_str());
179  }
180 
181  /* 1. remember whether the component was pending; if so, it may be removed
182  * from the pending components of the predecessor. Otherwise, it should
183  * not be removed
184  * 2. only erase the component once; it may be registered multiple times
185  */
186  bool pred_remove_from_pending = false;
187  if (remove_from_pending) {
188  multiset<string>::iterator it_pending = pending_emitters_.find(component);
189  if (it_pending != pending_emitters_.end()) {
190  pending_emitters_.erase(it_pending);
191  if (predecessor_) {
192  if (last_emitter_reset_ <= predecessor_->last_emitter_reset_) {
193  pred_remove_from_pending = true;
194  }
195  }
196 
197  // unlock all wait_for_all waiters if all pending emitters have emitted
198  if (pending_emitters_.empty()) {
199  watchers_wait_for_all_.clear();
203  reset_emitters();
204  }
205  }
206  }
207 
208  emit_calls_.push_back(SyncPointCall(component));
209 
210  if (predecessor_) {
211  predecessor_->emit(component, pred_remove_from_pending);
212  }
213 }
214 
215 /** Wait until SyncPoint is emitted.
216  * Either wait until a single emitter has emitted the SyncPoint, or wait
217  * until all registered emitters have emitted the SyncPoint.
218  * If wait_sec != 0 or wait_nsec !=0, then only wait for
219  * wait_sec + wait_nsec*10^-9 seconds and set the SyncPoint's maximum waiting
220  * time to the specified time (i.e., on any subsequent wait calls, wait for
221  * the specified time until a timeout is triggered).
222  * If the maximal wait time has been exceeded, a warning is shown and the
223  * SyncPoint is released.
224  * If the WakeupType is WAIT_FOR_ALL, then the time limit is only used if there
225  * is currently no other component waiting in WAIT_FOR_ALL mode. If there is
226  * already a component waiting, that component's wait_time is used to compute
227  * the timeout. This ensures that in case a timeout occurs, all waiting
228  * components in WAIT_FOR_ALL mode are released simultaneously. Components in
229  * WAIT_FOR_ONE mode are treated separately and have their own timeouts.
230  * @param component The identifier of the component waiting for the SyncPoint
231  * @param type the wakeup type. If this is set to WAIT_FOR_ONE, wait returns
232  * when a single emitter has emitted the SyncPoint. If set to WAIT_FOR_ALL, wait
233  * until all registered emitters have emitted the SyncPoint.
234  * @param wait_sec number of seconds to wait for the SyncPoint
235  * @param wait_nsec number of nanoseconds to wait for the SyncPoint
236  * @see SyncPoint::WakeupType
237  */
238 void
239 SyncPoint::wait(const std::string &component,
240  WakeupType type /* = WAIT_FOR_ONE */,
241  uint wait_sec /* = 0 */,
242  uint wait_nsec /* = 0 */)
243 {
244  MutexLocker ml(mutex_);
245 
246  std::set<std::string> * watchers;
247  WaitCondition * cond;
249  Mutex * mutex_cond;
250  bool * timer_running;
251  string * timer_owner;
252  // set watchers, cond and calls depending of the Wakeup type
253  if (type == WAIT_FOR_ONE) {
254  watchers = &watchers_wait_for_one_;
255  cond = cond_wait_for_one_;
256  mutex_cond = mutex_wait_for_one_;
257  calls = &wait_for_one_calls_;
258  timer_running = NULL;
259  } else if (type == WAIT_FOR_ALL) {
260  watchers = &watchers_wait_for_all_;
261  cond = cond_wait_for_all_;
262  mutex_cond = mutex_wait_for_all_;
263  timer_running = &wait_for_all_timer_running_;
264  timer_owner = &wait_for_all_timer_owner_;
265  calls = &wait_for_all_calls_;
266  } else {
268  }
269 
270  Time start;
271  mutex_cond->lock();
272 
273  // check if calling component is registered for this SyncPoint
274  if (!watchers_.count(component)) {
275  mutex_cond->unlock();
276  throw SyncPointNonWatcherCalledWaitException(component.c_str(), get_identifier().c_str());
277  }
278  // check if calling component is not already waiting
279  if (watchers->count(component)) {
280  mutex_cond->unlock();
281  throw SyncPointMultipleWaitCallsException(component.c_str(), get_identifier().c_str());
282  }
283 
284  /* if type == WAIT_FOR_ALL but no emitter has registered, we can
285  * immediately return
286  * if type == WAIT_FOR_ONE, we always wait
287  */
288  bool need_to_wait = !emitters_.empty() || type == WAIT_FOR_ONE;
289  if (need_to_wait) {
290  watchers->insert(component);
291  }
292 
294  if (emit_locker_ == component) {
295  emit_locker_ = "";
297  }
299  if (need_to_wait) {
300  if (type == WAIT_FOR_ONE) {
301  ml.unlock();
302  bool timeout;
303  pthread_cleanup_push(cleanup_mutex, mutex_cond);
304  timeout = !cond->reltimed_wait(wait_sec, wait_nsec);
305  pthread_cleanup_pop(1);
306  if (timeout) {
307  ml.relock();
308  handle_default(component, type);
309  ml.unlock();
310  }
311  } else {
312  if (*timer_running) {
313  ml.unlock();
314  pthread_cleanup_push(cleanup_mutex, mutex_cond);
315  cond->wait();
316  pthread_cleanup_pop(1);
317  } else {
318  *timer_running = true;
319  *timer_owner = component;
320  if (wait_sec != 0 || wait_nsec != 0) {
321  max_waittime_sec_ = wait_sec;
322  max_waittime_nsec_ = wait_nsec;
323  }
324  ml.unlock();
325  bool timeout;
326  pthread_cleanup_push(cleanup_mutex, mutex_cond);
328  pthread_cleanup_pop(1);
329  ml.relock();
330  *timer_running = false;
331  if (timeout) {
332  // wait failed, handle default
333  handle_default(component, type);
334  mutex_cond->lock();
335  cond->wake_all();
336  mutex_cond->unlock();
337  }
338  ml.unlock();
339  }
340  }
341  } else {
342  ml.unlock();
343  mutex_cond->unlock();
344  }
345  Time wait_time = Time() - start;
346  ml.relock();
347  calls->push_back(SyncPointCall(component, start, wait_time));
348 }
349 
350 /** Wait for a single emitter.
351  * @param component The identifier of the calling component.
352  */
353 void
354 SyncPoint::wait_for_one(const string &component)
355 {
356  wait(component, WAIT_FOR_ONE);
357 }
358 
359 /** Wait for all registered emitters.
360  * @param component The identifier of the calling component.
361  */
362 void
363 SyncPoint::wait_for_all(const string &component)
364 {
365  wait(component, WAIT_FOR_ALL);
366 }
367 
368 /** Wait for a single emitter for the given time.
369  * @param component The identifier of the calling component.
370  * @param wait_sec number of seconds to wait
371  * @param wait_nsec number of nanoseconds to wait additionally to wait_sec
372  */
373 void
374 SyncPoint::reltime_wait_for_one(const string &component, uint wait_sec, uint wait_nsec)
375 {
376  wait(component, SyncPoint::WAIT_FOR_ONE, wait_sec, wait_nsec);
377 }
378 
379 /** Wait for all registered emitters for the given time.
380  * @param component The identifier of the calling component.
381  * @param wait_sec number of seconds to wait
382  * @param wait_nsec number of nanoseconds to wait additionally to wait_sec
383  */
384 void
385 SyncPoint::reltime_wait_for_all(const string &component, uint wait_sec, uint wait_nsec)
386 {
387  wait(component, SyncPoint::WAIT_FOR_ALL, wait_sec, wait_nsec);
388 }
389 
390 /** Do not wait for the SyncPoint any longer.
391  * Removes the component from the list of waiters. If the given component is
392  * not waiting, do nothing.
393  * @param component the component to remove from the waiters
394  */
395 void
396 SyncPoint::unwait(const string &component)
397 {
398  MutexLocker ml(mutex_);
399  watchers_wait_for_one_.erase(component);
400  watchers_wait_for_all_.erase(component);
401  if (wait_for_all_timer_owner_ == component) {
402  // TODO: this lets the other waiting components wait indefinitely, even on
403  // a timed wait.
405  }
406 }
407 
408 /** Lock the SyncPoint for emitters until the specified component does the next
409  * wait() call. This forces an emitter of this SyncPoint to wait during the
410  * emit until the waiter calls wait(). This is useful if you want to guarantee
411  * that the waiter does not call wait() immediately after the emitter has
412  * called emit().
413  * @param component the component locking the SyncPoint
414  */
415 void
416 SyncPoint::lock_until_next_wait(const string &component)
417 {
418  MutexLocker ml(mutex_);
420  if (emit_locker_.empty()) {
421  emit_locker_ = component;
422  } else {
423  logger_->log_warn("SyncPoints",
424  "%s tried to call lock_until_next_wait, "
425  "but %s already did the same. Ignoring.",
426  component.c_str(),
427  emit_locker_.c_str());
428  }
430 }
431 
432 /** Register an emitter. A thread can only emit the barrier if it has been
433  * registered.
434  * @param component The identifier of the registering component.
435  */
436 void
437 SyncPoint::register_emitter(const string &component)
438 {
439  MutexLocker ml(mutex_);
440  emitters_.insert(component);
441  pending_emitters_.insert(component);
442  if (predecessor_) {
443  predecessor_->register_emitter(component);
444  }
445 }
446 
447 /** Unregister an emitter. This removes the component from the syncpoint, thus
448  * other components will not wait for it anymore.
449  * @param component The identifier of the component which is unregistered.
450  * @param emit_if_pending if this is set to true and the component is a
451  * pending emitter, emit the syncpoint before releasing it.
452  */
453 void
454 SyncPoint::unregister_emitter(const string &component, bool emit_if_pending)
455 {
456  // TODO should this throw if the calling component is not registered?
457  multiset<string>::iterator it_emitter = emitters_.find(component);
458  if (it_emitter == emitters_.end()) {
459  // component is not an emitter
460  return;
461  }
462  MutexLocker ml(mutex_);
463  if (emit_if_pending && is_pending(component)) {
464  ml.unlock();
465  emit(component);
466  ml.relock();
467  }
468 
469  // erase a single element from the set of emitters
470  emitters_.erase(it_emitter);
471  if (predecessor_) {
472  // never emit the predecessor if it's pending; it is already emitted above
473  predecessor_->unregister_emitter(component, false);
474  }
475 }
476 
477 /** Check if the given component is an emitter.
478  * @param component The name of the component.
479  * @return True iff the given component is an emitter of this syncpoint.
480  */
481 bool
482 SyncPoint::is_emitter(const string &component) const
483 {
484  MutexLocker ml(mutex_);
485  return emitters_.count(component) > 0;
486 }
487 
488 /** Check if the given component is a watch.
489  * @param component The name of the component.
490  * @return True iff the given component is a watcher.
491  */
492 bool
493 SyncPoint::is_watcher(const string &component) const
494 {
495  MutexLocker ml(mutex_);
496  return watchers_.count(component) > 0;
497 }
498 
499 /** Add a watcher to the watch list
500  * @param watcher the new watcher
501  * @return A pair, of which the first element is an iterator that points
502  * to the possibly inserted element, and the second is a bool
503  * that is true if the element was actually inserted.
504  */
505 pair<set<string>::iterator, bool>
506 SyncPoint::add_watcher(string watcher)
507 {
508  MutexLocker ml(mutex_);
509  return watchers_.insert(watcher);
510 }
511 
512 /**
513  * @return all watchers of the SyncPoint
514  */
515 std::set<std::string>
517 {
518  MutexLocker ml(mutex_);
519  return watchers_;
520 }
521 
522 /**
523  * @return a copy of the wait call buffer with the given type
524  * @param type the type of the wait call buffer
525  */
527 SyncPoint::get_wait_calls(WakeupType type /* = WAIT_FOR_ONE */) const
528 {
529  MutexLocker ml(mutex_);
530  if (type == WAIT_FOR_ONE) {
531  return wait_for_one_calls_;
532  } else if (type == WAIT_FOR_ALL) {
533  return wait_for_all_calls_;
534  } else {
536  }
537 }
538 
539 /**
540  * @return a copy of the set of registered emitters
541  */
542 multiset<string>
544 {
545  return emitters_;
546 }
547 
548 /**
549  * @return a copy of the emit call buffer
550  */
553 {
554  MutexLocker ml(mutex_);
555  return emit_calls_;
556 }
557 
558 /**
559  * Check if the given waiter is currently waiting with the given type
560  * @param watcher the string identifier of the watcher to check
561  * @param type the type of call to check
562  * @return true if the waiter is currently waiting
563  */
564 bool
565 SyncPoint::watcher_is_waiting(std::string watcher, WakeupType type) const
566 {
567  switch (type) {
568  case SyncPoint::WAIT_FOR_ONE: {
570  return watchers_wait_for_one_.count(watcher);
571  }
572  case SyncPoint::WAIT_FOR_ALL: {
574  return watchers_wait_for_all_.count(watcher);
575  }
576  default: throw Exception("Unknown watch type %u for syncpoint %s", type, identifier_.c_str());
577  }
578 }
579 
580 void
581 SyncPoint::reset_emitters()
582 {
583  last_emitter_reset_ = Time();
584  pending_emitters_ = emitters_;
585 }
586 
587 bool
588 SyncPoint::is_pending(string component)
589 {
590  return pending_emitters_.count(component) > 0;
591 }
592 
593 void
594 SyncPoint::handle_default(string component, WakeupType type)
595 {
596  logger_->log_warn(component.c_str(),
597  "Thread time limit exceeded while waiting for syncpoint '%s'. "
598  "Time limit: %f sec.",
599  get_identifier().c_str(),
600  max_waittime_sec_ + static_cast<float>(max_waittime_nsec_) / 1000000000.f);
601  bad_components_.insert(pending_emitters_.begin(), pending_emitters_.end());
602  if (bad_components_.size() > 1) {
603  string bad_components_string = "";
604  for (set<string>::const_iterator it = bad_components_.begin(); it != bad_components_.end();
605  it++) {
606  bad_components_string += " " + *it;
607  }
608  logger_->log_warn(component.c_str(), "bad components:%s", bad_components_string.c_str());
609  } else if (bad_components_.size() == 1) {
610  logger_->log_warn(component.c_str(), "bad component: %s", bad_components_.begin()->c_str());
611  } else if (type == SyncPoint::WAIT_FOR_ALL) {
612  throw Exception("SyncPoints: component %s defaulted, "
613  "but there is no pending emitter. This is probably a bug.",
614  component.c_str());
615  }
616 
617  watchers_wait_for_all_.erase(component);
618  watchers_wait_for_one_.erase(component);
619 }
620 
621 void
622 SyncPoint::cleanup()
623 {
624  delete cond_wait_for_one_;
625  delete mutex_wait_for_one_;
626  delete cond_wait_for_all_;
627  delete mutex_wait_for_all_;
628  delete mutex_next_wait_;
629  delete mutex_;
630 }
631 } // namespace fawkes
fawkes::Mutex::lock
void lock()
Lock this mutex.
Definition: mutex.cpp:87
fawkes::SyncPoint::WakeupType
WakeupType
Type to define when a thread wakes up after waiting for a SyncPoint.
Definition: syncpoint.h:56
fawkes::SyncPoint::mutex_next_wait_
Mutex * mutex_next_wait_
Mutex used to allow lock_until_next_wait.
Definition: syncpoint.h:133
fawkes::SyncPoint::watcher_is_waiting
bool watcher_is_waiting(std::string watcher, WakeupType type) const
Check if the given waiter is currently waiting with the given type.
Definition: syncpoint.cpp:565
fawkes::SyncPointNonWatcherCalledEmitException
Emit was called by a component which isn't in the watcher set (or wrong component argument was passed...
Definition: exceptions.h:52
fawkes::SyncPointInvalidIdentifierException
Invalid identifier used (i.e.
Definition: exceptions.h:122
fawkes::SyncPoint::unwait
virtual void unwait(const std::string &component)
abort waiting
Definition: syncpoint.cpp:396
fawkes::SyncPoint::add_watcher
std::pair< std::set< std::string >::iterator, bool > add_watcher(std::string watcher)
Add a watcher to the watch list.
Definition: syncpoint.cpp:506
fawkes::Mutex
Mutex mutual exclusion lock.
Definition: mutex.h:33
fawkes::SyncPoint::get_watchers
std::set< std::string > get_watchers() const
Definition: syncpoint.cpp:516
fawkes::SyncPoint::emit
virtual void emit(const std::string &component)
send a signal to all waiting threads
Definition: syncpoint.cpp:148
fawkes::SyncPoint::cond_wait_for_one_
WaitCondition * cond_wait_for_one_
WaitCondition which is used for wait_for_one()
Definition: syncpoint.h:139
fawkes::CircularBuffer::push_back
void push_back(const Type &val)
Insert an element at the end of the buffer and delete the first element if necessary.
Definition: circular_buffer.h:90
fawkes::SyncPoint::wait_for_all_timer_running_
bool wait_for_all_timer_running_
true if the wait for all timer is running
Definition: syncpoint.h:145
fawkes::SyncPoint::max_waittime_nsec_
uint max_waittime_nsec_
maximum waiting time in nsecs
Definition: syncpoint.h:151
fawkes::MultiLogger
Log through multiple loggers.
Definition: multi.h:35
fawkes::WaitCondition
Wait until a given condition holds.
Definition: wait_condition.h:37
fawkes::SyncPoint
The SyncPoint class.
Definition: syncpoint.h:50
fawkes::SyncPoint::watchers_
std::set< std::string > watchers_
Set of all components which use this SyncPoint.
Definition: syncpoint.h:115
fawkes::SyncPoint::mutex_wait_for_one_
Mutex * mutex_wait_for_one_
Mutex used for cond_wait_for_one_.
Definition: syncpoint.h:137
fawkes::SyncPoint::reltime_wait_for_all
virtual void reltime_wait_for_all(const std::string &component, uint wait_sec, uint wait_nsec)
Wait for all registered emitters for the given time.
Definition: syncpoint.cpp:385
fawkes::SyncPoint::get_wait_calls
CircularBuffer< SyncPointCall > get_wait_calls(WakeupType type=WAIT_FOR_ONE) const
Definition: syncpoint.cpp:527
fawkes::SyncPoint::watchers_wait_for_all_
std::set< std::string > watchers_wait_for_all_
Set of all components which are currently waiting on the barrier.
Definition: syncpoint.h:119
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
fawkes::SyncPoint::get_identifier
std::string get_identifier() const
Definition: syncpoint.cpp:105
fawkes::SyncPoint::identifier_
const std::string identifier_
The unique identifier of the SyncPoint.
Definition: syncpoint.h:113
fawkes::SyncPoint::max_waittime_sec_
uint max_waittime_sec_
maximum waiting time in secs
Definition: syncpoint.h:149
fawkes::SyncPoint::mutex_wait_for_all_
Mutex * mutex_wait_for_all_
Mutex used for cond_wait_for_all_.
Definition: syncpoint.h:141
fawkes::Mutex::unlock
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
fawkes::SyncPoint::is_watcher
bool is_watcher(const std::string &component) const
Check if the given component is a watch.
Definition: syncpoint.cpp:493
fawkes::SyncPoint::reltime_wait_for_one
virtual void reltime_wait_for_one(const std::string &component, uint wait_sec, uint wait_nsec)
wait for the sync point, but abort after given time
Definition: syncpoint.cpp:374
fawkes::WaitCondition::wait
void wait()
Wait for the condition forever.
Definition: wait_condition.cpp:139
fawkes::MultiLogger::log_warn
virtual void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: multi.cpp:216
fawkes::SyncPoint::cond_next_wait_
WaitCondition * cond_next_wait_
WaitCondition used for lock_until_next_wait.
Definition: syncpoint.h:135
fawkes::SyncPointCall
A call (wait() or emit()) to a SyncPoint.
Definition: syncpoint_call.h:32
fawkes::SyncPoint::cond_wait_for_all_
WaitCondition * cond_wait_for_all_
WaitCondition which is used for wait_for_all()
Definition: syncpoint.h:143
fawkes::SyncPoint::wait_for_all_calls_
CircularBuffer< SyncPointCall > wait_for_all_calls_
A buffer of the most recent wait calls of type WAIT_FOR_ALL.
Definition: syncpoint.h:126
fawkes::SyncPoint::unregister_emitter
virtual void unregister_emitter(const std::string &component, bool emit_if_pending=true)
unregister as emitter
Definition: syncpoint.cpp:454
fawkes
Fawkes library namespace.
fawkes::SyncPointInvalidTypeException
Invalid SyncPoint type.
Definition: exceptions.h:192
fawkes::SyncPoint::operator==
bool operator==(const SyncPoint &other) const
EqualOperator.
Definition: syncpoint.cpp:116
fawkes::SyncPoint::wait_for_one_calls_
CircularBuffer< SyncPointCall > wait_for_one_calls_
A buffer of the most recent wait calls of type WAIT_FOR_ONE.
Definition: syncpoint.h:124
fawkes::SyncPoint::logger_
MultiLogger * logger_
Logger.
Definition: syncpoint.h:154
fawkes::MutexLocker::relock
void relock()
Lock this mutex, again.
Definition: mutex_locker.cpp:141
fawkes::SyncPoint::wait_for_one
virtual void wait_for_one(const std::string &component)
Wait for a single emitter.
Definition: syncpoint.cpp:354
fawkes::WaitCondition::reltimed_wait
bool reltimed_wait(unsigned int sec, unsigned int nanosec)
Wait with relative timeout.
Definition: wait_condition.cpp:206
fawkes::WaitCondition::wake_all
void wake_all()
Wake up all waiting threads.
Definition: wait_condition.cpp:287
fawkes::SyncPointMultipleWaitCallsException
A component called wait() but is already waiting.
Definition: exceptions.h:156
fawkes::SyncPointNonWatcherCalledWaitException
Emit was called by a component which isn't in the watcher set (or wrong component argument was passed...
Definition: exceptions.h:70
fawkes::Time
A class for handling time.
Definition: time.h:93
fawkes::SyncPoint::watchers_wait_for_one_
std::set< std::string > watchers_wait_for_one_
Set of all components which are currently waiting for a single emitter.
Definition: syncpoint.h:117
fawkes::CircularBuffer
Circular buffer with a fixed size.
Definition: circular_buffer.h:45
fawkes::SyncPoint::register_emitter
virtual void register_emitter(const std::string &component)
register as emitter
Definition: syncpoint.cpp:437
fawkes::SyncPoint::emit_calls_
CircularBuffer< SyncPointCall > emit_calls_
A buffer of the most recent emit calls.
Definition: syncpoint.h:122
fawkes::SyncPointNonEmitterCalledEmitException
Emit was called on a SyncBarrier but the calling component is not registered as emitter.
Definition: exceptions.h:174
fawkes::SyncPoint::get_emitters
std::multiset< std::string > get_emitters() const
Definition: syncpoint.cpp:543
fawkes::SyncPoint::wait_for_all_timer_owner_
std::string wait_for_all_timer_owner_
the component that started the wait-for-all timer
Definition: syncpoint.h:147
fawkes::SyncPoint::operator<
bool operator<(const SyncPoint &other) const
LessThan Operator.
Definition: syncpoint.cpp:139
fawkes::SyncPoint::wait
virtual void wait(const std::string &component, WakeupType=WAIT_FOR_ONE, uint wait_sec=0, uint wait_nsec=0)
wait for the sync point to be emitted by any other component
Definition: syncpoint.cpp:239
fawkes::SyncPoint::is_emitter
bool is_emitter(const std::string &component) const
Check if the given component is an emitter.
Definition: syncpoint.cpp:482
fawkes::MutexLocker::unlock
void unlock()
Unlock the mutex.
Definition: mutex_locker.cpp:153
fawkes::SyncPoint::lock_until_next_wait
void lock_until_next_wait(const std::string &component)
Lock the SyncPoint for emitters until the specified component does the next wait() call.
Definition: syncpoint.cpp:416
fawkes::SyncPoint::get_emit_calls
CircularBuffer< SyncPointCall > get_emit_calls() const
Definition: syncpoint.cpp:552
fawkes::SyncPoint::wait_for_all
virtual void wait_for_all(const std::string &component)
Wait for all registered emitters.
Definition: syncpoint.cpp:363
fawkes::SyncPoint::mutex_
Mutex * mutex_
Mutex used to protect all member variables.
Definition: syncpoint.h:131
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36