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 
25 namespace 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  */
62 SyncPointAspect::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  */
86 void
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  */
108 void
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  */
128 void
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  */
139 void
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:239
virtual void unregister_emitter(const std::string &component, bool emit_if_pending=true)
unregister as emitter
Definition: syncpoint.cpp:454
virtual void register_emitter(const std::string &component)
register as emitter
Definition: syncpoint.cpp:437
virtual void emit(const std::string &component)
send a signal to all waiting threads
Definition: syncpoint.cpp:148
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.