1 //=============================================================================
3 * @file Notify_Performance_Test.cpp
5 * This test is used to time the notification mechanisms of the
6 * ACE_Reactors. Both the WFMO_Reactor and Select_Reactor can be
7 * tested. The notify() mechanism can also be tested with or
10 * @author Irfan Pyarali <irfan@cs.wustl.edu>
12 //=============================================================================
16 #include "test_config.h"
17 #include "ace/Profile_Timer.h"
18 #include "ace/Get_Opt.h"
19 #include "ace/Thread_Manager.h"
20 #include "ace/Reactor.h"
21 #include "ace/WFMO_Reactor.h"
22 #include "ace/Select_Reactor.h"
23 #include "ace/Dev_Poll_Reactor.h"
25 #include "ace/Atomic_Op.h"
27 #if defined (ACE_HAS_THREADS)
29 // Number of client (user) threads
30 static long opt_nthreads
= 1;
32 // Number of notify calls
33 static int opt_nloops
= 20000;
35 // Use the WFMO_Reactor
36 static int opt_wfmo_reactor
= 0;
38 // Use the Select_Reactor
39 static int opt_select_reactor
= 0;
41 // Use the Dev_Poll_Reactor
42 static int opt_dev_poll_reactor
= 0;
44 // Pass data through the notify call
45 static int opt_pass_notify_data
= 0;
47 // Simple no-op handler
48 class Handler
: public ACE_Event_Handler
51 /// The Handler callbacks.
52 int handle_exception (ACE_HANDLE fd
= ACE_INVALID_HANDLE
) override
;
56 Handler::handle_exception (ACE_HANDLE handle
)
58 ACE_UNUSED_ARG (handle
);
63 // Execute the client tests.
68 // Number of client (user) threads
69 static ACE_Atomic_Op
<ACE_Thread_Mutex
, long> thread_counter
;
70 thread_counter
= opt_nthreads
;
72 // To pass or not to pass is the question
74 if (!opt_pass_notify_data
)
77 handler
= (Handler
*) arg
;
79 for (int i
= 0; i
< opt_nloops
; i
++)
80 ACE_Reactor::instance ()->notify (handler
);
82 if (--thread_counter
== 0)
83 ACE_Reactor::instance()->end_reactor_event_loop ();
88 // Sets up the correct reactor (based on platform and options)
93 ACE_Reactor_Impl
*impl
= 0;
97 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1)
98 ACE_NEW (impl
, ACE_WFMO_Reactor
);
99 #endif /* ACE_HAS_WINSOCK2 == 1 */
101 else if (opt_select_reactor
)
103 ACE_NEW (impl
, ACE_Select_Reactor
);
105 else if (opt_dev_poll_reactor
)
107 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
108 ACE_NEW (impl
, ACE_Dev_Poll_Reactor
);
109 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */
111 ACE_Reactor
*reactor
= 0;
112 ACE_NEW (reactor
, ACE_Reactor (impl
));
113 ACE_Reactor::instance (reactor
);
117 print_results (ACE_Profile_Timer::ACE_Elapsed_Time
&et
)
119 const ACE_TCHAR
*reactor_type
= 0;
120 if (opt_wfmo_reactor
)
121 reactor_type
= ACE_TEXT ("WFMO_Reactor");
122 else if (opt_select_reactor
)
123 reactor_type
= ACE_TEXT ("Select_Reactor");
124 else if (opt_dev_poll_reactor
)
125 reactor_type
= ACE_TEXT ("Dev_Poll_Reactor");
127 reactor_type
= ACE_TEXT ("Platform's default Reactor");
129 ACE_DEBUG ((LM_DEBUG
,
130 ACE_TEXT ("\nNotify_Performance Test statistics:\n\n")));
131 ACE_DEBUG ((LM_DEBUG
,
132 ACE_TEXT ("\tReactor Type: %s\n"),
134 ACE_DEBUG ((LM_DEBUG
,
135 ACE_TEXT ("\tWorker threads (calling notify()): %d\n"),
137 ACE_DEBUG ((LM_DEBUG
,
138 ACE_TEXT ("\tIteration per thread: %d\n"),
140 if (opt_pass_notify_data
)
141 ACE_DEBUG ((LM_DEBUG
,
142 ACE_TEXT ("\tData was passed in the notify() call\n")));
144 ACE_DEBUG ((LM_DEBUG
,
145 ACE_TEXT ("\tNo data was passed in the notify() call\n")));
147 ACE_DEBUG ((LM_DEBUG
,
148 ACE_TEXT ("\n\tTiming results notify() call:\n")));
149 ACE_DEBUG ((LM_DEBUG
,
150 ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n\n"),
157 run_main (int argc
, ACE_TCHAR
*argv
[])
159 ACE_START_TEST (ACE_TEXT ("Notify_Performance_Test"));
161 //FUZZ: disable check_for_lack_ACE_OS
162 ACE_Get_Opt
getopt (argc
, argv
, ACE_TEXT ("pswdc:l:"));
164 for (int c
; (c
= getopt ()) != -1; )
167 //FUZZ: enable check_for_lack_ACE_OS
169 opt_dev_poll_reactor
= 1;
172 opt_select_reactor
= 1;
175 opt_wfmo_reactor
= 1;
178 opt_nthreads
= ACE_OS::atoi (getopt
.opt_arg ());
181 opt_nloops
= ACE_OS::atoi (getopt
.opt_arg ());
184 opt_pass_notify_data
= 1;
188 // Sets up the correct reactor (based on platform and options)
191 // Manage memory automagically.
192 std::unique_ptr
<ACE_Reactor
> reactor (ACE_Reactor::instance ());
193 std::unique_ptr
<ACE_Reactor_Impl
> impl
;
195 // If we are using other that the default implementation, we must
197 if (opt_select_reactor
|| opt_wfmo_reactor
|| opt_dev_poll_reactor
)
199 std::unique_ptr
<ACE_Reactor_Impl
> auto_impl (ACE_Reactor::instance ()->implementation ());
200 impl
= std::move(auto_impl
);
206 // Spawn worker threads
207 if (ACE_Thread_Manager::instance ()->spawn_n
209 ACE_THR_FUNC (client
),
211 THR_NEW_LWP
| THR_DETACHED
) == -1)
212 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%P|%t) %p\n%a"), ACE_TEXT ("thread create failed")));
215 ACE_Profile_Timer timer
;
219 ACE_Reactor::instance()->run_reactor_event_loop ();
223 ACE_Profile_Timer::ACE_Elapsed_Time et
;
224 timer
.elapsed_time (et
);
229 ACE_DEBUG ((LM_DEBUG
,
230 ACE_TEXT ("(%P|%t) waiting for the worker threads...\n")));
232 // Wait for all worker to get done.
233 ACE_Thread_Manager::instance ()->wait ();
241 run_main (int, ACE_TCHAR
*[])
243 ACE_START_TEST (ACE_TEXT ("Notify_Performance_Test"));
246 ACE_TEXT ("threads not supported on this platform\n")));
251 #endif /* ACE_HAS_THREADS */