Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / examples / Simulator / Event_Supplier / Logging_Sup.cpp
blob19c3243803f62954501d9b159a322beaf304f3fd
2 //=============================================================================
3 /**
4 * @file Logging_Sup.cpp
6 * Event Supplier for visualizing scheduling behavior, using arrival
7 * and dispatch data logged by an event channel dispatch command object
9 * @author Chris Gill (cdgill@cs.wustl.edu) Adapted from the DOVE simulation event supplier originally David Levine (levine@cs.wustl.edu) and Tim Harrison (harrison@cs.wustl.edu) modified Michael Kircher (mk1@cs.wustl.edu)
11 //=============================================================================
14 #include "Logging_Sup.h"
15 #include "NavWeapC.h"
17 #include "orbsvcs/Event_Utilities.h"
18 #include "orbsvcs/Event_Service_Constants.h"
19 #include "orbsvcs/Scheduler_Factory.h"
20 #include "orbsvcs/RtecEventChannelAdminC.h"
22 #include "tao/Utils/ORB_Manager.h"
24 #include "ace/Get_Opt.h"
25 #include "ace/Sched_Params.h"
26 #include "ace/OS_NS_stdio.h"
27 #include "ace/OS_NS_unistd.h"
28 #include "ace/OS_NS_string.h"
29 #include "ace/OS_NS_ctype.h"
31 static const char usage [] =
32 "[[-?]\n"
33 " [-O[RBport] ORB port number]\n"
34 " [-m <count> of messages to send [100]\n"
35 " [-f name of scheduler input data file]\n"
36 " [-d name of scheduler header dump file]\n"
37 " [-s to suppress data updates by EC]]\n";
40 Logging_Supplier::Logging_Supplier (int argc, ACE_TCHAR** argv)
41 : argc_(argc),
42 argv_(argv),
43 total_messages_(10),
44 input_file_name_(0),
45 update_data_ (1),
46 schedule_file_name_(0)
48 navigation_.roll = navigation_.pitch = 0;
51 Logging_Supplier::~Logging_Supplier ()
53 this->dOVE_Supplier_.disconnect ();
56 int
57 Logging_Supplier::init ()
59 this->get_options (argc_, argv_);
60 return this->dOVE_Supplier_.connect ();
63 void
64 Logging_Supplier::start_generating_events ()
66 unsigned long total_sent = 0;
68 // Load the scheduling data for the simulation.
69 ACE_Unbounded_Queue<Schedule_Viewer_Data *> schedule_data;
70 this->load_schedule_data (schedule_data);
71 ACE_Unbounded_Queue_Iterator<Schedule_Viewer_Data *>
72 schedule_iter (schedule_data);
74 if (schedule_iter.done ())
76 ACE_ERROR ((LM_ERROR,
77 "DOVE_Supplier::start_generating_events: "
78 "there is no scheduling data\n"));
79 return;
82 CORBA::Any any;
86 // Insert the event data
87 this->insert_event_data (any,
88 schedule_iter);
90 // deliver it over the wire
91 dOVE_Supplier_.notify (any);
93 if (total_sent < 5)
94 ACE_DEBUG ((LM_DEBUG,
95 "Pushing event data.\n"));
96 else if (total_sent == 5)
97 ACE_DEBUG ((LM_DEBUG,
98 "Everything is running. Going to be mute.\n"));
100 while (++total_sent < this->total_messages_);
102 // clean up the scheduling data
103 Schedule_Viewer_Data **data_temp;
104 for (schedule_iter.first ();
105 schedule_iter.done () == 0;
106 schedule_iter.advance ())
107 if (schedule_iter.next (data_temp) && data_temp)
108 delete (*data_temp);
111 void
112 Logging_Supplier::load_schedule_data
113 (ACE_Unbounded_Queue<Schedule_Viewer_Data *> &schedule_data)
115 Schedule_Viewer_Data *data = 0;
117 if (this->input_file_name_)
119 // Open the scheduler data input file and read its contents into
120 // a queue.
121 FILE *input_file;
123 int scan_count = 0;
124 input_file = ACE_OS::fopen(this->input_file_name_, "r");
126 if (input_file)
128 // Get a line at a time from the data file and parse it.
129 char input_buf[BUFSIZ];
130 while (ACE_OS::fgets (input_buf, BUFSIZ, input_file))
132 // Run through leading whitespace.
133 char *temp = input_buf;
134 while (*temp && ACE_OS::ace_isspace (*temp))
135 ++temp;
137 // If there is anything besides whitespace in the line
138 // read, scan its fields into the scheduling data
139 // structure.
140 if (ACE_OS::strlen (temp) > 0)
142 ACE_NEW (data, Schedule_Viewer_Data);
143 scan_count = sscanf (temp, "%s %lf %lf %lu %lu %lu %lu",
144 data->operation_name,
145 &data->utilitzation,
146 &data->overhead,
147 &data->arrival_time,
148 &data->deadline_time,
149 &data->completion_time,
150 &data->computation_time);
151 if (scan_count != 7)
153 ACE_ERROR ((LM_ERROR,
154 "DOVE_Supplier::start_generating_events: "
155 "scanned incorrect number of data elements: %d\n", scan_count));
157 delete data;
158 return;
161 // Insert the data into the queue.
162 schedule_data.enqueue_tail (data);
166 else
168 ACE_ERROR ((LM_ERROR,
169 "DOVE_Supplier::start_generating_events: "
170 "could not open input file [%s].\n",
171 this->input_file_name_));
172 return;
175 else
177 u_long last_completion = 0;
179 // Just create 10 dummy scheduling records and use them.
180 for (int i = 0; i < 10; ++i)
182 ACE_NEW (data, Schedule_Viewer_Data);
184 const char *oper_name = 0;
185 switch (i % 4)
187 case 0:
188 oper_name = "high_20";
189 break;
191 case 1:
192 oper_name = "low_20";
193 break;
195 case 2:
196 oper_name = "high_10";
197 break;
199 case 3:
200 default:
201 oper_name = "low_10";
202 break;
205 ACE_OS::strncpy (data->operation_name,
206 oper_name,
207 BUFSIZ-1);
209 data->utilitzation = (double)(20.0+ACE_OS::rand() %10);
210 data->overhead = (double)(ACE_OS::rand() %20);
212 data->arrival_time = ACE_OS::rand() % 200;
213 data->computation_time = (ACE_OS::rand() % 100) + 10;
215 data->completion_time = last_completion + (ACE_OS::rand() % 100) + 100;
216 data->completion_time =
217 data->completion_time < data->arrival_time + data->computation_time
218 ? data->arrival_time + data->computation_time
219 : data->completion_time;
221 last_completion = data->completion_time;
223 data->deadline_time = data->completion_time + (ACE_OS::rand() % 200) - 50;
225 // insert the data into the queue.
226 schedule_data.enqueue_tail (data);
231 // This function fills in the random data into the anys transported by
232 // the event channel.
234 void
235 Logging_Supplier::insert_event_data (CORBA::Any &data,
236 ACE_Unbounded_Queue_Iterator<Schedule_Viewer_Data *> &schedule_iter)
238 static u_long last_completion = 0;
240 // constants for periods (in units of one hundred nanoseconds)
241 const TimeBase::TimeT ONE_HZ_PERIOD = 10000000;
242 const TimeBase::TimeT FIVE_HZ_PERIOD = ONE_HZ_PERIOD / 5 ;
243 const TimeBase::TimeT TEN_HZ_PERIOD = ONE_HZ_PERIOD / 10;
244 const TimeBase::TimeT TWENTY_HZ_PERIOD = ONE_HZ_PERIOD / 20;
248 Schedule_Viewer_Data **sched_data;
250 if ((schedule_iter.next (sched_data)) && (sched_data) && (*sched_data))
252 if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_20") == 0) ||
253 (ACE_OS::strcmp((*sched_data)->operation_name, "low_20") == 0) ||
254 (ACE_OS::strcmp((*sched_data)->operation_name, "high_1") == 0) ||
255 (ACE_OS::strcmp((*sched_data)->operation_name, "low_1") == 0))
257 if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_20") == 0) ||
258 (ACE_OS::strcmp((*sched_data)->operation_name, "high_1") == 0))
260 navigation_.criticality = 1;
262 else
264 navigation_.criticality = 0;
267 if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_20") == 0) ||
268 (ACE_OS::strcmp((*sched_data)->operation_name, "low_20") == 0))
270 navigation_.deadline_time = TWENTY_HZ_PERIOD;
272 else
274 navigation_.deadline_time = ONE_HZ_PERIOD;
277 navigation_.position_latitude = ACE_OS::rand() % 90;
278 navigation_.position_longitude = ACE_OS::rand() % 180;
279 navigation_.altitude = ACE_OS::rand() % 100;
280 navigation_.heading = ACE_OS::rand() % 180;
281 navigation_.roll = (navigation_.roll >= 180) ? -180 : navigation_.roll + 1;
282 navigation_.pitch = (navigation_.pitch >= 90) ? -90 : navigation_.pitch + 1;
284 navigation_.utilization = 0.0;
285 navigation_.overhead = 0.0;
286 navigation_.arrival_time = ORBSVCS_Time::zero ();
287 navigation_.completion_time = ORBSVCS_Time::zero ();
288 navigation_.computation_time = ORBSVCS_Time::zero ();
289 navigation_.update_data = update_data_;
292 // because the scheduler data does not supply these values
293 navigation_.utilization = (double) (20.0 + ACE_OS::rand() % 10);
294 navigation_.overhead = (double) (ACE_OS::rand() % 10);
296 data <<= navigation_;
298 else if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_10") == 0) ||
299 (ACE_OS::strcmp((*sched_data)->operation_name, "low_10") == 0) ||
300 (ACE_OS::strcmp((*sched_data)->operation_name, "high_5") == 0) ||
301 (ACE_OS::strcmp((*sched_data)->operation_name, "low_5") == 0))
303 if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_10") == 0) ||
304 (ACE_OS::strcmp((*sched_data)->operation_name, "high_5") == 0))
306 weapons_.criticality = 1;
308 else
310 weapons_.criticality = 0;
313 if ((ACE_OS::strcmp((*sched_data)->operation_name, "high_10") == 0) ||
314 (ACE_OS::strcmp((*sched_data)->operation_name, "low_10") == 0))
316 weapons_.deadline_time = TEN_HZ_PERIOD;
318 else
320 weapons_.deadline_time = FIVE_HZ_PERIOD;
324 weapons_.number_of_weapons = 2;
325 weapons_.weapon1_identifier = CORBA::string_alloc (30);
326 ACE_OS::strcpy (weapons_.weapon1_identifier.inout (),"Photon Torpedoes");
327 weapons_.weapon1_status =(ACE_OS::rand() % 4) == 0 ? 0 : 1 ;
328 weapons_.weapon2_identifier = CORBA::string_alloc (30);
329 ACE_OS::strcpy (weapons_.weapon2_identifier.inout (),"Quantum Torpedoes");
330 weapons_.weapon2_status = (ACE_OS::rand() % 4) == 0 ? 0 : 1;
331 weapons_.weapon3_identifier = CORBA::string_alloc (1);
332 ACE_OS::strcpy (weapons_.weapon3_identifier.inout (), "");
333 weapons_.weapon3_status = 0;
334 weapons_.weapon4_identifier = CORBA::string_alloc (1);
335 ACE_OS::strcpy (weapons_.weapon4_identifier.inout (), "");
336 weapons_.weapon4_status = 0;
337 weapons_.weapon5_identifier = CORBA::string_alloc (1);
338 ACE_OS::strcpy (weapons_.weapon5_identifier.inout (), "");
339 weapons_.weapon5_status = 0;
340 weapons_.utilization = 0.0;
341 weapons_.overhead = 0.0;
342 weapons_.arrival_time = ORBSVCS_Time::zero ();
343 weapons_.completion_time = ORBSVCS_Time::zero ();
344 weapons_.computation_time = ORBSVCS_Time::zero ();
345 weapons_.update_data = update_data_;
348 data <<= weapons_;
350 else {
351 ACE_ERROR ((LM_ERROR,
352 "Logging_Supplier::insert_event_data:"
353 "unrecognized operation name [%s]",
354 (*sched_data)->operation_name));
358 if (last_completion > (*sched_data)->completion_time)
359 last_completion = 0;
361 if ((*sched_data)->completion_time >= last_completion)
363 ACE_Time_Value pause (0,
364 (*sched_data)->completion_time -
365 last_completion);
366 ACE_OS::sleep (pause);
367 last_completion = (*sched_data)->completion_time;
370 else
371 ACE_ERROR ((LM_ERROR,
372 "Logging_Supplier::insert_event_data:"
373 "Could Not access scheduling data"));
375 schedule_iter.advance ();
377 if (schedule_iter.done ())
378 schedule_iter.first ();
380 catch (const CORBA::Exception&)
382 ACE_ERROR ((LM_ERROR,
383 "(%t)Error in Logging_Supplier::insert_event_data.\n"));
387 // Function get_options.
388 unsigned int
389 Logging_Supplier::get_options (int argc, ACE_TCHAR *argv [])
391 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("f:m:d:s"));
392 int opt;
393 int temp;
395 while ((opt = get_opt ()) != -1)
397 switch (opt)
399 case 'm':
400 temp = ACE_OS::atoi (get_opt.opt_arg ());
401 if (temp > 0)
403 this->total_messages_ = (u_int) temp;
404 ACE_DEBUG ((LM_DEBUG,
405 "Messages to send: %d\n",
406 this->total_messages_));
408 else
409 ACE_ERROR_RETURN ((LM_ERROR,
410 "%s: count must be > 0",
411 argv[0]),
413 break;
414 case 'f':
415 this->input_file_name_ = get_opt.opt_arg ();
417 if (!this->input_file_name_ || ACE_OS::strlen (this->input_file_name_) > 0)
418 ACE_DEBUG ((LM_DEBUG,"Reading file!\n"));
419 else
421 this->input_file_name_ = 0;
422 ACE_ERROR_RETURN ((LM_ERROR,
423 "%s: file name must be specified with -f option",
424 argv[0]),
427 break;
428 case 'd':
429 this->schedule_file_name_ = get_opt.opt_arg ();
431 if (!this->schedule_file_name_ || ACE_OS::strlen (this->schedule_file_name_) > 0)
432 ACE_DEBUG ((LM_DEBUG,"Dumping file!\n"));
433 else
435 this->input_file_name_ = 0;
436 ACE_ERROR_RETURN ((LM_ERROR,
437 "%s: file name must be specified with -d option",
438 argv[0]),
441 break;
442 case 's':
443 update_data_ = 0;
444 break;
445 default:
446 case '?':
447 ACE_DEBUG ((LM_DEBUG,
448 "Usage: %s %s\n",
449 argv[0], usage));
450 ACE_OS::exit (0);
451 break;
455 if (argc != get_opt.opt_ind ())
456 ACE_ERROR_RETURN ((LM_ERROR,
457 "%s: too many arguments\n"
458 "Usage: %s %s\n",
459 argv[0],
460 argv[0],
461 usage),
464 return 0;
467 // function main
470 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
474 // Initialize ORB.
475 TAO_ORB_Manager orb_Manager;
477 orb_Manager.init (argc,
478 argv);
481 // Create the demo supplier.
482 Logging_Supplier *event_Supplier_ptr;
484 ACE_NEW_RETURN (event_Supplier_ptr,
485 Logging_Supplier(argc, argv),
486 -1);
488 // Initialize everthing
489 if (event_Supplier_ptr->init () == -1)
490 ACE_OS::exit (1);
492 // now we can go ahead
493 event_Supplier_ptr->start_generating_events ();
495 // when done, we clean up
496 delete event_Supplier_ptr;
498 catch (const CORBA::Exception& ex)
500 ex._tao_print_exception ("SYS_EX");
503 return 0;