3 // ============================================================================
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 // ============================================================================
17 #include "ace/SString.h"
19 #if !defined (ACE_LACKS_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"
33 class Test_Supplier
: public POA_RtecEventComm::PushSupplier
37 // Helper class to implement the different tests within Test_ECG.
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.
46 Test_Supplier (Test_ECG
* test
, void* cookie
);
48 void open (const char* name
,
49 int event_a
, int event_b
,
51 const RtecScheduler::Period_t
& rate
,
52 RtecEventChannelAdmin::EventChannel_ptr ec
);
53 // This method connects the supplier to the EC.
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;
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....
84 // The two types of events we may generate...
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
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
105 // Helper class to implement the different tests within Test_ECG.
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.
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.
122 // Disconnect from the EC.
124 virtual void push (const RtecEventComm::EventSet
& events
);
125 virtual void disconnect_push_consumer (void);
126 // The skeleton methods.
133 // The magic cookie that serves as our ID.
135 RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_
;
136 // We talk to the EC using this proxy.
143 // Test and demonstrate the use of TAO_EC_Gateway.
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
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
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.
165 // Maximum number of events to send...
167 MAX_CONSUMERS
= 1024,
168 // Maximum number of consumers.
171 // Maximum number of suppliers.
174 int run (int argc
, ACE_TCHAR
* argv
[]);
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.
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.
219 // Called when the main thread (i.e. not the scavenger thread) is
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.
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.
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.
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
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.
281 // The number of high priority suppliers in this test.
284 // The number of high priority consumers.
287 // The number of iterations of ACE::is_prime() to execute in high
288 // priority consumers.
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
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.
305 // The number of low priority suppliers in this test.
308 // The number of low priority consumers.
311 // The number of iterations of ACE::is_prime() to execute in low
312 // priority consumers.
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
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
332 const ACE_TCHAR
* pid_file_name_
;
333 // The name of a file where the process stores its pid
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
];
341 // We keep laxity and total_time stats only for the local events.
343 ACE_hrtime_t rmt_latency_
[MAX_EVENTS
];
346 Stats stats_
[Test_ECG::MAX_CONSUMERS
];
347 // Store the measurements for local and remote events..
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
370 #endif /* EC_MULTIPLE_H */