1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
/* -*- C++ -*- */
// $Id$
//
// ============================================================================
//
// = DESCRIPTION
// This test attempts to communicate several Event Channels.
// The test hardcodes all the objects involved (consumers,
// suppliers, proxies, etc.); the objective is to gain understanding
// on the architecture needed to exploit locality in the Event
// cycle, not to provide a definite solution.
//
// ============================================================================
#if !defined (EC_MULTIPLE_H)
#define EC_MULTIPLE_H
#include "ace/SString.h"
#include "ace/Task.h"
#include "ace/High_Res_Timer.h"
#include "orbsvcs/RtecEventChannelAdminC.h"
#include "orbsvcs/RtecEventCommS.h"
#include "orbsvcs/Channel_Clients_T.h"
#include "orbsvcs/Event/EC_Gateway.h"
class Test_ECG : public ACE_Task_Base
//
// = TITLE
// A simple test for the EC_Proxy class.
//
// = DESCRIPTION
// This class is design to exercise several features of the EC_Proxy
// class and the multiple EC architecture.
// We want to create two EC, each one having a single supplier and a
// single consumer.
// + To test the remote facilities the consumer register for both a
// local event and a remote one.
// + To test the remote filtering features the remote consumer only
// wants one of the local events, and this event is generated less
// frequently.
//
// This class creates the local EC_Gateway a consumer and a
// supplier, it uses the command line to figure the subscriptions
// and publications list.
//
{
public:
Test_ECG (void);
enum {
DEFAULT_EVENT_COUNT = 128,
// The default event count.
MAX_EVENTS = 256000
// Maximum number of events to send...
};
int run (int argc, char* argv[]);
// Execute the test.
void disconnect_push_supplier (CORBA::Environment &);
void disconnect_push_consumer (CORBA::Environment &);
void push (const RtecEventComm::EventSet &events,
CORBA::Environment &);
// Implement the consumer and supplier upcalls.
virtual int svc (void);
// Run the scavenger thread for the utilization test.
virtual int handle_timeout (const ACE_Time_Value &tv,
const void *arg = 0);
// Used when short circuiting the EC, this is the Event_Handler
// callback.
private:
int parse_args (int argc, char* argv[]);
// parse the command line args
int run_short_circuit (CORBA::ORB_ptr orb,
PortableServer::POA_ptr root_poa,
PortableServer::POAManager_ptr poa_manager,
CORBA::Environment& _env);
// Run the short-circuit version of the test, i.e. we don't use the
// EC to pass the events.
// To simulate the periodic nature of the EC event generation we run
// the ORB and connect to its Reactor for the timeouts.
int run_ec (CORBA::ORB_ptr orb,
PortableServer::POA_ptr root_poa,
PortableServer::POAManager_ptr poa_manager,
CORBA::Environment& _env);
// Run the test using the EC.
void dump_results (void);
// Dumpt the results to the standard output.
RtecEventChannelAdmin::EventChannel_ptr
get_ec (CosNaming::NamingContext_ptr naming_context,
const char* ec_name,
CORBA::Environment &_env);
// Helper routine to obtain an EC given its name.
int connect_supplier (RtecEventChannelAdmin::EventChannel_ptr local_ec,
CORBA::Environment &_env);
// Connect the supplier, it builds the proper Publication list based
// on the command line args.
int connect_consumer (RtecEventChannelAdmin::EventChannel_ptr local_ec,
CORBA::Environment &_env);
// Connect the consumer, it builds the proper Subscription list
// based on the command line args.
int connect_ecg (RtecEventChannelAdmin::EventChannel_ptr local_ec,
RtecEventChannelAdmin::EventChannel_ptr remote_ec,
RtecScheduler::Scheduler_ptr remote_sch,
CORBA::Environment &_env);
// Connect the EC gateway, it builds the Subscriptions and the
// Publications list.
int shutdown (CORBA::Environment&);
// Called when the main thread (i.e. not the scavenger thread) is
// shutting down.
private:
ACE_PushConsumer_Adapter<Test_ECG> consumer_;
// Our consumer personality....
ACE_PushSupplier_Adapter<Test_ECG> supplier_;
// Our supplier personality....
TAO_EC_Gateway ecg_;
// The proxy used to connect both event channels.
RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_;
// We talk to the EC (as a supplier) using this proxy.
RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
// We talk to the EC (as a consumer) using this proxy.
RtecEventComm::EventSourceID supplier_id_;
// Our ID as a supplier.
char* lcl_ec_name_;
// The name of the "local" EC.
char* rmt_ec_name_;
// The name of the "remote" EC.
char* lcl_sch_name_;
// The name of the local scheduling service.
char* rmt_sch_name_;
// The name of the remote scheduling service.
int global_scheduler_;
// Don't create a local scheduler.
int short_circuit_;
// Don't send the messages through the EC. This is needed to measure
// the overhead introduced by the EC.
int interval_;
// The interval between the messages.
int message_count_;
// How many messages we will send
int event_a_;
int event_b_;
int event_c_;
// We generate events <a> and <b> and receive events <a> and <c>,
// this allows for a lot of configurations (making a == c or
// different, etc.)
ACE_hrtime_t lcl_time_[Test_ECG::MAX_EVENTS];
int lcl_cnt_;
ACE_hrtime_t rmt_time_[Test_ECG::MAX_EVENTS];
int rmt_cnt_;
// Store the measurements for local and remote events..
ACE_hrtime_t scavenger_start_;
ACE_hrtime_t scavenger_end_;
// Measure the time it takes to run the scavenger thread.
ACE_Barrier scavenger_barrier_;
// The scavenger thread should not start until the EC is running.
int scavenger_cnt_;
// The number of iterations to run in the scavenger thread, if 0
// then there utilization thread is not started (this is good to
// measure just latency).
int scavenger_priority_;
// The priority at which the scavenger thread runs, must be lower
// that all the other threads.
ACE_High_Res_Timer push_timer_;
// Measure the time spent in pushes...
int scheduling_class_;
};
#endif /* EC_MULTIPLE_H */
|