summaryrefslogtreecommitdiff
path: root/TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.h
blob: 799d92701474e34a94d472937bfde5e4f7d6ea64 (plain)
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
/* -*- C++ -*- */
// $Id$

// ============================================================================
//
// = LIBRARY
//    TAO/tests
//
// = FILENAME
//    Task_Client.h
//
// = AUTHOR
//    Andy Gokhale, Sumedh Mungee ,Sergio Flores-Gaitan and Nagarajan Surendran.
//
// ============================================================================

#if !defined (TASK_CLIENT_H)
#define TASK_CLIENT_H

#include "ace/Synch.h"
#include "ace/Task.h"
#include "ace/Thread_Manager.h"
#include "ace/Get_Opt.h"
#include "ace/Profile_Timer.h"
#include "ace/ARGV.h"
#include "ace/Sched_Params.h"
#include "ace/High_Res_Timer.h"
#include "ace/Containers.h"

#include "orbsvcs/CosNamingC.h"
#include "orbsvcs/Naming/Naming_Utils.h"
#include "cubitC.h"
#include "cubit_i.h"
#include "Globals.h"
#include "Timer.h"

#if defined (CHORUS)
#include "pccTimer.h"
#endif /* CHORUS */

#include <math.h>

// I will integrate this, together with the sqrt() function when
// the implementation is complete.  --Sergio.
#if defined (ACE_LACKS_FLOATING_POINT)
#define fabs(X) ((X) >= 0 ? (X) : -(X))
// the following is just temporary, until we finish the sqrt()
// implementation.
#define sqrt(X) (1)
#endif /* ACE_LACKS_FLOATING_POINT */

#if defined (NO_ACE_QUANTIFY)
#define START_QUANTIFY \
quantify_start_recording_data ();
#define STOP_QUANTIFY \
quantify_stop_recording_data();
#define CLEAR_QUANTIFY \
quantify_clear_data ();
#else /*!NO_ACE_QUANTIFY */
#define START_QUANTIFY 
#define STOP_QUANTIFY 
#define CLEAR_QUANTIFY
#endif /* !NO_ACE_QUANTIFY */


enum Cubit_Datatypes
{
  // = The various datatypes the client and the server can exchange.
  CB_OCTET,
  CB_SHORT,
  CB_LONG,
  CB_STRUCT,

  // = Rate constants.
  CB_20HZ_CONSUMER = 0,
  CB_10HZ_CONSUMER = 1,
  CB_5HZ_CONSUMER = 2,
  CB_1HZ_CONSUMER = 3,

  CB_20HZ_CONSUMER_RATE = 20,
  CB_10HZ_CONSUMER_RATE = 10,
  CB_5HZ_CONSUMER_RATE = 5,
  CB_1HZ_CONSUMER_RATE = 1,

  CB_HIGH_PRIORITY_RATE = 20,
  CB_LOW_PRIORITY_RATE = 10
};

typedef ACE_Unbounded_Set<ACE_timer_t> JITTER_ARRAY;
typedef ACE_Unbounded_Set_Iterator<ACE_timer_t> JITTER_ARRAY_ITERATOR;

class Task_State
{
  // = TITLE
  //     Maintains state common to multiple Cubit clients.
  //
  // = DESCRIPTION
  //     This class maintains state which is common to the potentially
  //     multiple concurrent clients.
public:
  Task_State (void);
  // Constructor. 

  int parse_args (int argc,char **argv);
  // parses the arguments with the provided argc and argv.

  ~Task_State (void);
  // Destructor

  ACE_Barrier *barrier_;
  // Barrier for the multiple clients to synchronize after binding to
  // the servants.

  CORBA::String key_;
  // All cubit objects will have this as prefix to its key.

  u_int loop_count_;
  // Number of times to loop, making calls.

  u_int thread_count_;
  // Number of concurrent clients to create.

  ACE_timer_t *latency_;
  // Array to store the latency for every client, indexed by
  // thread-id.

  int *ave_latency_;
  // Int array to store the latencies.

  Cubit_Datatypes datatype_;
  // Which datatype to use to make the calls.

  ACE_SYNCH_MUTEX lock_;
  // Lock to protect access to this object.

  u_int thread_per_rate_;
  // Flag for the thread_per_rate test.

  JITTER_ARRAY **global_jitter_array_;
  // This array stores the latency seen by each client for each
  // request, to be used later to compute jitter.

  u_int *count_;
  // This array stores the call count of each thread.  They will not
  // always have the same call count.

  u_int shutdown_;
  // Flag that indicates if we are going to call the shutdown methos
  // for the servant.

  u_int oneway_;
  // Flag that indicates if we are going to use oneway calls instead
  // of two-way.

  char *one_ior_;
  // Ior array used if utilization test is run.

  u_int use_name_service_;
  // Flag that say if we are using the or not the name service.

  u_int one_to_n_test_;
  // indicates whether we are running the "1 to n" test, which has 1
  // low priority servant and n low priority clients.

  u_int context_switch_test_;
  // flag to run context switch test

  char **iors_;
  // Array of pointers used to hold the ior strings read from the ior file
  // that the server created.

  int iors_count_;
  // count on the number of iors

  char *ior_file_;
  // Name of the filename that the server used to store the iors.

  u_int granularity_;
  // this is the granularity of the timing of the CORBA requests. A
  // value of 5 represents that we will take time every 5 requests,
  // instead of the default of every request (1).

  u_int use_utilization_test_;
  // flag to indicate we are to use the utilization test.  By default
  // we do not use it, because it can cause starvation with real-time
  // threads

  u_int high_priority_loop_count_;
  // Number of times the high priority looped.  We are going to loop
  // as long as there is low priority clients running, so as to
  // maintain high priority traffic as long as low priority traffic is
  // going through.

  ACE_Thread_Semaphore *semaphore_;
  // semaphore in order for the high priority client to keep running
  // as long as the low priority clients are running.  See explanation
  // of "high_priority_loop_count_" member in this class.

  u_int use_multiple_priority_;
  // flag to indicate we are to use multiple priorities for the low
  // priority clients.  By default we use only one priority for all
  // client threads.

  int utilization_task_started_;
  // Indicates whether the utilization task has started.

  ACE_High_Res_Timer timer_;
  // global timer to be started by the utilization task.

  u_int util_time_;
  // the amount of time in seconds that the utilization test will run.

  int ready_;
  // ready flag used by the high priority thread to wake up the low
  // priority threads after it's parsed the arguments.

  ACE_SYNCH_MUTEX ready_mtx_;
  // mutex for the condition variable.

  ACE_Condition<ACE_SYNCH_MUTEX> ready_cnd_;
  // condition variable for the low priority threads to wait
  //until the high priority thread is done with the arguments parsing.

  u_int remote_invocations_;
  // flag to indicate whether we make remote versus local invocations
  // to calculate accurately the ORB overhead.

  ACE_timer_t util_test_time_;
  // holds the total time for the utilization test to complete.
};

class Client : public ACE_Task<ACE_SYNCH>
{
  // = TITLE
  //     The Cubit client.
  //
  // = DESCRIPTION
  //     This class implements the Cubit Client, which is an active object.
  //     `n' threads execute svc, and make 2way CORBA calls on the server
public:
  Client (ACE_Thread_Manager *,
          Task_State *ts,
          int argc,
          char **argv,
          u_int id);
  // Constructor, with a pointer to the common task state.

  ~Client (void);
  // destructor.

  virtual int svc (void);
  // The thread function.

  ACE_timer_t get_high_priority_latency (void);
  // Returns the latency of the high priority thread in usecs.

  ACE_timer_t get_low_priority_latency (void);
  // Returns the average latency found for the low 
  // priority threads in usecs.

  ACE_timer_t get_high_priority_jitter (void);
  // Returns the high priority jitter in usecs.

  ACE_timer_t get_low_priority_jitter (void);
  // Returns the jitter for all the low priority 
  // thread request in usecs.

  ACE_timer_t get_latency (u_int thread_id);
  // gets the average latency for that thread.

  ACE_timer_t get_jitter (u_int id);
  // gets the jitter for this thread.

  static int func (u_int i);
  // Arbitrary generator used by the client to create the numbers to be
  // cubed.

private:
  int init_orb (void);
  // initialize the ORB.

  int get_cubit_from_naming (void);
  // initialize the naming service.

  void read_ior (void);
  // reads the cubit ior from a file.

  int get_cubit (void);
  // gets the cubit object.

  int run_tests (void);
  // Run the various tests.

  int make_request (void);
  // make a CORBA request depending on the datatype.

  int do_test (void);
  // makes the corba requests.

  int cube_octet (void);
  // call cube_octet method on the cubit object.

  int cube_short (void);
  // call cube short on the cubit object.
  
  int cube_long (void);
  // call cube long on the cubit object.

  int cube_struct (void);
  // call cube struct on the cubit object.

  void print_stats (void);
  // prints the latency stats.

  void put_latency (JITTER_ARRAY *jitter,
                    ACE_timer_t latency,
                    u_int thread_id,
                    u_int count);
  // Records the latencies in the <Task_State>.

  int parse_args (int, char **);
  // Parses the arguments.

  void find_frequency (void);
  // determines the frequency at which to make calls depending on the
  // id of the thread.

  ACE_timer_t calc_delta (ACE_timer_t real_time,
                          ACE_timer_t delta);
  // calculate the delta value.

  Cubit_ptr cubit_;
  // pointer to the cubit object.

  Cubit_i *cubit_impl_;
  // cubit implementation object.

  Task_State *ts_;
  // Pointer to shared state.

  u_int num_;
  // number used for cubing.

  u_int id_;
  // unique id of the task

  u_int call_count_;
  // count of the number of calls made.

  u_int error_count_;
  // number of calls that failed.

  CosNaming::NamingContext_var mt_cubit_context_;
  // Object reference to the cubit context "MT_Cubit".

  TAO_Naming_Client my_name_client_;
  // Naming Client intermediary to naming service stuff.

  JITTER_ARRAY *my_jitter_array_;
  // ACE Unbounded set holding the latency values for all the
  // requests of this thread.

  MT_Cubit_Timer *timer_;
  // Timer using pccTimer for chorus and ACE_Timer for other platforms.

  ACE_timer_t frequency_;
  // frequency of CORBA requests.

  CORBA::ORB_var orb_;
  // ORB pointer.
  
  u_int naming_success_;
  // flag indicating the success of naming service.

  ACE_timer_t latency_;
  // aggregate latency of the requests.

  // command-line arguments.
  int argc_;
  char **argv_;
};

#endif /* !defined (TASK_CLIENT_H) */