Fawkes API Fawkes Development Version
syncpoint.cpp
1/***************************************************************************
2 * syncpoint.cpp - SyncPoint Aspect
3 *
4 * Created: Thu Feb 19 14:31:42 2015
5 * Copyright 2015 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 <aspect/syncpoint.h>
23#include <core/threading/thread.h>
24
25namespace fawkes {
26
27/** @class SyncPointAspect <aspect/syncpoint_manager.h>
28 * Thread aspect to acces to SyncPoints
29 * Give this aspect to your thread to manage SyncPoints,
30 * i.e. wait for SyncPoints and emit SyncPoints
31 * @ingroup Aspects
32 * @author Till Hofmann
33 */
34
35/** Constructor.
36 * Use this constructor if there should be an input syncpoint. The input syncpoint
37 * will be waited for before every loop.
38 * @param type_in type of the input syncpoint
39 * @param identifier_in identifier of the input syncpoint
40 * @param identifier_out identifier of the output syncpoint.
41 * If this identifier is empty, no output syncpoint will be used.
42 */
44 std::string identifier_in,
45 std::string identifier_out /* = "" */)
46: type_in_(type_in),
47 identifier_in_(identifier_in),
48 identifier_out_(identifier_out),
49 sp_in_(NULL),
50 sp_out_(NULL)
51{
52 add_aspect("SyncPointAspect");
53 has_input_syncpoint_ = (identifier_in != "");
54 has_output_syncpoint_ = (identifier_out != "");
55}
56
57/** Constructor.
58 * Use this constructor if there should be no input syncpoint, but only an output
59 * syncpoint.
60 * @param identifier_out identifier of the output syncpoint
61 */
62SyncPointAspect::SyncPointAspect(std::string identifier_out)
63: type_in_(SyncPoint::NONE),
64 identifier_in_(""),
65 identifier_out_(identifier_out),
66 sp_in_(NULL),
67 sp_out_(NULL)
68{
69 add_aspect("SyncPointAspect");
70 has_input_syncpoint_ = false;
71 has_output_syncpoint_ = true;
72}
73
74/** Destructor */
76{
77}
78
79/** Init SyncPoint aspect.
80 * This initializes the syncpoints and registers the thread as loop listener.
81 * Additionally, the thread is registered as emitter for the output syncpoint
82 * if an output syncpoint is created.
83 * @param thread thread which uses this aspect
84 * @param manager SyncPointManager to use
85 */
86void
88{
89 if (has_input_syncpoint_) {
90 sp_in_ = manager->get_syncpoint(thread->name(), identifier_in_);
91 }
92
93 if (has_output_syncpoint_) {
94 sp_out_ = manager->get_syncpoint(thread->name(), identifier_out_);
95 sp_out_->register_emitter(thread->name());
96 }
97
98 if (has_input_syncpoint_ || has_output_syncpoint_) {
99 thread->add_loop_listener(this);
100 }
101}
102
103/** Finalize SyncPoint aspect.
104 * This releases all syncpoints and unregisters the thread as loop listener.
105 * @param thread thread which uses this aspect
106 * @param manager SyncPointManager to use
107 */
108void
110{
111 if (has_input_syncpoint_) {
112 manager->release_syncpoint(thread->name(), sp_in_);
113 }
114
115 if (has_output_syncpoint_) {
116 sp_out_->unregister_emitter(thread->name());
117 manager->release_syncpoint(thread->name(), sp_out_);
118 }
119
120 if (has_input_syncpoint_ || has_output_syncpoint_) {
121 thread->remove_loop_listener(this);
122 }
123}
124
125/** Wait for the input syncpoint before loop()
126 * @param thread thread which uses this aspect and whose loop() will be called
127 */
128void
130{
131 if (has_input_syncpoint_) {
132 sp_in_->wait(thread->name(), type_in_);
133 }
134}
135
136/** Emit the output syncpoint after loop()
137 * @param thread thread which uses this aspect and whose loop() just returned
138 */
139void
141{
142 if (has_output_syncpoint_) {
143 sp_out_->emit(thread->name());
144 }
145}
146
147} // end namespace fawkes
void add_aspect(const char *name)
Add an aspect to a thread.
Definition: aspect.cpp:49
void init_SyncPointAspect(Thread *thread, SyncPointManager *syncpoint_manager)
Init SyncPoint aspect.
Definition: syncpoint.cpp:87
void pre_loop(Thread *thread)
Wait for the input syncpoint before loop()
Definition: syncpoint.cpp:129
void finalize_SyncPointAspect(Thread *thread, SyncPointManager *syncpoint_manager)
Finalize SyncPoint aspect.
Definition: syncpoint.cpp:109
void post_loop(Thread *thread)
Emit the output syncpoint after loop()
Definition: syncpoint.cpp:140
SyncPointAspect(SyncPoint::WakeupType type_in, std::string identifier_in, std::string identifier_out="")
Constructor.
Definition: syncpoint.cpp:43
virtual ~SyncPointAspect()
Destructor.
Definition: syncpoint.cpp:75
This class gives access to SyncPoints.
void release_syncpoint(const std::string &component, RefPtr< SyncPoint > syncpoint)
Release a SyncPoint.
RefPtr< SyncPoint > get_syncpoint(const std::string &component, const std::string &identifier)
Get a SyncPoint.
The SyncPoint class.
Definition: syncpoint.h:50
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:241
virtual void unregister_emitter(const std::string &component, bool emit_if_pending=true)
unregister as emitter
Definition: syncpoint.cpp:456
virtual void register_emitter(const std::string &component)
register as emitter
Definition: syncpoint.cpp:439
virtual void emit(const std::string &component)
send a signal to all waiting threads
Definition: syncpoint.cpp:150
WakeupType
Type to define when a thread wakes up after waiting for a SyncPoint.
Definition: syncpoint.h:56
Thread class encapsulation of pthreads.
Definition: thread.h:46
void add_loop_listener(ThreadLoopListener *loop_listener)
Add loop listener.
Definition: thread.cpp:1181
const char * name() const
Get name of thread.
Definition: thread.h:100
void remove_loop_listener(ThreadLoopListener *loop_listener)
Remove loop listener.
Definition: thread.cpp:1190
Fawkes library namespace.