3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #include <beacon/fast_signal.hpp>
8 #include <beacon/event_loop.hpp>
9 #include <beacon/trackable.hpp>
10 #include <boost/bind.hpp>
12 #include <boost/signal.hpp>
13 #include <boost/thread/xtime.hpp>
14 #include <boost/thread.hpp>
15 #include <fastsig/fastsig.hpp>
19 size_t const nof_event_loops
= 4;
20 size_t const nof_signals
= 10;
21 size_t const nof_threads
= 10;
23 beacon::event_loop event_loops
[nof_event_loops
];
24 beacon::fast_signal
<void ()> signals
[nof_signals
];
26 size_t nof_loops
= 10;
27 size_t test_runs
= 10;
31 boost::thread cur_thread
;
33 boost::xtime_get(&now
, boost::TIME_UTC
);
41 cur_thread
.sleep(now
);
45 void run_test(char const * name
, size_t runs
, size_t const nof_threads
, void(* setup
)(), void(* payload
)(), void( * teardown
)()) {
47 double test_sum_time
= 0;
48 double overall_sum_time
= 0;
49 for(size_t run
= 0; run
< runs
; ++run
) {
50 boost::xtime overall_start
, test_start
, overall_end
, test_end
;
52 boost::xtime_get(&overall_start
, boost::TIME_UTC
);
58 boost::thread_group tg
;
60 boost::xtime_get(&test_start
, boost::TIME_UTC
);
62 for(size_t i
= 1; i
< nof_threads
; ++i
) {
63 tg
.create_thread(payload
);
70 boost::xtime_get(&test_end
, boost::TIME_UTC
);
76 boost::xtime_get(&overall_end
, boost::TIME_UTC
);
78 test_sum_time
+= test_end
.sec
- test_start
.sec
+ (test_end
.nsec
- test_start
.nsec
) / 1e9
;
79 overall_sum_time
+= overall_end
.sec
- overall_start
.sec
+ (overall_end
.nsec
- overall_start
.nsec
) / 1e9
;
81 std::cout
<< name
<< " (" << nof_threads
<< " threads) avg. time: " <<
82 (test_sum_time
/ runs
) << "/" << (overall_sum_time
/ runs
) << " in " << runs
<< " runs." << std::endl
;
89 void connect_all_signals_no_event_loop() {
90 for(size_t i
= 0; i
< nof_signals
; ++i
) {
91 signals
[i
].connect(&fn
);
95 void disconnect_all_signals() {
96 for(size_t i
= 0; i
< nof_signals
; ++i
) {
101 void connect_all_signals_first_event_loop() {
102 for(size_t i
= 0; i
< nof_signals
; ++i
) {
103 signals
[i
].connect(&fn
, event_loops
[0]);
107 void connect_all_signals_event_loops() {
108 for(size_t i
= 0; i
< nof_signals
; ++i
) {
109 int el_idx
= rand() % nof_event_loops
;
110 signals
[i
].connect(&fn
, event_loops
[el_idx
]);
114 void start_first_event_loop_no_signals() {
115 event_loops
[0].start();
118 void stop_first_event_loop_no_signals() {
119 event_loops
[0].join();
122 void start_all_event_loops_no_signals() {
123 for(size_t i
= 0; i
< nof_event_loops
; ++i
) {
124 event_loops
[i
].start();
128 void stop_all_event_loops_no_signals() {
129 for(size_t i
= 0; i
< nof_event_loops
; ++i
) {
130 event_loops
[i
].join();
134 void start_first_event_loop() {
135 connect_all_signals_first_event_loop();
136 event_loops
[0].start();
139 void stop_first_event_loop() {
140 event_loops
[0].join();
141 disconnect_all_signals();
144 void start_all_event_loops() {
145 connect_all_signals_event_loops();
146 for(size_t i
= 0; i
< nof_event_loops
; ++i
) {
147 event_loops
[i
].start();
151 void stop_all_event_loops() {
152 for(size_t i
= 0; i
< nof_event_loops
; ++i
) {
153 event_loops
[i
].join();
155 disconnect_all_signals();
162 void boost_signal() {
163 boost::signal
<void ()> sig
;
167 for(size_t i
= 0; i
< nof_loops
; ++i
) {
172 void fastsig_signal() {
173 fastsig::signal
<void ()> sig
;
177 for(size_t i
= 0; i
< nof_loops
; ++i
) {
182 void fast_signal_no_event_loop() {
183 beacon::fast_signal
<void ()> sig
;
187 for(size_t i
= 0; i
< nof_loops
; ++i
) {
192 void all_fast_signals() {
193 for(size_t i
= 0; i
< nof_loops
; ++i
) {
194 int sig_idx
= rand() % nof_signals
;
199 void one_fast_signal() {
200 beacon::fast_signal
<void ()> & sig
= signals
[0];
201 for(size_t i
= 0; i
< nof_loops
; ++i
) {
206 void short_lived_fast_signal_one_event_loop() {
207 beacon::fast_signal
<void ()> sig
;
209 sig
.connect(&fn
, event_loops
[0]);
211 for(size_t i
= 0; i
< nof_loops
; ++i
) {
216 void short_lived_fast_signal_event_loops() {
217 beacon::fast_signal
<void ()> sig
;
219 int el_i
= rand() % nof_event_loops
;
221 sig
.connect(&fn
, event_loops
[el_i
]);
223 for(size_t i
= 0; i
< nof_loops
; ++i
) {
228 int main(int argc
, char * argv
[]) {
230 for(size_t threads
= 1; threads
< nof_threads
; ++threads
) {
231 run_test("boost::signal",
238 run_test("fastsig::signal",
245 run_test("fast_signal no event loop",
249 fast_signal_no_event_loop
,
252 run_test("fast_signal one event loop",
255 start_first_event_loop
,
257 stop_first_event_loop
);
259 run_test("fast_signals all event loops",
262 start_all_event_loops
,
264 stop_all_event_loops
);
266 run_test("short lived fast_signal one event loop",
269 start_first_event_loop_no_signals
,
270 short_lived_fast_signal_one_event_loop
,
271 stop_first_event_loop_no_signals
);
273 run_test("short lived fast_signal all event loops",
276 start_all_event_loops_no_signals
,
277 short_lived_fast_signal_event_loops
,
278 stop_all_event_loops_no_signals
);