Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / examples / Simulator / Event_Supplier / DualEC_Sup.cpp
blobfb2b427f3248466c799431f1cb5e94374d268ce4
2 //=============================================================================
3 /**
4 * @file DualEC_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 "DualEC_Sup.h"
15 #include "NavWeapC.h"
17 #include "orbsvcs/Event_Utilities.h"
18 #include "orbsvcs/Event_Service_Constants.h"
19 #include "orbsvcs/Event/EC_Event_Channel.h"
20 #include "orbsvcs/Sched/Config_Scheduler.h"
21 #include "orbsvcs/Runtime_Scheduler.h"
22 #include "orbsvcs/RtecEventChannelAdminC.h"
24 #include "tao/Utils/ORB_Manager.h"
25 #include "tao/ORB_Core.h"
27 #include "ace/Get_Opt.h"
28 #include "ace/Sched_Params.h"
29 #include "ace/OS_NS_errno.h"
30 #include "ace/OS_NS_ctype.h"
32 //FUZZ: disable check_for_lack_ACE_OS
33 static const char usage [] =
34 "[[-?]\n"
35 " -f <name of input data file>\n"
36 " [-O[RBport] ORB port number]\n"
37 " [-m <count> of messages to send (2000)]\n"
38 " [-b <count> at which to break navigation event\n"
39 " stream out onto its own channel (1000)]\n"
40 " [-n <usec> pause between navigation events (100000)]\n"
41 " [-w <usec> pause between weapons events (100000)]\n"
42 " [-d to dump scheduler header files]\n"
43 " [-s to suppress data updates by EC]\n"
44 " [-r to use runtime schedulers]\n"
45 " [-p to suppress prioritization of operations]\n";
46 //FUZZ: enable check_for_lack_ACE_OS
48 DualEC_Supplier::DualEC_Supplier (int argc, ACE_TCHAR** argv)
49 : nav_pause_ (0, 100000),
50 weap_pause_ (0, 100000),
51 channel_hi_name_ (1),
52 channel_lo_name_ (1),
53 sched_hi_name_ (1),
54 sched_lo_name_ (1),
55 sched_hi_impl_ (0),
56 sched_lo_impl_ (0),
57 ec_hi_impl_ (0),
58 ec_lo_impl_ (0),
59 argc_(argc),
60 argv_(argv),
61 total_messages_ (2000),
62 break_count_(-1),
63 input_file_name_(0),
64 update_data_ (1),
65 dump_schedule_headers_ (0),
66 use_runtime_schedulers_ (0),
67 suppress_priority_ (0),
68 hi_schedule_file_name_ (ACE_TEXT("DualEC_Runtime_Hi.h")),
69 lo_schedule_file_name_ (ACE_TEXT("DualEC_Runtime_Lo.h")),
70 nav_roll_ (0),
71 nav_pitch_ (0)
73 try
75 this->sched_hi_name_.length (1);
76 this->sched_hi_name_[0].id = CORBA::string_dup ("DUAL_SCHED_HI");
78 this->sched_lo_name_.length (1);
79 this->sched_lo_name_[0].id = CORBA::string_dup ("DUAL_SCHED_LO");
81 this->channel_hi_name_.length (1);
82 this->channel_hi_name_[0].id = CORBA::string_dup ("DUAL_EC_HI");
84 this->channel_lo_name_.length (1);
85 this->channel_lo_name_[0].id = CORBA::string_dup ("DUAL_EC_LO");
87 this->terminator_ = terminator_impl_._this ();
89 catch (const CORBA::Exception& ex)
91 ex._tao_print_exception (
92 "DualEC_Supplier::DualEC_Supplier : could "
93 "not resolve reference to terminator");
96 // Initialize the high priority RT_Info data
97 rt_info_nav_hi_.entry_point = "DUALEC_NAV_HI";
98 rt_info_nav_hi_.criticality = RtecScheduler::VERY_HIGH_CRITICALITY;
99 rt_info_nav_hi_.worst_case_execution_time = ORBSVCS_Time::zero ();
100 rt_info_nav_hi_.typical_execution_time = ORBSVCS_Time::zero ();
101 rt_info_nav_hi_.cached_execution_time = ORBSVCS_Time::zero ();
102 rt_info_nav_hi_.period = 2500000;
103 rt_info_nav_hi_.importance = RtecScheduler::VERY_HIGH_IMPORTANCE;
104 rt_info_nav_hi_.quantum = ORBSVCS_Time::zero ();
105 rt_info_nav_hi_.threads = 1;
106 rt_info_nav_hi_.info_type = RtecScheduler::OPERATION;
107 rt_info_weap_hi_ = rt_info_nav_hi_;
108 rt_info_weap_hi_.entry_point = "DUALEC_WEAP_HI";
109 rt_info_dummy_hi_ = rt_info_nav_hi_;
110 rt_info_dummy_hi_.entry_point = "DUALEC_DUMMY_HI";
112 // Initialize the low priority RT_Info data
113 rt_info_nav_lo_.entry_point = "DUALEC_NAV_LO";
114 rt_info_nav_lo_.criticality = RtecScheduler::VERY_LOW_CRITICALITY;
115 rt_info_nav_lo_.worst_case_execution_time = ORBSVCS_Time::zero ();
116 rt_info_nav_lo_.typical_execution_time = ORBSVCS_Time::zero ();
117 rt_info_nav_lo_.cached_execution_time = ORBSVCS_Time::zero ();
118 rt_info_nav_lo_.period = 10000000;
119 rt_info_nav_lo_.importance = RtecScheduler::VERY_LOW_IMPORTANCE;
120 rt_info_nav_lo_.quantum = ORBSVCS_Time::zero ();
121 rt_info_nav_lo_.threads = 1;
122 rt_info_nav_lo_.info_type = RtecScheduler::OPERATION;
123 rt_info_weap_lo_ = rt_info_nav_lo_;
124 rt_info_weap_lo_.entry_point = "DUALEC_WEAP_LO";
125 rt_info_dummy_lo_ = rt_info_nav_lo_;
126 rt_info_dummy_lo_.entry_point = "DUALEC_DUMMY_LO";
129 DualEC_Supplier::~DualEC_Supplier ()
133 this->navigation_Supplier_.disconnect ();
134 this->weapons_Supplier_.disconnect ();
136 // Unbind the schedulers from the NS.
137 this->naming_context_->unbind (this->sched_hi_name_);
138 this->naming_context_->unbind (this->sched_lo_name_);
140 // Unbind the ECs from the NS.
141 this->naming_context_->unbind (this->channel_hi_name_);
142 this->naming_context_->unbind (this->channel_lo_name_);
144 catch (const CORBA::Exception& ex)
146 ex._tao_print_exception ("DualEC_Supplier::~DualEC_Supplier");
149 // @@TBD - destroy the ECs
150 // @@TBD - destroy the schedulers
154 DualEC_Supplier::init ()
156 this->get_options (argc_, argv_);
160 // Connect to the RootPOA.
161 CORBA::Object_var poaObject_var =
162 TAO_ORB_Core_instance()->orb()->resolve_initial_references("RootPOA");
164 if (CORBA::is_nil (poaObject_var.in ()))
165 ACE_ERROR_RETURN ((LM_ERROR,
166 " (%P|%t) Unable to initialize the POA.\n"),
169 this->root_POA_var_ =
170 PortableServer::POA::_narrow (poaObject_var.in ());
172 this->poa_manager_ =
173 root_POA_var_->the_POAManager ();
175 poa_manager_->activate ();
177 // Get the Naming Service object reference.
178 CORBA::Object_var namingObj_var =
179 TAO_ORB_Core_instance()->orb()->resolve_initial_references (
180 "NameService");
182 if (CORBA::is_nil (namingObj_var.in ()))
183 ACE_ERROR_RETURN ((LM_ERROR,
184 " (%P|%t) Unable to get the Naming Service.\n"),
185 -1);
187 this->naming_context_ =
188 CosNaming::NamingContext::_narrow (namingObj_var.in ());
191 catch (const CORBA::Exception& ex)
193 ex._tao_print_exception ("DualEC_Supplier::init");
194 return -1;
197 // Create two scheduling service instances.
198 if (this->create_schedulers () == -1)
200 ACE_ERROR_RETURN ((LM_ERROR,
201 "Could not create schedulers"),
202 -1);
205 // Create two event channels.
206 if (this->create_event_channels () == -1)
208 ACE_ERROR_RETURN ((LM_ERROR,
209 "Could not create event channels"),
210 -1);
213 // Connect suppliers to the respective event channels.
214 ACE_Scheduler_Factory::POD_RT_Info * rt_info_nav_hi =
215 (suppress_priority_) ? 0 : &rt_info_nav_hi_;
216 ACE_Scheduler_Factory::POD_RT_Info * rt_info_weap_hi =
217 (suppress_priority_) ? 0 : &rt_info_weap_hi_;
218 ACE_Scheduler_Factory::POD_RT_Info * rt_info_nav_lo =
219 (suppress_priority_) ? 0 : &rt_info_nav_lo_;
220 ACE_Scheduler_Factory::POD_RT_Info * rt_info_weap_lo =
221 (suppress_priority_) ? 0 : &rt_info_weap_lo_;
223 if (this->navigation_Supplier_.connect ("MIB_unknown",
224 "DUAL_EC_HI",
225 "DUAL_SCHED_HI",
226 rt_info_nav_hi) == -1)
228 ACE_ERROR_RETURN ((LM_ERROR,
229 "Could not connect navigation supplier to DUAL_EC_HI"),
230 -1);
233 if (this->navigation_Supplier_.connect ("MIB_unknown",
234 "DUAL_EC_LO",
235 "DUAL_SCHED_LO",
236 rt_info_nav_lo) == -1)
238 ACE_ERROR_RETURN ((LM_ERROR,
239 "Could not connect navigation supplier to DUAL_EC_LO"),
240 -1);
243 if (this->weapons_Supplier_.connect ("MIB_unknown",
244 "DUAL_EC_HI",
245 "DUAL_SCHED_HI",
246 rt_info_weap_hi) == -1)
248 ACE_ERROR_RETURN ((LM_ERROR,
249 "Could not connect weapons supplier to DUAL_EC_HI"),
250 -1);
253 if (this->weapons_Supplier_.connect ("MIB_unknown",
254 "DUAL_EC_LO",
255 "DUAL_SCHED_LO",
256 rt_info_weap_lo) == -1)
258 ACE_ERROR_RETURN ((LM_ERROR,
259 "Could not connect weapons supplier to DUAL_EC_LO"),
260 -1);
263 return 0;
266 // Private class that implements a termination servant.
268 void
269 DualEC_Supplier::Terminator::shutdown (void)
271 TAO_ORB_Core_instance ()->orb ()->shutdown ();
275 // Run the ORB event loop.
277 ACE_THR_FUNC_RETURN
278 DualEC_Supplier::run_orb (void *)
280 TAO_ORB_Core_instance ()->orb ()->run ();
281 return 0;
285 // Run navigation event generation thread.
287 ACE_THR_FUNC_RETURN
288 DualEC_Supplier::run_nav_thread (void *arg)
290 DualEC_Supplier * sup =
291 static_cast<DualEC_Supplier *> (arg);
295 ACE_Unbounded_Queue_Iterator<Navigation *>
296 nav_iter (sup->navigation_data_);
298 if (nav_iter.done ())
300 ACE_ERROR_RETURN ((LM_ERROR,
301 "DualEC_Supplier::run_event_thread: "
302 "there is no navigation data\n"), 0);
305 CORBA::Any any;
307 long total_sent = 0;
311 // Insert the event data
312 Navigation **nav;
314 if ((nav_iter.next (nav)) && (nav) && (*nav))
316 any <<= *nav;
318 // Sleep briefly to avoid too much livelock (a little is good).
319 ACE_OS::sleep (sup->nav_pause_);
321 // If the break count has been reached, change the
322 // channel that is being used by the NAV supplier
323 if (total_sent == sup->break_count_)
325 ACE_DEBUG ((LM_DEBUG,
326 "breaking out nav at event: %d\n",
327 sup->break_count_));
329 sup->navigation_Supplier_.use_next_connection ();
332 sup->navigation_Supplier_.notify (any);
334 else
336 ACE_ERROR ((LM_ERROR,
337 "DualEC_Supplier::run_nav_thread:"
338 "Could Not access navigation data"));
341 if (total_sent < 5)
342 ACE_DEBUG ((LM_DEBUG,
343 "Pushing event data.\n"));
344 else if (total_sent == 5)
345 ACE_DEBUG ((LM_DEBUG,
346 "Everything is running. Going to be mute.\n"));
348 nav_iter.advance ();
350 if (nav_iter.done ())
351 nav_iter.first ();
354 while (++total_sent < sup->total_messages_);
357 catch (const CORBA::Exception&)
361 return 0;
365 // Run weapons event generation thread.
367 ACE_THR_FUNC_RETURN
368 DualEC_Supplier::run_weap_thread (void *arg)
370 DualEC_Supplier * sup =
371 static_cast<DualEC_Supplier *> (arg);
375 ACE_Unbounded_Queue_Iterator<Weapons *>
376 weap_iter (sup->weapons_data_);
378 if (weap_iter.done ())
380 ACE_ERROR_RETURN ((LM_ERROR,
381 "DualEC_Supplier::run_event_thread: "
382 "there is no navigation data\n"), 0);
385 CORBA::Any any;
387 long total_sent = 0;
391 // Insert the event data
392 Weapons **weap;
394 if ((weap_iter.next (weap)) && (weap) && (*weap))
396 any <<= *weap;
398 // Sleep briefly to avoid too much livelock (a little is good).
399 ACE_OS::sleep (sup->weap_pause_);
401 sup->weapons_Supplier_.notify (any);
403 else
405 ACE_ERROR ((LM_ERROR,
406 "DualEC_Supplier::run_weap_thread:"
407 "Could Not access weapons data"));
410 if (total_sent < 5)
411 ACE_DEBUG ((LM_DEBUG,
412 "Pushing event data.\n"));
413 else if (total_sent == 5)
414 ACE_DEBUG ((LM_DEBUG,
415 "Everything is running. Going to be mute.\n"));
417 weap_iter.advance ();
419 if (weap_iter.done ())
420 weap_iter.first ();
423 while (++total_sent < sup->total_messages_);
426 catch (const CORBA::Exception&)
430 return 0;
435 // Create two scheduling service instances, register
436 // them with the Naming Service.
439 DualEC_Supplier::create_schedulers (void)
441 // @@TBD - look at a command line modified setting,
442 // create either a runtime or a config scheduler for
443 // each instance
447 if (use_runtime_schedulers_)
449 ACE_ERROR_RETURN ((LM_ERROR,
450 " (%P|%t) Runtime Schedulers not implemented\n"),
451 -1);
453 else
455 // Create Event Service Implementations, passing in the respective
456 // Scheduling Service Implementations (which must already be created).
458 ACE_NEW_RETURN (this->sched_hi_impl_,
459 ACE_Config_Scheduler,
460 -1);
462 this->sched_hi_ = sched_hi_impl_->_this ();
464 ACE_NEW_RETURN (this->sched_lo_impl_,
465 ACE_Config_Scheduler,
466 -1);
468 this->sched_lo_ = sched_lo_impl_->_this ();
470 // Register Scheduling Service Implementations with Naming Service
472 this->naming_context_->bind (this ->sched_hi_name_,
473 this->sched_hi_.in ());
475 naming_context_->bind (this->sched_lo_name_,
476 this->sched_lo_.in ());
478 // Register high and low priority rt_infos with the
479 // schedulers to force priority differentiation.
481 this->sched_hi_rt_info_hi_ =
482 this->sched_hi_->
483 create (this->rt_info_dummy_hi_.entry_point);
486 this->sched_hi_->
487 set (this->sched_hi_rt_info_hi_,
488 static_cast<RtecScheduler::Criticality_t> (this->rt_info_dummy_hi_.criticality),
489 this->rt_info_dummy_hi_.worst_case_execution_time,
490 this->rt_info_dummy_hi_.typical_execution_time,
491 this->rt_info_dummy_hi_.cached_execution_time,
492 this->rt_info_dummy_hi_.period,
493 static_cast<RtecScheduler::Importance_t> (this->rt_info_dummy_hi_.importance),
494 this->rt_info_dummy_hi_.quantum,
495 this->rt_info_dummy_hi_.threads,
496 static_cast<RtecScheduler::Info_Type_t> (this->rt_info_dummy_hi_.info_type));
499 this->sched_hi_rt_info_lo_ =
500 this->sched_hi_->
501 create (this->rt_info_dummy_lo_.entry_point);
504 this->sched_hi_->
505 set (this->sched_hi_rt_info_lo_,
506 static_cast<RtecScheduler::Criticality_t> (this->rt_info_dummy_lo_.criticality),
507 this->rt_info_dummy_lo_.worst_case_execution_time,
508 this->rt_info_dummy_lo_.typical_execution_time,
509 this->rt_info_dummy_lo_.cached_execution_time,
510 this->rt_info_dummy_lo_.period,
511 static_cast<RtecScheduler::Importance_t> (this->rt_info_dummy_lo_.importance),
512 this->rt_info_dummy_lo_.quantum,
513 this->rt_info_dummy_lo_.threads,
514 static_cast<RtecScheduler::Info_Type_t> (this->rt_info_dummy_lo_.info_type));
517 this->sched_hi_rt_info_hi_ =
518 this->sched_lo_->
519 create (this->rt_info_dummy_hi_.entry_point);
522 this->sched_lo_->
523 set (this->sched_hi_rt_info_hi_,
524 static_cast<RtecScheduler::Criticality_t> (this->rt_info_dummy_hi_.criticality),
525 this->rt_info_dummy_hi_.worst_case_execution_time,
526 this->rt_info_dummy_hi_.typical_execution_time,
527 this->rt_info_dummy_hi_.cached_execution_time,
528 this->rt_info_dummy_hi_.period,
529 static_cast<RtecScheduler::Importance_t> (this->rt_info_dummy_hi_.importance),
530 this->rt_info_dummy_hi_.quantum,
531 this->rt_info_dummy_hi_.threads,
532 static_cast<RtecScheduler::Info_Type_t> (this->rt_info_dummy_hi_.info_type));
535 this->sched_hi_rt_info_lo_ =
536 this->sched_lo_->
537 create (this->rt_info_dummy_lo_.entry_point);
540 this->sched_lo_->
541 set (this->sched_hi_rt_info_lo_,
542 static_cast<RtecScheduler::Criticality_t> (this->rt_info_dummy_lo_.criticality),
543 this->rt_info_dummy_lo_.worst_case_execution_time,
544 this->rt_info_dummy_lo_.typical_execution_time,
545 this->rt_info_dummy_lo_.cached_execution_time,
546 this->rt_info_dummy_lo_.period,
547 static_cast<RtecScheduler::Importance_t> (this->rt_info_dummy_lo_.importance),
548 this->rt_info_dummy_lo_.quantum,
549 this->rt_info_dummy_lo_.threads,
550 static_cast<RtecScheduler::Info_Type_t> (this->rt_info_dummy_lo_.info_type));
555 catch (const CORBA::Exception& ex)
557 ex._tao_print_exception ("DualEC_Supplier::create_schedulers");
558 return -1;
561 return 0;
565 // Create two event service instances, registers
566 // them with the Naming Service.
569 DualEC_Supplier::create_event_channels (void)
573 // Create Event Service Implementations, passing in the respective
574 // Scheduling Service Implementations (which must already be created).
575 TAO_EC_Event_Channel_Attributes attr_high (root_POA_var_.in (),
576 root_POA_var_.in ());
578 attr_high.scheduler = sched_hi_.in ();
580 ACE_NEW_RETURN (this->ec_hi_impl_,
581 TAO_EC_Event_Channel (attr_high),
582 -1);
584 this->ec_hi_ = ec_hi_impl_->_this ();
586 TAO_EC_Event_Channel_Attributes attr_low (root_POA_var_.in (),
587 root_POA_var_.in ());
589 attr_low.scheduler = sched_lo_.in ();
591 ACE_NEW_RETURN (this->ec_lo_impl_,
592 TAO_EC_Event_Channel (attr_low),
593 -1);
595 this->ec_lo_ = ec_lo_impl_->_this ();
597 // Register Event Service Implementations with Naming Service
599 naming_context_->bind (this->channel_hi_name_,
600 this->ec_hi_.in ());
602 naming_context_->bind (this->channel_lo_name_,
603 this->ec_lo_.in ());
606 catch (const CORBA::Exception& ex)
608 ex._tao_print_exception ("DualEC_Supplier::create_event_channels");
609 return -1;
612 return 0;
615 void
616 DualEC_Supplier::compute_schedules (void)
620 sched_hi_->compute_scheduling
621 (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
622 ACE_SCOPE_THREAD),
623 ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
624 ACE_SCOPE_THREAD),
625 this->infos_hi_.out (),
626 this->deps_hi_.out (),
627 this->configs_hi_.out (),
628 this->anomalies_hi_.out ());
630 sched_lo_->compute_scheduling
631 (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
632 ACE_SCOPE_THREAD),
633 ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
634 ACE_SCOPE_THREAD),
635 this->infos_lo_.out (),
636 this->deps_hi_.out (),
637 this->configs_lo_.out (),
638 this->anomalies_lo_.out ());
640 if (dump_schedule_headers_ && (this->hi_schedule_file_name_ != 0))
642 ACE_Scheduler_Factory::dump_schedule (infos_hi_.in (),
643 deps_hi_.in (),
644 configs_hi_.in (),
645 anomalies_hi_.in (),
646 this->hi_schedule_file_name_);
649 if (dump_schedule_headers_ && (this->lo_schedule_file_name_ != 0))
651 ACE_Scheduler_Factory::dump_schedule (infos_lo_.in (),
652 deps_lo_.in (),
653 configs_lo_.in (),
654 anomalies_lo_.in (),
655 this->lo_schedule_file_name_);
658 catch (const CORBA::Exception& ex)
660 ex._tao_print_exception ("SYS_EX");
664 void
665 DualEC_Supplier::start_generating_events (void)
669 // Spawn a thread that runs the orb event loop
670 ACE_Thread_Manager orb_thread_manager;
671 orb_thread_manager.spawn (DualEC_Supplier::run_orb);
673 // Compute the scheduling information, based on the provided RT_Infos.
674 this->compute_schedules ();
677 // Load the scheduling data for the simulation.
678 this->load_schedule_data ();
680 // Sleep for 10 seconds to give time for registrations.
681 ACE_DEBUG ((LM_DEBUG,
682 "\nDUAL_SCHED_HI, DUAL_SCHED_LO, DUAL_EC_HI and "
683 "DUAL_EC_LO are registered with the Naming Service.\n"
684 "Sleeping 10 seconds before generating events\n"));
685 ACE_Time_Value tv (10, 0);
686 ACE_OS::sleep (tv);
688 // Spawn thread to run over the navigation data and generate events.
689 ACE_Thread_Manager event_thread_manager;
690 event_thread_manager.spawn (DualEC_Supplier::run_nav_thread,
691 this);
693 // Spawn thread to run over the weapons data and generate events.
694 event_thread_manager.spawn (DualEC_Supplier::run_weap_thread,
695 this);
697 // Wait for the threads that are generating events.
698 event_thread_manager.wait ();
700 // Shut down the ORB via the termination servant
701 this->terminator_->shutdown ();
703 // Wait for the thread that runs the orb event loop.
704 orb_thread_manager.wait ();
706 // Clean up the navigation data.
707 ACE_Unbounded_Queue_Iterator<Navigation *>
708 nav_iter (this->navigation_data_);
709 Navigation **nav_temp;
710 for (nav_iter.first ();
711 nav_iter.done () == 0;
712 nav_iter.advance ())
713 if (nav_iter.next (nav_temp) && nav_temp)
714 delete (*nav_temp);
716 // Clean up the weapons data.
717 ACE_Unbounded_Queue_Iterator<Weapons *>
718 weap_iter (this->weapons_data_);
719 Weapons **weap_temp;
720 for (weap_iter.first ();
721 weap_iter.done () == 0;
722 weap_iter.advance ())
723 if (weap_iter.next (weap_temp) && weap_temp)
724 delete (*weap_temp);
726 catch (const CORBA::Exception& ex)
728 ex._tao_print_exception ("SYS_EX");
733 void
734 DualEC_Supplier::load_schedule_data ()
736 Navigation * nav = 0;
737 Weapons * weap = 0;
739 Schedule_Viewer_Data data;
741 // constants for periods (in units of one hundred nanoseconds)
742 const TimeBase::TimeT ONE_HZ_PERIOD = 10000000;
743 // const TimeBase::TimeT FIVE_HZ_PERIOD = ONE_HZ_PERIOD / 5;
744 // const TimeBase::TimeT TEN_HZ_PERIOD = ONE_HZ_PERIOD / 10;
745 const TimeBase::TimeT TWENTY_HZ_PERIOD = ONE_HZ_PERIOD / 20;
747 if (this->input_file_name_)
749 // Open the scheduler data input file and read its contents into
750 // a queue.
751 FILE *input_file;
753 int scan_count = 0;
754 input_file = ACE_OS::fopen(this->input_file_name_, "r");
756 if (input_file)
758 // Get a line at a time from the data file and parse it.
759 char input_buf[BUFSIZ];
760 while (ACE_OS::fgets (input_buf, BUFSIZ, input_file))
762 // Run through leading whitespace.
763 char *temp = input_buf;
764 while (*temp && ACE_OS::ace_isspace (*temp))
765 ++temp;
767 // If there is anything besides whitespace in the line
768 // read, scan its fields into the scheduling data
769 // structure.
770 if (ACE_OS::strlen (temp) > 0)
772 scan_count = sscanf (temp, "%s %lf %lf %lu %lu %lu %lu",
773 data.operation_name,
774 &data.utilitzation,
775 &data.overhead,
776 &data.arrival_time,
777 &data.deadline_time,
778 &data.completion_time,
779 &data.computation_time);
780 if (scan_count != 7)
782 ACE_ERROR ((LM_ERROR,
783 "DOVE_Supplier::load_schedule_data: "
784 "scanned incorrect number of data elements: %d\n", scan_count));
785 return;
789 if ((ACE_OS::strcmp(data.operation_name, "high_20") == 0) ||
790 (ACE_OS::strcmp(data.operation_name, "low_20") == 0))
792 ACE_NEW (weap, Weapons);
793 if (weap == 0)
795 ACE_ERROR ((LM_ERROR,
796 "DOVE_Supplier::load_schedule_data: "
797 "failed to allocate Weapons\n"));
798 return;
801 weap->criticality = 1;
802 weap->deadline_time = TWENTY_HZ_PERIOD;
803 weap->number_of_weapons = 2;
804 weap->weapon1_identifier = CORBA::string_alloc (30);
805 ACE_OS::strcpy (weap->weapon1_identifier.inout (),"Photon Torpedoes");
806 weap->weapon1_status =(ACE_OS::rand() % 4) == 0 ? 0 : 1 ;
807 weap->weapon2_identifier = CORBA::string_alloc (30);
808 ACE_OS::strcpy (weap->weapon2_identifier.inout (),"Quantum Torpedoes");
809 weap->weapon2_status = (ACE_OS::rand() % 4) == 0 ? 0 : 1;
810 weap->weapon3_identifier = CORBA::string_alloc (1);
811 ACE_OS::strcpy (weap->weapon3_identifier.inout (), "");
812 weap->weapon3_status = 0;
813 weap->weapon4_identifier = CORBA::string_alloc (1);
814 ACE_OS::strcpy (weap->weapon4_identifier.inout (), "");
815 weap->weapon4_status = 0;
816 weap->weapon5_identifier = CORBA::string_alloc (1);
817 ACE_OS::strcpy (weap->weapon5_identifier.inout (), "");
818 weap->weapon5_status = 0;
819 weap->utilization = 0.0;
820 weap->overhead = 0.0;
821 weap->arrival_time = ORBSVCS_Time::zero ();
822 weap->completion_time = ORBSVCS_Time::zero ();
823 weap->computation_time = ORBSVCS_Time::zero ();
824 weap->update_data = update_data_;
826 // Insert the data into the queue.
827 weapons_data_.enqueue_tail (weap);
829 else
831 ACE_NEW (nav, Navigation);
832 if (nav == 0)
834 ACE_ERROR ((LM_ERROR,
835 "DOVE_Supplier::load_schedule_data: "
836 "failed to allocate Navigation\n"));
837 return;
840 nav->criticality = 0;
841 nav->deadline_time = TWENTY_HZ_PERIOD;
842 nav->position_latitude = ACE_OS::rand() % 90;
843 nav->position_longitude = ACE_OS::rand() % 180;
844 nav->altitude = ACE_OS::rand() % 100;
845 nav->heading = ACE_OS::rand() % 180;
846 this->nav_roll_ = (this->nav_roll_ >= 180) ? -180 : this->nav_roll_ + 1;
847 nav->roll = this->nav_roll_;
848 this->nav_pitch_ = (this->nav_pitch_ >= 90) ? -90 : this->nav_pitch_ + 1;
849 nav->pitch = this->nav_pitch_;
850 nav->utilization = 0.0;
851 nav->overhead = 0.0;
852 nav->arrival_time = ORBSVCS_Time::zero ();
853 nav->completion_time = ORBSVCS_Time::zero ();
854 nav->computation_time = ORBSVCS_Time::zero ();
855 nav->update_data = this->update_data_;
856 nav->utilization = (double) (20.0 + ACE_OS::rand() % 10);
857 nav->overhead = (double) (ACE_OS::rand() % 10);
859 // Insert the data into the queue.
860 navigation_data_.enqueue_tail (nav);
865 else
867 ACE_ERROR ((LM_ERROR,
868 "DOVE_Supplier::start_generating_events: "
869 "could not open input file [%s].\n",
870 this->input_file_name_));
871 return;
877 // Get command line options.
879 unsigned int
880 DualEC_Supplier::get_options (int argc, ACE_TCHAR *argv [])
882 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("f:m:b:n:w:dsrp"));
883 int opt;
884 int temp;
886 while ((opt = get_opt ()) != -1)
888 switch (opt)
890 case 'f':
891 this->input_file_name_ = get_opt.opt_arg ();
893 if (!this->input_file_name_ || ACE_OS::strlen (this->input_file_name_) > 0)
894 ACE_DEBUG ((LM_DEBUG,"Reading file!\n"));
895 else
897 this->input_file_name_ = 0;
898 ACE_ERROR_RETURN ((LM_ERROR,
899 "%s: file name must be specified with -f option",
900 argv[0]),
903 break;
905 case 'm':
906 temp = ACE_OS::atoi (get_opt.opt_arg ());
907 if (temp > 0)
909 this->total_messages_ = (u_int) temp;
910 ACE_DEBUG ((LM_DEBUG,
911 "Messages to send: %d\n",
912 this->total_messages_));
914 else
915 ACE_ERROR_RETURN ((LM_ERROR,
916 "%s: message count must be > 0",
917 argv[0]),
919 break;
921 case 'b':
922 temp = ACE_OS::atoi (get_opt.opt_arg ());
923 if (temp > 0)
925 this->break_count_ = (u_int) temp;
926 ACE_DEBUG ((LM_DEBUG,
927 "Break count: %d\n",
928 this->break_count_));
930 else
931 ACE_ERROR_RETURN ((LM_ERROR,
932 "%s: break count must be > 0",
933 argv[0]),
935 break;
937 case 'n':
938 temp = ACE_OS::atoi (get_opt.opt_arg ());
939 if (temp >= 0)
941 this->nav_pause_ =
942 ACE_Time_Value(0, static_cast<long> (temp));
943 ACE_DEBUG ((LM_DEBUG,
944 "Navigation pause: %d usec\n",
945 temp));
947 else
948 ACE_ERROR_RETURN ((LM_ERROR,
949 "%s: navigation pause must be >= 0",
950 argv[0]),
952 break;
955 case 'w':
956 temp = ACE_OS::atoi (get_opt.opt_arg ());
957 if (temp >= 0)
959 this->weap_pause_ =
960 ACE_Time_Value(0, static_cast<long> (temp));
961 ACE_DEBUG ((LM_DEBUG,
962 "Weapons pause: %d usec\n",
963 temp));
965 else
966 ACE_ERROR_RETURN ((LM_ERROR,
967 "%s: weapons pause must be >= 0",
968 argv[0]),
970 break;
972 case 'd':
974 this->dump_schedule_headers_ = 1;
975 break;
977 case 's':
978 update_data_ = 0;
979 break;
981 case 'r':
982 use_runtime_schedulers_ = 1;
983 break;
985 case 'p':
986 suppress_priority_ = 1;
987 break;
989 default:
990 case '?':
991 ACE_DEBUG ((LM_DEBUG,
992 "Usage: %s %s\n",
993 argv[0], usage));
994 ACE_OS::exit (0);
995 break;
999 if (argc != get_opt.opt_ind ())
1000 ACE_ERROR_RETURN ((LM_ERROR,
1001 "%s: too many arguments\n"
1002 "Usage: %s %s\n",
1003 argv[0],
1004 argv[0],
1005 usage),
1008 return 0;
1011 // function main
1014 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
1016 // Enable FIFO scheduling, e.g., RT scheduling class on Solaris.
1017 int min_priority =
1018 ACE_Sched_Params::priority_min (ACE_SCHED_FIFO);
1020 // Set all threads in the process into the RT scheduling class
1021 if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO,
1022 min_priority,
1023 ACE_SCOPE_PROCESS)) != 0)
1025 if (ACE_OS::last_error () == EPERM)
1026 ACE_DEBUG ((LM_DEBUG,
1027 "%s: user is not superuser, "
1028 "so remain in time-sharing class\n", argv[0]));
1029 else
1030 ACE_ERROR ((LM_ERROR,
1031 "%s: ACE_OS::sched_params failed\n", argv[0]));
1038 // Initialize ORB.
1039 TAO_ORB_Manager orb_Manager;
1041 orb_Manager.init (argc,
1042 argv);
1045 // Create the demo supplier.
1046 DualEC_Supplier *event_Supplier_ptr;
1048 ACE_NEW_RETURN (event_Supplier_ptr,
1049 DualEC_Supplier(argc, argv),
1050 -1);
1052 // Initialize everthing
1053 if (event_Supplier_ptr->init () == -1)
1054 ACE_OS::exit (1);
1056 // now we can go ahead
1057 event_Supplier_ptr->start_generating_events ();
1059 // when done, we clean up
1060 delete event_Supplier_ptr;
1062 catch (const CORBA::Exception& ex)
1064 ex._tao_print_exception ("SYS_EX");
1067 return 0;