summaryrefslogtreecommitdiff
path: root/TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.h
blob: 818ccc448f58ea0ce4fcc743154e52756ba7ba00 (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
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file    Task_Client.h
 *
 *  @author Andy Gokhale
 *  @author Sumedh Mungee
 *  @author Sergio Flores-Gaitan
 *  @author and Nagarajan Surendran.
 */
//=============================================================================


#ifndef TASK_CLIENT_H
#define TASK_CLIENT_H

#include "ace/config-all.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#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 "cubitC.h"
#include "cubit_i.h"
#include "Globals.h"
#include "Timer.h"

// FUZZ: disable check_for_math_include
#if !defined (__xlC__)
    // Some plaforms define an exception structure in math.h...
# if defined (__GNUG__)
    // And some compilers have this workaround.  Disable it with this
    // #define, to avoid warning about multiple #defines of exception.
#   define _MATH_H_WRAPPER
# endif /* __GNUG__ */
# define exception _math_exception
# include /**/ <math.h>
# undef exception
#else
# include /**/ <math.h>
#endif

#if defined (ACE_HAS_QUANTIFY)
# define START_QUANTIFY quantify_start_recording_data ();
# define STOP_QUANTIFY quantify_stop_recording_data();
# define CLEAR_QUANTIFY quantify_clear_data ();
#else /* ! ACE_HAS_QUANTIFY */
# define START_QUANTIFY
# define STOP_QUANTIFY
# define CLEAR_QUANTIFY
#endif /* ! ACE_HAS_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_Queue<ACE_timer_t> JITTER_ARRAY;
typedef ACE_Unbounded_Queue_Iterator<ACE_timer_t> JITTER_ARRAY_ITERATOR;

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

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

  /// Destructor
  ~Task_State (void);

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

  /// All cubit objects will have this as prefix to its key.
  const char *key_;

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

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

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

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

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

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

  /// Flag for the thread_per_rate test.
  u_int thread_per_rate_;

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

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

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

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

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

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

  /// flag to run context switch test
  u_int context_switch_test_;

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

  /// count on the number of iors
  int iors_count_;

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

  /**
   * 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 granularity_;

  /**
   * 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 use_utilization_test_;

  /**
   * 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.
   */
  u_int high_priority_loop_count_;

  /**
   * 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.
   */
  ACE_SYNCH_SEMAPHORE *semaphore_;

  /**
   * 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.
   */
  u_int use_multiple_priority_;

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

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

  /// mutex for the condition variable.
  TAO_SYNCH_MUTEX ready_mtx_;

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

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

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

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

  /// destructor.
  ~Client (void);

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

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

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

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

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

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

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

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

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

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

  /// gets the cubit object.
  int get_cubit (CORBA::ORB_ptr orb);

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

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

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

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

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

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

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

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

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

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

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

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

  /// pointer to the cubit object.
  Cubit_ptr cubit_;

  /// cubit implementation object.
  Cubit_i cubit_impl_;

  /// Pointer to shared state.
  Task_State *ts_;

  /// number used for cubing.
  u_int num_;

  /// unique id of the task
  u_int id_;

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

  /// number of calls that failed.
  u_int error_count_;

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

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

  /// frequency of CORBA requests.
  ACE_timer_t frequency_;

  /// aggregate latency of the requests.
  ACE_timer_t latency_;

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

#endif /* !defined (TASK_CLIENT_H) */