Fawkes API  Fawkes Development Version
syncpoint.h
1 /***************************************************************************
2  * syncpoint.h - Fawkes SyncPoint
3  *
4  * Created: Thu Jan 09 12:22:03 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 #ifndef _SYNCPOINT_SYNCPOINT_H_
23 #define _SYNCPOINT_SYNCPOINT_H_
24 
25 #include <core/threading/mutex.h>
26 #include <core/threading/wait_condition.h>
27 #include <core/utils/circular_buffer.h>
28 #include <core/utils/refptr.h>
29 #include <interface/interface.h>
30 #include <logging/multi.h>
31 #include <syncpoint/syncpoint_call.h>
32 #include <utils/time/time.h>
33 
34 #include <map>
35 #include <set>
36 #include <string>
37 
38 namespace fawkes {
39 
40 class SyncPointManager;
41 class SyncPoint;
42 
44 {
45 public:
46  bool operator()(const RefPtr<SyncPoint> sp1, const RefPtr<SyncPoint> sp2) const;
47 };
48 
49 class SyncPoint
50 {
51 public:
52  /** Type to define when a thread wakes up after waiting for a SyncPoint.
53  * A thread can be either wake up if ANY other thread emits the SyncPoint,
54  * or if ALL registered threads emit the SyncPoint.
55  */
56  typedef enum { WAIT_FOR_ONE, WAIT_FOR_ALL, NONE } WakeupType;
57 
58  SyncPoint(std::string identifier,
59  MultiLogger *logger,
60  uint max_waittime_sec = 0,
61  uint max_waittime_nsec = 0);
62  virtual ~SyncPoint();
63 
64  /** send a signal to all waiting threads */
65  virtual void emit(const std::string &component);
66 
67  /** wait for the sync point to be emitted by any other component */
68  virtual void wait(const std::string &component,
69  WakeupType = WAIT_FOR_ONE,
70  uint wait_sec = 0,
71  uint wait_nsec = 0);
72  /** abort waiting */
73  virtual void unwait(const std::string &component);
74  virtual void wait_for_one(const std::string &component);
75  virtual void wait_for_all(const std::string &component);
76  /** wait for the sync point, but abort after given time */
77  virtual void reltime_wait_for_one(const std::string &component, uint wait_sec, uint wait_nsec);
78  virtual void reltime_wait_for_all(const std::string &component, uint wait_sec, uint wait_nsec);
79 
80  /** register as emitter */
81  virtual void register_emitter(const std::string &component);
82 
83  /** unregister as emitter */
84  virtual void unregister_emitter(const std::string &component, bool emit_if_pending = true);
85  bool is_emitter(const std::string &component) const;
86  bool is_watcher(const std::string &component) const;
87 
88  void lock_until_next_wait(const std::string &component);
89 
90  std::string get_identifier() const;
91  bool operator==(const SyncPoint &other) const;
92  bool operator==(const std::string &other) const;
93  bool operator<(const SyncPoint &other) const;
94 
95  std::set<std::string> get_watchers() const;
96  std::multiset<std::string> get_emitters() const;
97  CircularBuffer<SyncPointCall> get_wait_calls(WakeupType type = WAIT_FOR_ONE) const;
99  bool watcher_is_waiting(std::string watcher, WakeupType type) const;
100 
101  /**
102  * allow Syncpoint Manager to edit
103  */
104  friend class SyncPointManager;
105 
106 protected:
107  std::pair<std::set<std::string>::iterator, bool> add_watcher(std::string watcher);
108  /** send a signal to all waiting threads */
109  virtual void emit(const std::string &component, bool remove_from_pending);
110 
111 protected:
112  /** The unique identifier of the SyncPoint */
113  const std::string identifier_;
114  /** Set of all components which use this SyncPoint */
115  std::set<std::string> watchers_;
116  /** Set of all components which are currently waiting for a single emitter */
117  std::set<std::string> watchers_wait_for_one_;
118  /** Set of all components which are currently waiting on the barrier */
119  std::set<std::string> watchers_wait_for_all_;
120 
121  /** A buffer of the most recent emit calls. */
123  /** A buffer of the most recent wait calls of type WAIT_FOR_ONE. */
125  /** A buffer of the most recent wait calls of type WAIT_FOR_ALL. */
127  /** Time when this SyncPoint was created */
129 
130  /** Mutex used to protect all member variables */
132  /** Mutex used to allow lock_until_next_wait */
134  /** WaitCondition used for lock_until_next_wait */
136  /** Mutex used for cond_wait_for_one_ */
138  /** WaitCondition which is used for wait_for_one() */
140  /** Mutex used for cond_wait_for_all_ */
142  /** WaitCondition which is used for wait_for_all() */
144  /** true if the wait for all timer is running */
146  /** the component that started the wait-for-all timer */
148  /** maximum waiting time in secs */
150  /** maximum waiting time in nsecs */
152 
153  /** Logger */
155 
156 private:
157  void reset_emitters();
158  bool is_pending(std::string component);
159  void handle_default(std::string component, WakeupType type);
160  void cleanup();
161 
162 private:
163  /** The predecessor SyncPoint, which is the SyncPoint one level up
164  * e.g. "/test/sp" -> "/test"
165  */
166  RefPtr<SyncPoint> predecessor_;
167 
168  /** all successors */
169  std::set<RefPtr<SyncPoint>, SyncPointSetLessThan> successors_;
170 
171  std::multiset<std::string> emitters_;
172  std::multiset<std::string> pending_emitters_;
173 
174  std::set<std::string> bad_components_;
175 
176  std::string emit_locker_;
177 
178  Time last_emitter_reset_;
179 };
180 
181 } // end namespace fawkes
182 
183 #endif
fawkes::SyncPointSetLessThan::operator()
bool operator()(const RefPtr< SyncPoint > sp1, const RefPtr< SyncPoint > sp2) const
LessThan Operator to use for the manager's SyncPoint set Since we store RefPtrs to SyncPoints we have...
Definition: syncpoint_manager.cpp:105
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::SyncPointManager
This class gives access to SyncPoints.
Definition: syncpoint_manager.h:38
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::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::RefPtr< SyncPoint >
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::SyncPoint::SyncPoint
SyncPoint(std::string identifier, MultiLogger *logger, uint max_waittime_sec=0, uint max_waittime_nsec=0)
Constructor.
Definition: syncpoint.cpp:57
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::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::SyncPoint::creation_time_
const Time creation_time_
Time when this SyncPoint was created.
Definition: syncpoint.h:128
fawkes::SyncPoint::cond_next_wait_
WaitCondition * cond_next_wait_
WaitCondition used for lock_until_next_wait.
Definition: syncpoint.h:135
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::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::SyncPoint::wait_for_one
virtual void wait_for_one(const std::string &component)
Wait for a single emitter.
Definition: syncpoint.cpp:354
fawkes::Time
A class for handling time.
Definition: time.h:93
fawkes::SyncPointSetLessThan
Compare sets of syncpoints.
Definition: syncpoint.h:44
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::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::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