2 //=============================================================================
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"
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
[] =
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
)
46 schedule_file_name_(0)
48 navigation_
.roll
= navigation_
.pitch
= 0;
51 Logging_Supplier::~Logging_Supplier ()
53 this->dOVE_Supplier_
.disconnect ();
57 Logging_Supplier::init ()
59 this->get_options (argc_
, argv_
);
60 return this->dOVE_Supplier_
.connect ();
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 ())
77 "DOVE_Supplier::start_generating_events: "
78 "there is no scheduling data\n"));
86 // Insert the event data
87 this->insert_event_data (any
,
90 // deliver it over the wire
91 dOVE_Supplier_
.notify (any
);
95 "Pushing event data.\n"));
96 else if (total_sent
== 5)
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
)
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
124 input_file
= ACE_OS::fopen(this->input_file_name_
, "r");
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
))
137 // If there is anything besides whitespace in the line
138 // read, scan its fields into the scheduling data
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
,
148 &data
->deadline_time
,
149 &data
->completion_time
,
150 &data
->computation_time
);
153 ACE_ERROR ((LM_ERROR
,
154 "DOVE_Supplier::start_generating_events: "
155 "scanned incorrect number of data elements: %d\n", scan_count
));
161 // Insert the data into the queue.
162 schedule_data
.enqueue_tail (data
);
168 ACE_ERROR ((LM_ERROR
,
169 "DOVE_Supplier::start_generating_events: "
170 "could not open input file [%s].\n",
171 this->input_file_name_
));
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;
188 oper_name
= "high_20";
192 oper_name
= "low_20";
196 oper_name
= "high_10";
201 oper_name
= "low_10";
205 ACE_OS::strncpy (data
->operation_name
,
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.
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;
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
;
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;
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
;
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_
;
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
)
361 if ((*sched_data
)->completion_time
>= last_completion
)
363 ACE_Time_Value
pause (0,
364 (*sched_data
)->completion_time
-
366 ACE_OS::sleep (pause
);
367 last_completion
= (*sched_data
)->completion_time
;
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.
389 Logging_Supplier::get_options (int argc
, ACE_TCHAR
*argv
[])
391 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("f:m:d:s"));
395 while ((opt
= get_opt ()) != -1)
400 temp
= ACE_OS::atoi (get_opt
.opt_arg ());
403 this->total_messages_
= (u_int
) temp
;
404 ACE_DEBUG ((LM_DEBUG
,
405 "Messages to send: %d\n",
406 this->total_messages_
));
409 ACE_ERROR_RETURN ((LM_ERROR
,
410 "%s: count must be > 0",
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"));
421 this->input_file_name_
= 0;
422 ACE_ERROR_RETURN ((LM_ERROR
,
423 "%s: file name must be specified with -f option",
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"));
435 this->input_file_name_
= 0;
436 ACE_ERROR_RETURN ((LM_ERROR
,
437 "%s: file name must be specified with -d option",
447 ACE_DEBUG ((LM_DEBUG
,
455 if (argc
!= get_opt
.opt_ind ())
456 ACE_ERROR_RETURN ((LM_ERROR
,
457 "%s: too many arguments\n"
470 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
475 TAO_ORB_Manager orb_Manager
;
477 orb_Manager
.init (argc
,
481 // Create the demo supplier.
482 Logging_Supplier
*event_Supplier_ptr
;
484 ACE_NEW_RETURN (event_Supplier_ptr
,
485 Logging_Supplier(argc
, argv
),
488 // Initialize everthing
489 if (event_Supplier_ptr
->init () == -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");