void FT_EventService::setup_scheduler(CosNaming::NamingContext_ptr naming_context) { RtecScheduler::Scheduler_var scheduler; if (CORBA::is_nil(naming_context)) { ACE_NEW_THROW_EX (this->sched_impl_, ACE_Config_Scheduler, CORBA::NO_MEMORY()); scheduler = this->sched_impl_->_this (); if (ACE_Scheduler_Factory::server(scheduler.in()) == -1) ORBSVCS_ERROR((LM_ERROR,"Unable to install scheduler\n")); } else { // This is the name we (potentially) register the Scheduling // Service in the Naming Service. CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); if (1) { // We must find the scheduler object reference... if (this->global_scheduler_ == 0) { ACE_NEW_THROW_EX (this->sched_impl_, ACE_Config_Scheduler, CORBA::NO_MEMORY()); scheduler = this->sched_impl_->_this (); // Register the servant with the Naming Context.... naming_context->rebind (schedule_name, scheduler.in ()); } else { CORBA::Object_var tmp = naming_context->resolve (schedule_name); scheduler = RtecScheduler::Scheduler::_narrow (tmp.in ()); } } } }
TAO_EC_Scheduling_Strategy* TAO_EC_Kokyu_Factory::create_scheduling_strategy (TAO_EC_Event_Channel_Base* ec) { if (this->scheduling_ == 2) { CORBA::Object_var tmp = ec->scheduler (); RtecScheduler::Scheduler_var scheduler = RtecScheduler::Scheduler::_narrow (tmp.in ()); return new TAO_EC_Kokyu_Scheduling (scheduler.in ()); } return this->TAO_EC_Default_Factory::create_scheduling_strategy (ec); }
int Event_Service::run (int argc, ACE_TCHAR* argv[]) { try { // Check if -ORBDaemon is specified and if so, daemonize at this moment, // -ORBDaemon in the ORB core is faulty, see bugzilla 3335 TAO_Daemon_Utility::check_for_daemon (argc, argv); // Initialize ORB. this->orb_ = CORBA::ORB_init (argc, argv); if (this->parse_args (argc, argv) == -1) return 1; CORBA::Object_var root_poa_object = this->orb_->resolve_initial_references("RootPOA"); if (CORBA::is_nil (root_poa_object.in ())) ORBSVCS_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize the root POA.\n"), 1); PortableServer::POA_var root_poa = PortableServer::POA::_narrow (root_poa_object.in ()); PortableServer::POAManager_var poa_manager = root_poa->the_POAManager (); poa_manager->activate (); // When we have a service name or a non local scheduler we must use the // naming service. bool use_name_service = bind_to_naming_service_ || this->scheduler_type_ != ES_SCHED_NONE; CORBA::Object_var naming_obj; RtecScheduler::Scheduler_var scheduler; CosNaming::NamingContext_var naming_context; if (use_name_service) { naming_obj= this->orb_->resolve_initial_references ("NameService"); if (CORBA::is_nil (naming_obj.in ())) ORBSVCS_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize the Naming Service.\n"), 1); naming_context = CosNaming::NamingContext::_narrow (naming_obj.in ()); } // This is the name we (potentially) register the Scheduling // Service in the Naming Service. CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); // The old EC always needs a scheduler. If none is // specified, we default to a local scheduler if (this->scheduler_type_ == ES_SCHED_LOCAL) { // Create a local scheduler instance ACE_NEW_RETURN (this->sched_impl_, ACE_Config_Scheduler, 1); scheduler = this->sched_impl_->_this (); // Register the servant with the Naming Context.... if (!CORBA::is_nil (naming_context.in ())) { naming_context->rebind (schedule_name, scheduler.in ()); } } else if (this->scheduler_type_ == ES_SCHED_GLOBAL) { // Get reference to a scheduler from naming service CORBA::Object_var tmp = naming_context->resolve (schedule_name); scheduler = RtecScheduler::Scheduler::_narrow (tmp.in ()); if (CORBA::is_nil (scheduler.in ())) ORBSVCS_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to resolve the Scheduling Service.\n"), 1); } TAO_EC_Event_Channel_Attributes attr (root_poa.in (), root_poa.in ()); if (this->scheduler_type_ != ES_SCHED_NONE) { attr.scheduler = scheduler.in (); } TAO_EC_Event_Channel* ec_impl = 0; ACE_NEW_RETURN (ec_impl, TAO_EC_Event_Channel (attr), 1); this->ec_impl_ = ec_impl; ec_impl->activate (); RtecEventChannelAdmin::EventChannel_var ec; // If the object_id_ is empty and we don't use BiDIR GIOP, activate the // servant under the default POA, else create a new child POA with // the needed policies int persistent = ACE_OS::strcmp(this->object_id_.c_str(), ""); if ((persistent == 0) && (this->use_bidir_giop_ == false)) { // Notice that we activate *this* object with the POA, but we // forward all the requests to the underlying EC // implementation. ec = this->_this (); } else { CORBA::ULong index = 0; // Create child POA CORBA::PolicyList policies (3); if (persistent != 0) { policies.length (index++); policies[index] = root_poa->create_id_assignment_policy (PortableServer::USER_ID); policies.length (index++); policies[index] = root_poa->create_lifespan_policy (PortableServer::PERSISTENT); } if (this->use_bidir_giop_ == true) { CORBA::Any pol; pol <<= BiDirPolicy::BOTH; policies.length (index++); policies[index] = this->orb_->create_policy (BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE, pol); } ACE_CString child_poa_name = "childPOA"; PortableServer::POA_var child_poa = root_poa->create_POA (child_poa_name.c_str (), poa_manager.in (), policies); // Creation of persistentPOA is over. Destroy the Policy objects. for (CORBA::ULong i = 0; i < policies.length (); ++i) { policies[i]->destroy (); } if (CORBA::is_nil (child_poa.in ())) ORBSVCS_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize the child POA.\n"), 1); PortableServer::ObjectId_var ec_object_id = PortableServer::string_to_ObjectId(object_id_.c_str()); child_poa->activate_object_with_id(ec_object_id.in(), this); CORBA::Object_var ec_obj = child_poa->id_to_reference(ec_object_id.in()); ec = RtecEventChannelAdmin::EventChannel::_narrow(ec_obj.in()); } CORBA::String_var str = this->orb_->object_to_string (ec.in ()); if (ACE_OS::strcmp(this->ior_file_name_.c_str(), ACE_TEXT("")) != 0) { FILE *output_file= ACE_OS::fopen (this->ior_file_name_.c_str(), ACE_TEXT("w")); if (output_file == 0) ORBSVCS_ERROR_RETURN ((LM_ERROR, "Cannot open output file for writing IOR: %s", this->ior_file_name_.c_str()), 1); ACE_OS::fprintf (output_file, "%s", str.in ()); ACE_OS::fclose (output_file); } if (ACE_OS::strcmp(this->pid_file_name_.c_str(), ACE_TEXT("")) != 0) { FILE *pidf = ACE_OS::fopen (this->pid_file_name_.c_str(), ACE_TEXT("w")); if (pidf != 0) { ACE_OS::fprintf (pidf, "%ld\n", static_cast<long> (ACE_OS::getpid ())); ACE_OS::fclose (pidf); } } ORBSVCS_DEBUG ((LM_DEBUG, ACE_TEXT("The EC IOR is <%C>\n"), str.in ())); if (bind_to_naming_service_ && !CORBA::is_nil (naming_context.in ())) { CosNaming::Name channel_name (1); channel_name.length (1); channel_name[0].id = CORBA::string_dup (this->service_name_.c_str()); naming_context->rebind (channel_name, ec.in ()); } ORBSVCS_DEBUG ((LM_DEBUG, ACE_TEXT("%C; running event service\n"), __FILE__)); this->orb_->run (); if (bind_to_naming_service_ && !CORBA::is_nil (naming_context.in ())) { CosNaming::Name channel_name (1); channel_name.length (1); channel_name[0].id = CORBA::string_dup (this->service_name_.c_str()); naming_context->unbind (channel_name); } if (!CORBA::is_nil (scheduler.in ()) && !CORBA::is_nil (naming_context.in ())) { naming_context->unbind (schedule_name); } } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("EC"); } return 0; }
int ECT_Consumer_Driver::run (int argc, ACE_TCHAR* argv[]) { try { this->orb_ = CORBA::ORB_init (argc, argv); CORBA::Object_var poa_object = this->orb_->resolve_initial_references("RootPOA"); if (CORBA::is_nil (poa_object.in ())) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize the POA.\n"), 1); PortableServer::POA_var root_poa = PortableServer::POA::_narrow (poa_object.in ()); PortableServer::POAManager_var poa_manager = root_poa->the_POAManager (); if (this->parse_args (argc, argv)) return 1; if (TAO_debug_level > 0) { ACE_DEBUG ((LM_DEBUG, "Execution parameters:\n" " consumers = <%d>\n" " suppliers = <%d>\n" " type start = <%d>\n" " type count = <%d>\n" " pid file name = <%s>\n", this->n_consumers_, this->n_suppliers_, this->type_start_, this->type_count_, this->pid_file_name_?this->pid_file_name_:ACE_TEXT("nil")) ); } if (this->pid_file_name_ != 0) { FILE* pid = ACE_OS::fopen (this->pid_file_name_, "w"); if (pid != 0) { ACE_OS::fprintf (pid, "%ld\n", static_cast<long> (ACE_OS::getpid ())); ACE_OS::fclose (pid); } } int min_priority = ACE_Sched_Params::priority_min (ACE_SCHED_FIFO); // Enable FIFO scheduling, e.g., RT scheduling class on Solaris. if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO, min_priority, ACE_SCOPE_PROCESS)) != 0) { if (ACE_OS::last_error () == EPERM) ACE_DEBUG ((LM_DEBUG, "%s: user is not superuser, " "so remain in time-sharing class\n", argv[0])); else ACE_ERROR ((LM_ERROR, "%s: ACE_OS::sched_params failed\n", argv[0])); } if (ACE_OS::thr_setprio (min_priority) == -1) { ACE_ERROR ((LM_ERROR, "(%P|%t) main thr_setprio failed," "no real-time features\n")); } CORBA::Object_var naming_obj = this->orb_->resolve_initial_references ("NameService"); if (CORBA::is_nil (naming_obj.in ())) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to get the Naming Service.\n"), 1); CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_obj.in ()); CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); CORBA::Object_var sched_obj = naming_context->resolve (schedule_name); if (CORBA::is_nil (sched_obj.in ())) return 1; RtecScheduler::Scheduler_var scheduler = RtecScheduler::Scheduler::_narrow (sched_obj.in ()); CosNaming::Name name (1); name.length (1); name[0].id = CORBA::string_dup ("EventService"); CORBA::Object_var ec_obj = naming_context->resolve (name); RtecEventChannelAdmin::EventChannel_var channel; if (CORBA::is_nil (ec_obj.in ())) channel = RtecEventChannelAdmin::EventChannel::_nil (); else channel = RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in ()); poa_manager->activate (); this->connect_consumers (scheduler.in (), channel.in ()); ACE_DEBUG ((LM_DEBUG, "connected consumer(s)\n")); ACE_DEBUG ((LM_DEBUG, "running the test\n")); for (;;) { ACE_Time_Value tv (1, 0); this->orb_->perform_work (tv); ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 1); if (this->active_count_ <= 0) break; } ACE_DEBUG ((LM_DEBUG, "event loop finished\n")); this->dump_results (); this->disconnect_consumers (); if (this->shutdown_event_channel_ != 0) { channel->destroy (); } root_poa->destroy (1, 1); this->orb_->destroy (); } catch (const CORBA::SystemException& sys_ex) { sys_ex._tao_print_exception ("SYS_EX"); } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("NON SYS EX"); } return 0; }
int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { TAO_EC_Default_Factory::init_svcs (); try { // ORB initialization boiler plate... CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); if (parse_args (argc, argv) == -1) { ACE_ERROR ((LM_ERROR, "Usage: Service [-o IOR_file_name]\n")); return 1; } CORBA::Object_var object = orb->resolve_initial_references ("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow (object.in ()); PortableServer::POAManager_var poa_manager = poa->the_POAManager (); poa_manager->activate (); // **************************************************************** #if 0 // Obtain a reference to the naming service... CORBA::Object_var naming_obj = orb->resolve_initial_references ("NameService"); CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_obj.in ()); #endif /* 0 */ // **************************************************************** // Create an scheduling service POA_RtecScheduler::Scheduler* sched_impl = 0; if (config_run) { ACE_NEW_RETURN (sched_impl, RECONFIG_SCHED_TYPE, 1); } else { ACE_NEW_RETURN (sched_impl, RECONFIG_SCHED_TYPE (configs_size, configs, infos_size, infos, 0, 0, 0), 1); } RtecScheduler::Scheduler_var scheduler = sched_impl->_this (); #if 0 // Bind the scheduler with the naming service so clients // (consumers and suppliers) can resolve it, some (old) // implementations of the EC will try to do the same thing // (yikes!) CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); // Register the servant with the Naming Context.... naming_context->rebind (schedule_name, scheduler.in ()); #endif /* 0 */ // **************************************************************** TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ()); attributes.scheduler = scheduler.in (); // no need to dup TAO_EC_Event_Channel ec_impl (attributes); ACE_DEBUG ((LM_DEBUG, "activating EC\n")); ec_impl.activate (); ACE_DEBUG ((LM_DEBUG, "EC activated\n")); RtecEventChannelAdmin::EventChannel_var event_channel = ec_impl._this (); // **************************************************************** // Create a consumer, intialize its RT_Info structures, and // connnect to the event channel.... Consumer consumer_impl; RtecScheduler::handle_t consumer_rt_info1 = scheduler->create ("consumer_event_1"); // Let's say that the execution time for event 1 is 2 // milliseconds... ACE_Time_Value tv (0, 2000); TimeBase::TimeT time; ORBSVCS_Time::Time_Value_to_TimeT (time, tv); scheduler->set (consumer_rt_info1, RtecScheduler::VERY_HIGH_CRITICALITY, time, time, time, 0, RtecScheduler::VERY_LOW_IMPORTANCE, time, 0, RtecScheduler::OPERATION); RtecScheduler::handle_t consumer_rt_info2 = scheduler->create ("consumer_event_2"); // Let's say that the execution time for event 2 is 1 // milliseconds... tv.set (0, 1000); ORBSVCS_Time::Time_Value_to_TimeT (time, tv); scheduler->set (consumer_rt_info2, RtecScheduler::VERY_LOW_CRITICALITY, time, time, time, 0, RtecScheduler::VERY_LOW_IMPORTANCE, time, 0, RtecScheduler::OPERATION); ACE_ConsumerQOS_Factory consumer_qos; consumer_qos.start_disjunction_group (); // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are // reserved for the EC... consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED, consumer_rt_info1); consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED + 1, consumer_rt_info2); // The canonical protocol to connect to the EC RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = event_channel->for_consumers (); RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy = consumer_admin->obtain_push_supplier (); RtecEventComm::PushConsumer_var consumer = consumer_impl._this (); ACE_DEBUG ((LM_DEBUG, "connecting consumer\n")); supplier_proxy->connect_push_consumer (consumer.in (), consumer_qos.get_ConsumerQOS ()); ACE_DEBUG ((LM_DEBUG, "consumer connected\n")); // **************************************************************** Supplier supplier_impl; RtecScheduler::handle_t supplier_rt_info1 = scheduler->create ("supplier_event_1"); // The execution times are set to reasonable values, but // actually they are changed on the real execution, i.e. we // lie to the scheduler to obtain right priorities; but we // don't care if the set is schedulable. tv.set (0, 10000); TimeBase::TimeT tmp; ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); RtecScheduler::Period_t rate = ACE_U64_TO_U32(tmp); scheduler->set (supplier_rt_info1, RtecScheduler::VERY_HIGH_CRITICALITY, 0, 0, 0, rate, RtecScheduler::VERY_LOW_IMPORTANCE, 0, 1, RtecScheduler::OPERATION); RtecScheduler::handle_t supplier_rt_info2 = scheduler->create ("supplier_event_2"); // The execution times are set to reasonable values, but // actually they are changed on the real execution, i.e. we // lie to the scheduler to obtain right priorities; but we // don't care if the set is schedulable. tv.set (0, 20000); ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); rate = ACE_U64_TO_U32(tmp); scheduler->set (supplier_rt_info2, RtecScheduler::VERY_HIGH_CRITICALITY, 0, 0, 0, rate, RtecScheduler::VERY_LOW_IMPORTANCE, 0, 1, RtecScheduler::OPERATION); RtecEventComm::EventSourceID supplier_id = 1; ACE_SupplierQOS_Factory supplier_qos; supplier_qos.insert (supplier_id, ACE_ES_EVENT_UNDEFINED, supplier_rt_info1, 1 /* number of calls, but what does that mean? */); supplier_qos.insert (supplier_id, ACE_ES_EVENT_UNDEFINED + 1, supplier_rt_info2, 1 /* number of calls, but what does that mean? */); // The canonical protocol to connect to the EC RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = event_channel->for_suppliers (); RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy = supplier_admin->obtain_push_consumer (); RtecEventComm::PushSupplier_var supplier = supplier_impl._this (); ACE_DEBUG ((LM_DEBUG, "connecting supplier\n")); consumer_proxy->connect_push_supplier (supplier.in (), supplier_qos.get_SupplierQOS ()); ACE_DEBUG ((LM_DEBUG, "supplier connected\n")); // **************************************************************** // At this point the consumer and supplier are connected to the // EC, they have provided their QoS info to the Scheduling // Service and the EC has informed the Scheduler about the // dependencies between them. // We can now compute the schedule for this configuration... // The schedule is returned in this variables.... if (config_run) { ACE_DEBUG ((LM_DEBUG, "Computing schedule\n")); RtecScheduler::RT_Info_Set_var infos; RtecScheduler::Dependency_Set_var deps; RtecScheduler::Config_Info_Set_var configs; RtecScheduler::Scheduling_Anomaly_Set_var anomalies; // Obtain the range of valid priorities in the current // platform, the scheduler hard-code this values in the // generated file, but in the future we may just use the // "logical" priorities and define the mapping to OS // priorities at run-time. int min_os_priority = ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); int max_os_priority = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); scheduler->compute_scheduling (min_os_priority, max_os_priority, infos.out (), deps.out (), configs.out (), anomalies.out ()); // Dump the schedule to a file.. ACE_Scheduler_Factory::dump_schedule (infos.in (), deps.in (), configs.in (), anomalies.in (), ACE_TEXT("schedule.out")); } // **************************************************************** ACE_DEBUG ((LM_DEBUG, "Pushing events\n")); // Generate a few events.... RtecEventComm::EventSet event1 (1); event1.length (1); event1[0].header.type = ACE_ES_EVENT_UNDEFINED; event1[0].header.source = supplier_id; event1[0].header.ttl = 1; RtecEventComm::EventSet event2 (1); event2.length (1); event2[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; event2[0].header.source = supplier_id; event2[0].header.ttl = 1; for (int i = 0; i != 200; ++i) { if (i % 2 == 0) { consumer_proxy->push (event1); } else { consumer_proxy->push (event2); } ACE_Time_Value rate (0, 10000); ACE_OS::sleep (rate); } // **************************************************************** // We should do a lot of cleanup (disconnect from the EC, // deactivate all the objects with the POA, etc.) but this is // just a simple demo so we are going to be lazy. } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("Service"); return 1; } return 0; }
int ECT_Throughput::run (int argc, ACE_TCHAR* argv[]) { try { // Calibrate the high resolution timer *before* starting the // test. ACE_High_Res_Timer::calibrate (); this->orb_ = CORBA::ORB_init (argc, argv); CORBA::Object_var poa_object = this->orb_->resolve_initial_references("RootPOA"); if (CORBA::is_nil (poa_object.in ())) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize the POA.\n"), 1); PortableServer::POA_var root_poa = PortableServer::POA::_narrow (poa_object.in ()); PortableServer::POAManager_var poa_manager = root_poa->the_POAManager (); poa_manager->activate (); if (this->parse_args (argc, argv)) return 1; if (TAO_debug_level > 0) { ACE_DEBUG ((LM_DEBUG, "Execution parameters:\n" " consumers = <%d>\n" " suppliers = <%d>\n" " burst count = <%d>\n" " burst size = <%d>\n" " event size = <%d>\n" " burst pause = <%d>\n" " consumer type start = <%d>\n" " consumer type count = <%d>\n" " consumer type shift = <%d>\n" " supplier type start = <%d>\n" " supplier type count = <%d>\n" " supplier type shift = <%d>\n" " pid file name = <%s>\n" " concurrency HWM = <%d>\n", this->n_consumers_, this->n_suppliers_, this->burst_count_, this->burst_size_, this->event_size_, this->burst_pause_, this->consumer_type_start_, this->consumer_type_count_, this->consumer_type_shift_, this->supplier_type_start_, this->supplier_type_count_, this->supplier_type_shift_, this->pid_file_name_?this->pid_file_name_:ACE_TEXT("nil"), this->ec_concurrency_hwm_ ) ); } if (this->pid_file_name_ != 0) { FILE* pid = ACE_OS::fopen (this->pid_file_name_, "w"); if (pid != 0) { ACE_OS::fprintf (pid, "%ld\n", static_cast<long> (ACE_OS::getpid ())); ACE_OS::fclose (pid); } } int priority = (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO) + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2; priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO, priority); // Enable FIFO scheduling, e.g., RT scheduling class on Solaris. if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO, priority, ACE_SCOPE_PROCESS)) != 0) { if (ACE_OS::last_error () == EPERM) { ACE_DEBUG ((LM_DEBUG, "%s: user is not superuser, " "so remain in time-sharing class\n", argv[0])); this->thr_create_flags_ = THR_NEW_LWP; } else ACE_ERROR ((LM_ERROR, "%s: ACE_OS::sched_params failed\n", argv[0])); } if (ACE_OS::thr_setprio (priority) == -1) { ACE_ERROR ((LM_ERROR, "(%P|%t) main thr_setprio failed," "no real-time features\n")); } #if 1 ACE_Config_Scheduler scheduler_impl; #else #include "ECT_Scheduler_Info.h" ACE_Runtime_Scheduler scheduler_impl ( runtime_configs_size, runtime_configs, runtime_infos_size, runtime_infos); #endif RtecScheduler::Scheduler_var scheduler = scheduler_impl._this (); #if 0 CORBA::Object_var naming_obj = this->orb_->resolve_initial_references ("NameService"); if (CORBA::is_nil (naming_obj.in ())) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to get the Naming Service.\n"), 1); CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_obj.in ()); // This is the name we (potentially) register the Scheduling // Service in the Naming Service. CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); CORBA::String_var str = this->orb_->object_to_string (scheduler.in ()); ACE_DEBUG ((LM_DEBUG, "The (local) scheduler IOR is <%s>\n", str.in ())); // Register the servant with the Naming Context.... naming_context->rebind (schedule_name, scheduler.in ()); ACE_Scheduler_Factory::use_config (naming_context.in ()); #endif /* 0 */ auto_ptr<POA_RtecEventChannelAdmin::EventChannel> ec_impl; TAO_EC_Event_Channel_Attributes attr (root_poa.in (), root_poa.in ()); TAO_EC_Event_Channel *ec = new TAO_EC_Event_Channel (attr); ec->activate (); auto_ptr<POA_RtecEventChannelAdmin::EventChannel> auto_ec_impl (ec); ec_impl = auto_ec_impl; RtecEventChannelAdmin::EventChannel_var channel = ec_impl->_this (); this->connect_consumers (scheduler.in (), channel.in ()); ACE_DEBUG ((LM_DEBUG, "connected consumer(s)\n")); this->connect_suppliers (scheduler.in (), channel.in ()); ACE_DEBUG ((LM_DEBUG, "connected supplier(s)\n")); this->activate_suppliers (); ACE_DEBUG ((LM_DEBUG, "suppliers are active\n")); // Wait for the supplier threads... if (ACE_Thread_Manager::instance ()->wait () == -1) { ACE_ERROR ((LM_ERROR, "Thread_Manager wait failed\n")); return 1; } ACE_DEBUG ((LM_DEBUG, "suppliers finished\n")); this->dump_results (); this->disconnect_consumers (); ACE_DEBUG ((LM_DEBUG, "consumers disconnected\n")); this->disconnect_suppliers (); ACE_DEBUG ((LM_DEBUG, "suppliers disconnected\n")); channel->destroy (); ACE_DEBUG ((LM_DEBUG, "channel destroyed\n")); { // Deactivate the EC PortableServer::POA_var poa = ec_impl->_default_POA (); PortableServer::ObjectId_var id = poa->servant_to_id (ec_impl.get ()); poa->deactivate_object (id.in ()); ACE_DEBUG ((LM_DEBUG, "EC deactivated\n")); } { // Deactivate the Scheduler PortableServer::POA_var poa = scheduler_impl._default_POA (); PortableServer::ObjectId_var id = poa->servant_to_id (&scheduler_impl); poa->deactivate_object (id.in ()); ACE_DEBUG ((LM_DEBUG, "scheduler deactivated\n")); } } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("ECT_Throughput::run"); } catch (...) { ACE_ERROR ((LM_ERROR, "non-corba exception raised\n")); } return 0; }
int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { ACE_UNUSED_ARG (config_run); //TAO_EC_Default_Factory::init_svcs (); TAO_EC_Kokyu_Factory::init_svcs (); try { // ORB initialization boiler plate... CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); if (parse_args (argc, argv) == -1) { ACE_ERROR ((LM_ERROR, "Usage: Service [-o IOR_file_name]\n")); return 1; } CORBA::Object_var object = orb->resolve_initial_references ("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow (object.in ()); PortableServer::POAManager_var poa_manager = poa->the_POAManager (); poa_manager->activate (); // **************************************************************** // Create an scheduling service POA_RtecScheduler::Scheduler* sched_impl = 0; if (ACE_OS::strcasecmp(sched_type.c_str(), "rms") == 0) { ACE_DEBUG ((LM_DEBUG, "Creating RMS scheduler\n")); ACE_NEW_RETURN (sched_impl, RECONFIG_RMS_SCHED_TYPE, 1); } else if (ACE_OS::strcasecmp(sched_type.c_str(), "muf") == 0) { ACE_DEBUG ((LM_DEBUG, "Creating MUF scheduler\n")); ACE_NEW_RETURN (sched_impl, RECONFIG_MUF_SCHED_TYPE, 1); } RtecScheduler::Scheduler_var scheduler = sched_impl->_this (); // **************************************************************** TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ()); attributes.scheduler = scheduler.in (); // no need to dup TAO_EC_Event_Channel ec_impl (attributes); RtecEventChannelAdmin::EventChannel_var event_channel = ec_impl._this (); // **************************************************************** // Create a consumer, intialize its RT_Info structures, and // connnect to the event channel.... Consumer consumer_impl1, consumer_impl2; RtecScheduler::handle_t consumer1_rt_info = scheduler->create ("consumer1"); RtecScheduler::handle_t consumer2_rt_info = scheduler->create ("consumer2"); //consumer's rate will get propagated from the supplier. //so no need to specify a period here. Specifying //criticality is crucial since it propagates from //consumer to supplier. ACE_Time_Value tv (0,0); TimeBase::TimeT tmp; ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); scheduler->set (consumer1_rt_info, RtecScheduler::VERY_LOW_CRITICALITY, tmp, tmp, tmp, time_val_to_period (tv), RtecScheduler::VERY_LOW_IMPORTANCE, tmp, 0, RtecScheduler::OPERATION); scheduler->set (consumer2_rt_info, RtecScheduler::VERY_HIGH_CRITICALITY, tmp, tmp, tmp, time_val_to_period (tv), RtecScheduler::VERY_HIGH_IMPORTANCE, tmp, 0, RtecScheduler::OPERATION); ACE_ConsumerQOS_Factory consumer_qos1, consumer_qos2; //consumer_qos.start_disjunction_group (); // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are // reserved for the EC... consumer_qos1.insert_type (ACE_ES_EVENT_UNDEFINED, consumer1_rt_info); RtecEventChannelAdmin::ConsumerQOS qos = consumer_qos1.get_ConsumerQOS (); /* for (int i=0;i<qos.dependencies.length (); ++i) { ACE_DEBUG ((LM_DEBUG, "consumer_qos1[%d] event.header.type = %d, " "consumer_qos1[%d] rt_info = %d, " "consumer_qos1[%d] event.header.source = %d\n", i,qos.dependencies[i].event.header.type, i,qos.dependencies[i].rt_info, i,qos.dependencies[i].event.header.source)); } */ consumer_qos2.insert_type (ACE_ES_EVENT_UNDEFINED + 1, consumer2_rt_info); // The canonical protocol to connect to the EC RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = event_channel->for_consumers (); RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy1 = consumer_admin->obtain_push_supplier (); RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy2 = consumer_admin->obtain_push_supplier (); RtecEventComm::PushConsumer_var consumer1 = consumer_impl1._this (); RtecEventComm::PushConsumer_var consumer2 = consumer_impl2._this (); ACE_DEBUG ((LM_DEBUG, "connecting consumers\n")); ACE_DEBUG ((LM_DEBUG, "connecting consumer1\n")); supplier_proxy1->connect_push_consumer (consumer1.in (), consumer_qos1.get_ConsumerQOS ()); ACE_DEBUG ((LM_DEBUG, "connecting consumer2\n")); supplier_proxy2->connect_push_consumer (consumer2.in (), consumer_qos2.get_ConsumerQOS ()); ACE_DEBUG ((LM_DEBUG, "consumers connected\n")); // **************************************************************** RtecScheduler::handle_t supplier1_rt_info = scheduler->create ("supplier1"); RtecScheduler::handle_t supplier2_rt_info = scheduler->create ("supplier2"); RtecEventComm::EventSourceID supplier_id1 = 1, supplier_id2 = 2; ACE_SupplierQOS_Factory supplier_qos1, supplier_qos2; supplier_qos1.insert (supplier_id1, ACE_ES_EVENT_UNDEFINED, supplier1_rt_info, 1 /* number of calls, but what does that mean? */); supplier_qos2.insert (supplier_id2, ACE_ES_EVENT_UNDEFINED + 1, supplier2_rt_info, 1 /* number of calls, but what does that mean? */); // The canonical protocol to connect to the EC RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = event_channel->for_suppliers (); RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy1 = supplier_admin->obtain_push_consumer (); RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy2 = supplier_admin->obtain_push_consumer (); Supplier supplier_impl1(supplier_id1, consumer_proxy1.in ()); Supplier supplier_impl2(supplier_id2, consumer_proxy2.in ()); RtecEventComm::PushSupplier_var supplier1 = supplier_impl1._this (); RtecEventComm::PushSupplier_var supplier2 = supplier_impl2._this (); ACE_DEBUG ((LM_DEBUG, "connecting suppliers\n")); ACE_DEBUG ((LM_DEBUG, "connecting supplier1\n")); consumer_proxy1->connect_push_supplier (supplier1.in (), supplier_qos1.get_SupplierQOS ()); ACE_DEBUG ((LM_DEBUG, "connecting supplier2\n")); consumer_proxy2->connect_push_supplier (supplier2.in (), supplier_qos2.get_SupplierQOS ()); ACE_DEBUG ((LM_DEBUG, "suppliers connected\n")); // **************************************************************** //Timer Registration part //Timeout consumers for the two suppliers. Timeout_Consumer timeout_consumer_impl1(&supplier_impl1); Timeout_Consumer timeout_consumer_impl2(&supplier_impl2); RtecScheduler::handle_t supplier1_timeout_consumer_rt_info = scheduler->create ("supplier1_timeout_consumer"); //Period = 1sec tv.set (1,0); ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); scheduler->set (supplier1_timeout_consumer_rt_info, RtecScheduler::VERY_LOW_CRITICALITY, tmp, tmp, tmp, time_val_to_period (tv), RtecScheduler::VERY_LOW_IMPORTANCE, tmp, 0, RtecScheduler::OPERATION); RtecScheduler::handle_t supplier2_timeout_consumer_rt_info = scheduler->create ("supplier2_timeout_consumer"); //Period = 3sec tv.set (3, 0); ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); scheduler->set (supplier2_timeout_consumer_rt_info, RtecScheduler::VERY_HIGH_CRITICALITY, tmp, tmp, tmp, time_val_to_period (tv), RtecScheduler::VERY_HIGH_IMPORTANCE, tmp, 0, RtecScheduler::OPERATION); ACE_ConsumerQOS_Factory timer_qos1, timer_qos2; timer_qos1.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT, 10000000, //in 100s of nanosec supplier1_timeout_consumer_rt_info); timer_qos2.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT, 30000000, //in 100s of nanosec supplier2_timeout_consumer_rt_info); RtecEventChannelAdmin::ProxyPushSupplier_var timeout_supplier_proxy1 = consumer_admin->obtain_push_supplier (); RtecEventChannelAdmin::ProxyPushSupplier_var timeout_supplier_proxy2 = consumer_admin->obtain_push_supplier (); RtecEventComm::PushConsumer_var safe_timeout_consumer1 = timeout_consumer_impl1._this (); RtecEventComm::PushConsumer_var safe_timeout_consumer2 = timeout_consumer_impl2._this (); ACE_DEBUG ((LM_DEBUG, "connecting timeout consumers\n")); timeout_supplier_proxy1-> connect_push_consumer (safe_timeout_consumer1.in (), timer_qos1.get_ConsumerQOS ()); timeout_supplier_proxy2-> connect_push_consumer (safe_timeout_consumer2.in (), timer_qos2.get_ConsumerQOS ()); ACE_DEBUG ((LM_DEBUG, "timeout consumers connected\n")); // **************************************************************** //Registering dependency between timeout consumers and our suppliers //with the scheduler scheduler->add_dependency (supplier1_timeout_consumer_rt_info, supplier1_rt_info, 1, RtecBase::TWO_WAY_CALL); scheduler->add_dependency (supplier2_timeout_consumer_rt_info, supplier2_rt_info, 1, RtecBase::TWO_WAY_CALL); // **************************************************************** // At this point the consumer and supplier are connected to the // EC, they have provided their QoS info to the Scheduling // Service and the EC has informed the Scheduler about the // dependencies between them. // We can now compute the schedule for this configuration... // The schedule is returned in this variables.... ACE_DEBUG ((LM_DEBUG, "Computing schedule\n")); RtecScheduler::RT_Info_Set_var infos; RtecScheduler::Config_Info_Set_var configs; RtecScheduler::Dependency_Set_var dependencies; RtecScheduler::Scheduling_Anomaly_Set unsafe_anomalies; RtecScheduler::Scheduling_Anomaly_Set_var anomalies; scheduler->get_rt_info_set (infos.out() ); scheduler->get_dependency_set (dependencies.out() ); scheduler->get_config_info_set (configs.out() ); ACE_DEBUG ((LM_DEBUG, "Printing intermediate results\n")); ACE_Scheduler_Factory::dump_schedule (infos.in (), dependencies.in (), configs.in (), unsafe_anomalies, ACE_TEXT("schedule.out")); // Obtain the range of valid priorities in the current // platform, the scheduler hard-code this values in the // generated file, but in the future we may just use the // "logical" priorities and define the mapping to OS // priorities at run-time. int min_os_priority = ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); int max_os_priority = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); scheduler->compute_scheduling (min_os_priority, max_os_priority, infos.out (), dependencies.out (), configs.out (), anomalies.out ()); // Dump the schedule to a file.. ACE_Scheduler_Factory::dump_schedule (infos.in (), dependencies.in (), configs.in (), anomalies.in (), ACE_TEXT("schedule.out")); // **************************************************************** ACE_DEBUG ((LM_DEBUG, "Pushing events\n")); ACE_hthread_t thr_handle; ACE_Thread::self (thr_handle); int prio = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO); ACE_OS::thr_setprio (thr_handle, prio); // // Generate a few events.... // RtecEventComm::EventSet event1 (1); // event1.length (1); // event1[0].header.type = ACE_ES_EVENT_UNDEFINED; // event1[0].header.source = supplier_id1; // event1[0].header.ttl = 1; // RtecEventComm::EventSet event2 (1); // event2.length (1); // event2[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; // event2[0].header.source = supplier_id2; // event2[0].header.ttl = 1; // for (int i = 0; i != 200; ++i) // { // if (i % 2 == 0) // { // consumer_proxy1->push (event1); // } // else // { // consumer_proxy2->push (event2); // } // ACE_Time_Value rate (0, 10000); // ACE_OS::sleep (rate); // } ACE_DEBUG ((LM_DEBUG, "(%t) activating EC\n")); ec_impl.activate (); ACE_DEBUG ((LM_DEBUG, "EC activated\n")); orb->run (); // **************************************************************** // We should do a lot of cleanup (disconnect from the EC, // deactivate all the objects with the POA, etc.) but this is // just a simple demo so we are going to be lazy. } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("Service"); return 1; } return 0; }
TAO_EC_Filter* TAO_EC_Kokyu_Filter_Builder::build ( TAO_EC_ProxyPushSupplier *supplier, RtecEventChannelAdmin::ConsumerQOS& qos) const { CORBA::ULong i=0,found=0; CORBA::ULong pos = 0; CORBA::Long npos = -1; int establish_final_consumer_dependency=0; CORBA::Object_var tmp = this->event_channel_->scheduler (); RtecScheduler::Scheduler_var scheduler = RtecScheduler::Scheduler::_narrow (tmp.in ()); #ifdef EC_KOKYU_LOGGING for (i=0; i<qos.dependencies.length (); ++i) { ORBSVCS_DEBUG ((LM_DEBUG, "consumerqos[%d] event.header.type = %s," "rt_info = %d\n", i, designator (qos.dependencies[i].event.header.type), qos.dependencies[i].rt_info)); } #endif //find the first entry which is not a designator. We are going to //assume that this entry will have the rt_info of the connecting //consumer (ProxyPushSupplier), which is passed into this function. for (i=0; !found && i<qos.dependencies.length (); ++i) { switch (qos.dependencies[i].event.header.type) { case ACE_ES_CONJUNCTION_DESIGNATOR: case ACE_ES_DISJUNCTION_DESIGNATOR: case ACE_ES_NEGATION_DESIGNATOR: case ACE_ES_LOGICAL_AND_DESIGNATOR: case ACE_ES_BITMASK_DESIGNATOR: case ACE_ES_MASKED_TYPE_DESIGNATOR: case ACE_ES_NULL_DESIGNATOR: establish_final_consumer_dependency = 1; continue; case ACE_ES_GLOBAL_DESIGNATOR: case ACE_ES_EVENT_TIMEOUT: case ACE_ES_EVENT_INTERVAL_TIMEOUT: case ACE_ES_EVENT_DEADLINE_TIMEOUT: continue; default: npos = i; found = 1; break; } } ACE_CString final_consumer_rep_name; RtecScheduler::handle_t h_final_consumer_rt_info = 0; RtecScheduler::handle_t h_final_consumer_rep_rt_info = 0; #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "consumer rt_info found in consumerqos[%d]\n", npos)); #endif if (npos >= 0 && establish_final_consumer_dependency == 1) { //Hopefully this will have the final consumer's rt_info h_final_consumer_rt_info = qos.dependencies[npos].rt_info; #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "about to get rt_info = %d\n", h_final_consumer_rep_rt_info)); #endif RtecScheduler::RT_Info_var final_consumer_rt_info = scheduler->get ( h_final_consumer_rt_info); final_consumer_rep_name = final_consumer_rt_info->entry_point.in (); final_consumer_rep_name += "#rep"; #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "about to create consumer rep %s\n", final_consumer_rep_name.c_str ())); #endif //create an rt_info corresponding to this rep. h_final_consumer_rep_rt_info = scheduler->create (final_consumer_rep_name.c_str ()); #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "consumer rep created\n")); #endif } //We are passing the final consumer as the parent. The final //consumer is the one which is connecting to the ProxyPushSupplier //passed in to this function. TAO_EC_Filter* filter = this->recursive_build (supplier, qos, pos, scheduler.in (), h_final_consumer_rep_rt_info //parent_info ); #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "Filter_Builder::Verifying whether root filter" " dependency can be established\n")); #endif if (npos >= 0 && establish_final_consumer_dependency == 1) { #ifdef EC_KOKYU_LOGGING ORBSVCS_DEBUG ((LM_DEBUG, "Filter_Builder::root filter dependency " "can be established\n")); #endif TAO_EC_Kokyu_Filter* kokyu_filter = dynamic_cast<TAO_EC_Kokyu_Filter*> (filter); //add the dependency between the root in the filter hierarchy and //the final consumer TAO_EC_QOS_Info qos_info; kokyu_filter->get_qos_info (qos_info); scheduler->add_dependency (h_final_consumer_rt_info, qos_info.rt_info, 1, RtecBase::ONE_WAY_CALL); } return filter; }