Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / orbsvcs / tests / EC_Multiple / EC_Multiple.h
blob9ba503ad3fe3c7f0e25955c648223c393f99690d
1 /* -*- C++ -*- */
2 //
3 // ============================================================================
4 //
5 // = DESCRIPTION
6 // This test attempts to communicate several Event Channels.
7 // The test hardcodes all the objects involved (consumers,
8 // suppliers, proxies, etc.); the objective is to gain understanding
9 // on the architecture needed to exploit locality in the Event
10 // cycle, not to provide a definite solution.
12 // ============================================================================
14 #ifndef EC_MULTIPLE_H
15 #define EC_MULTIPLE_H
17 #include "ace/SString.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "ace/High_Res_Timer.h"
24 #include "ace/Condition_Thread_Mutex.h"
25 #include "orbsvcs/RtecEventChannelAdminC.h"
26 #include "orbsvcs/RtecEventCommS.h"
27 #include "orbsvcs/Channel_Clients_T.h"
28 #include "orbsvcs/Event/EC_Gateway_Sched.h"
29 #include "orbsvcs/CosNamingC.h"
31 class Test_ECG;
33 class Test_Supplier : public POA_RtecEventComm::PushSupplier
36 // = TITLE
37 // Helper class to implement the different tests within Test_ECG.
39 // = DESCRIPTION
40 // Test_ECG can be configured to have a single or multiple
41 // suppliers, to use the EC or short-circuit it, to use the
42 // Gateway or not; this class connects as a consumer for timeouts
43 // in the EC, at each timeout it delegates on the Test_ECG class
44 // to execute the proper test.
45 public:
46 Test_Supplier (Test_ECG* test, void* cookie);
48 void open (const char* name,
49 int event_a, int event_b,
50 int message_count,
51 const RtecScheduler::Period_t& rate,
52 RtecEventChannelAdmin::EventChannel_ptr ec);
53 // This method connects the supplier to the EC.
55 void close (void);
56 // Disconnect from the EC.
58 void activate (const char* name,
59 const RtecScheduler::Period_t& rate,
60 RtecEventChannelAdmin::EventChannel_ptr ec);
62 void push (const RtecEventComm::EventSet& events);
63 void disconnect_push_consumer (void);
64 // Implement the callbacks for our consumer personality.
67 virtual void disconnect_push_supplier (void);
68 // The methods in the skeleton.
70 RtecEventComm::EventSourceID supplier_id (void) const;
71 // The supplier ID.
73 private:
74 Test_ECG* test_;
76 void *cookie_;
77 // The test provide us a cookie so we can give back our identity.
79 RtecEventComm::EventSourceID supplier_id_;
80 // We generate an id based on the name....
82 int event_a_;
83 int event_b_;
84 // The two types of events we may generate...
86 int message_count_;
87 // The number of events sent by this supplier.
89 RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_;
90 // We talk to the EC (as a supplier) using this proxy.
92 ACE_PushConsumer_Adapter<Test_Supplier> consumer_;
93 // We also connect to the EC as a consumer so we can receive the
94 // timeout events.
96 RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
97 // We talk to the EC (as a supplier) using this proxy.
101 class Test_Consumer : public POA_RtecEventComm::PushConsumer
104 // = TITLE
105 // Helper class to implement the different tests within Test_ECG.
107 // = DESCRIPTION
108 // Test_ECG must collect events destined to many consumers, but
109 // needs to distinguish through which consumer it is receiving the
110 // event. The easiest way is to create a shallow class that
111 // forwards the events to the EC, but passing back some cookie to
112 // identify the consumer.
113 public:
114 Test_Consumer (Test_ECG* test, void *cookie);
116 void open (const char* name,
117 int event_a, int event_b,
118 RtecEventChannelAdmin::EventChannel_ptr ec);
119 // This method connects the consumer to the EC.
121 void close (void);
122 // Disconnect from the EC.
124 virtual void push (const RtecEventComm::EventSet& events);
125 virtual void disconnect_push_consumer (void);
126 // The skeleton methods.
128 private:
129 Test_ECG* test_;
130 // The test class.
132 void *cookie_;
133 // The magic cookie that serves as our ID.
135 RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
136 // We talk to the EC using this proxy.
139 class Test_ECG
142 // = TITLE
143 // Test and demonstrate the use of TAO_EC_Gateway.
145 // = DESCRIPTION
146 // This class is design to exercise several features of the EC_Gateway
147 // class and the multiple EC architecture.
148 // We want to create two EC, each one having a single supplier and a
149 // single consumer.
150 // + To test the remote facilities the consumer register for both a
151 // local event and a remote one.
152 // + To test the remote filtering features the remote consumer only
153 // wants one of the local events, and this event is generated less
154 // frequently.
156 // This class creates the local EC_Gateway a consumer and a
157 // supplier, it uses the command line to figure the subscriptions
158 // and publications list.
160 public:
161 Test_ECG (void);
163 enum {
164 MAX_EVENTS = 1024,
165 // Maximum number of events to send...
167 MAX_CONSUMERS = 1024,
168 // Maximum number of consumers.
170 MAX_SUPPLIERS = 1024
171 // Maximum number of suppliers.
174 int run (int argc, ACE_TCHAR* argv[]);
175 // Execute the test.
177 void push_supplier (void* supplier_cookie,
178 RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer,
179 const RtecEventComm::EventSet &events);
180 // Callback method for suppliers, we push for them to their
181 // consumers and take statistics on the way.
182 // It is possible that we ignore the <consumer> parameter when
183 // testing the short-circuit case.
185 void push_consumer (void* consumer_cookie,
186 ACE_hrtime_t arrival,
187 const RtecEventComm::EventSet& events);
188 // Callback method for consumers, if any of our consumers has
189 // received events it will invoke this method.
191 void shutdown_supplier (void* supplier_cookie,
192 RtecEventComm::PushConsumer_ptr consumer);
193 // One of the suppliers has completed its work.
195 private:
196 RtecEventChannelAdmin::EventChannel_ptr
197 get_ec (CosNaming::NamingContext_ptr naming_context,
198 const char* ec_name);
199 // Helper routine to obtain an EC given its name.
201 void connect_suppliers (RtecEventChannelAdmin::EventChannel_ptr local_ec);
202 void disconnect_suppliers (void);
203 // Connect the suppliers.
205 void activate_suppliers (RtecEventChannelAdmin::EventChannel_ptr local_ec);
206 // Activate the suppliers, i.e. they start generating events.
208 void connect_ecg (RtecEventChannelAdmin::EventChannel_ptr local_ec,
209 RtecEventChannelAdmin::EventChannel_ptr remote_ec,
210 RtecScheduler::Scheduler_ptr remote_sch);
211 // Connect the EC gateway, it builds the Subscriptions and the
212 // Publications list.
214 void connect_consumers (RtecEventChannelAdmin::EventChannel_ptr local_ec);
215 void disconnect_consumers (void);
216 // Connect and disconnect the consumers.
218 int shutdown (void);
219 // Called when the main thread (i.e. not the scavenger thread) is
220 // shutting down.
222 int parse_args (int argc, ACE_TCHAR* argv[]);
223 // parse the command line args
225 void dump_results (void);
226 // Dump the results to the standard output.
228 void wait_until_ready (void);
229 // Block event delivery until all the consumers are ready.
231 struct Stats;
232 void dump_results (const ACE_TCHAR* name, Stats& stats);
233 // Dump the results for a particular consumer.
235 int local_source (RtecEventComm::EventSourceID id) const;
236 // Check if <id> correspond to a local supplier.
238 void shutdown_consumer (int id);
239 // One of the consumers has completed its work.
241 private:
242 ACE_CString lcl_name_;
243 // The name of the "local" EC.
245 ACE_CString rmt_name_;
246 // The name of the "remote" EC.
248 TAO_EC_Gateway_Sched ecg_;
249 // The proxy used to connect both event channels.
251 enum {
252 ss_global,
253 ss_local,
254 ss_runtime
256 int scheduling_type_;
257 // The type of scheduling service to use:
258 // "global" is a remote scheduling service, usually to perform
259 // simultaneous scheduling across all the processes.
260 // "local" instantiate a local config time scheduling service.
261 // "runtime" instantiates a local rumtime scheduling service.
263 int consumer_disconnects_;
264 int supplier_disconnects_;
265 // How many times to disconnect the consumers (and suppliers) before
266 // the final connection. This is useful to test the disconnection in
267 // the EC.
269 int short_circuit_;
270 // Don't send the messages through the EC. This is needed to measure
271 // the overhead introduced by the EC.
273 Test_Supplier* suppliers_[Test_ECG::MAX_SUPPLIERS];
274 Test_Consumer* consumers_[Test_ECG::MAX_CONSUMERS];
275 // The suppliers and consumer arrays, the sizes are controlled using
276 // {lp,hp}_{suppliers,consumers}_
278 // @@ TODO it looks like the HP and LP data could be encapsulated.
280 int hp_suppliers_;
281 // The number of high priority suppliers in this test.
283 int hp_consumers_;
284 // The number of high priority consumers.
286 int hp_workload_;
287 // The number of iterations of ACE::is_prime() to execute in high
288 // priority consumers.
290 int hp_interval_;
291 // The high priority events are generated using this interval.
293 int hp_message_count_;
294 // How many messages we will send in the HP suppliers
296 int hps_event_a_;
297 int hps_event_b_;
298 int hpc_event_a_;
299 int hpc_event_b_;
300 // Each supplier send two types of events, each consumer receives
301 // two other types. The types for high-priority clients can be
302 // different from the types to low priority clients.
304 int lp_suppliers_;
305 // The number of low priority suppliers in this test.
307 int lp_consumers_;
308 // The number of low priority consumers.
310 int lp_workload_;
311 // The number of iterations of ACE::is_prime() to execute in low
312 // priority consumers.
314 int lp_interval_;
315 // The low priority events are generated using this interval.
317 int lp_message_count_;
318 // How many messages we will send in the LP suppliers
320 int lps_event_a_;
321 int lps_event_b_;
322 int lpc_event_a_;
323 int lpc_event_b_;
324 // Each supplier send two types of events, each consumer receives
325 // two other types. The types for high-priority clients can be
326 // different from the types to low priority clients.
328 const ACE_TCHAR* schedule_file_;
329 // Ask the schedule to compute and dump its schedule after the test
330 // execution.
332 const ACE_TCHAR* pid_file_name_;
333 // The name of a file where the process stores its pid
335 struct Stats {
336 ACE_hrtime_t total_time_;
337 float laxity_[MAX_EVENTS];
338 ACE_hrtime_t lcl_latency_[MAX_EVENTS];
339 ACE_hrtime_t end_[MAX_EVENTS];
340 int lcl_count_;
341 // We keep laxity and total_time stats only for the local events.
343 ACE_hrtime_t rmt_latency_[MAX_EVENTS];
344 int rmt_count_;
346 Stats stats_[Test_ECG::MAX_CONSUMERS];
347 // Store the measurements for local and remote events..
349 int ready_;
350 TAO_SYNCH_MUTEX ready_mtx_;
351 TAO_SYNCH_CONDITION ready_cnd_;
352 // Before accepting any events the suppliers must wait for the test
353 // to setup all the consumers.
354 // The suppliers wait on the condition variable.
356 ACE_Atomic_Op<TAO_SYNCH_MUTEX,int> running_suppliers_;
357 // keep track of how many suppliers are still running so we shutdown
358 // at the right moment.
360 ACE_Atomic_Op<TAO_SYNCH_MUTEX,int> running_consumers_;
361 // keep track of how many consumers are still running so we shutdown
362 // at the right moment.
364 ACE_hrtime_t test_start_;
365 ACE_hrtime_t test_stop_;
366 // Measure the test elapsed time as well as mark the beginning of
367 // the frames.
370 #endif /* EC_MULTIPLE_H */