int ACE_Scheduler::dispatch_configuration (const Preemption_Priority & p_priority, OS_Thread_Priority & priority, Dispatching_Type & d_type) { // look up the stored configuration info for the given priority level Config_Info *config_info; if (lookup_config_info (p_priority, config_info) != SUCCEEDED) { ORBSVCS_ERROR_RETURN ((LM_ERROR, "Config info for priority %lu could not be found\n", p_priority), -1); } priority = config_info->thread_priority; d_type = config_info->dispatching_type; return 0; }
void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority, CORBA::Long maximum_priority, RtecScheduler::RT_Info_Set_out infos, RtecScheduler::Dependency_Set_out dependencies, RtecScheduler::Config_Info_Set_out configs, RtecScheduler::Scheduling_Anomaly_Set_out anomalies) { // Initialize the scheduler implementation. impl->init (minimum_priority, maximum_priority); // Construct an unbounded set to hold any scheduling anomalies. ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> anomaly_set; // Invoke the imlementation's scheduling method. BaseSchedImplType::status_t schedule_status; schedule_status = impl->schedule (anomaly_set); if (dependencies.ptr () == 0) { dependencies = new RtecScheduler::Dependency_Set (); } // Iterate over the set of anomalies, reporting each one, storing // it in the set of anomalies to return, and determining the worst // anomaly severity. RtecScheduler::Anomaly_Severity severity = RtecScheduler::ANOMALY_NONE; RtecScheduler::Scheduling_Anomaly **anomaly = 0; const char *anomaly_severity_msg = "NONE"; CORBA::ULong anomaly_index = 0; CORBA::ULong anomaly_set_size = static_cast<CORBA::ULong> (anomaly_set.size ()); if (anomalies.ptr () == 0) { anomalies = new RtecScheduler::Scheduling_Anomaly_Set (anomaly_set_size); } anomalies->length (anomaly_set_size); ACE_Unbounded_Set_Iterator<RtecScheduler::Scheduling_Anomaly *> anomaly_iter (anomaly_set); for (anomaly_iter.first (), anomaly_index = 0; anomaly_iter.next (anomaly); anomaly_iter.advance (), ++anomaly_index) { if (0 == *anomaly) { // if for some reason we stored a null anomaly pointer, // just give default values to that entry in the sequence. anomalies[anomaly_index].severity = RtecScheduler::ANOMALY_NONE; anomalies[anomaly_index].description = ""; continue; } // Keep track of the *worst* anomaly severity switch ((*anomaly)->severity) { case RtecScheduler::ANOMALY_FATAL: anomaly_severity_msg = "FATAL"; severity = RtecScheduler::ANOMALY_FATAL; break; case RtecScheduler::ANOMALY_ERROR: anomaly_severity_msg = "ERROR"; if (severity != RtecScheduler::ANOMALY_FATAL) { severity = RtecScheduler::ANOMALY_ERROR; } break; case RtecScheduler::ANOMALY_WARNING: anomaly_severity_msg = "WARNING"; if ((severity != RtecScheduler::ANOMALY_FATAL) && (severity != RtecScheduler::ANOMALY_ERROR)) { severity = RtecScheduler::ANOMALY_WARNING; } break; // case RtecScheduler::ANOMALY_NONE: // case Anomaly_Severity_TAO_ENUM_32BIT_ENFORCER: default: anomaly_severity_msg = "UNKNOWN"; break; } // Output the anomaly message ORBSVCS_DEBUG ((LM_DEBUG, "%s: %s\n", anomaly_severity_msg, (*anomaly)->description.in ())); // Store the anomaly in the anomaly sequence out parameter anomalies[anomaly_index] = **anomaly; // Release the anomaly node. delete *anomaly; } switch (severity) { // On a fatal anomaly abort without generating a schedule. case RtecScheduler::ANOMALY_FATAL: // TODO: throw something. ORBSVCS_ERROR ((LM_ERROR, "Schedule failed due to FATAL anomaly.\n")); return; // Otherwise, make sure we didn't get a fatal return type. default: switch (schedule_status) { case BaseSchedImplType::ST_BAD_INTERNAL_POINTER : // TODO: throw something. ORBSVCS_ERROR ((LM_ERROR, "Schedule failed due to bad internal pointer.\n")); return; case BaseSchedImplType::ST_VIRTUAL_MEMORY_EXHAUSTED : // TODO: throw something. ORBSVCS_ERROR ((LM_ERROR, "Schedule failed due to insufficient memory.\n")); return; case BaseSchedImplType::THREAD_COUNT_MISMATCH : // TODO: throw something. ORBSVCS_ERROR ((LM_ERROR, "Schedule failed due to thread count mismatch.\n")); return; case BaseSchedImplType::TASK_COUNT_MISMATCH : // TODO: throw something. ORBSVCS_ERROR ((LM_ERROR, "Schedule failed due to task count mismatch.\n")); return; // Otherwise, go ahead and generate a schedule. default: break; } break; } // return the set of scheduled RT_Infos if (infos.ptr () == 0) { infos = new RtecScheduler::RT_Info_Set (impl->tasks ()); } infos->length (impl->tasks ()); for (RtecScheduler::handle_t handle = 1; handle <= static_cast<RtecScheduler::handle_t> (impl->tasks ()); ++handle) { RtecScheduler::RT_Info* rt_info = 0; switch (impl->lookup_rt_info (handle, rt_info)) { case BaseSchedImplType::SUCCEEDED: // We know that handles start at 1. infos[static_cast<CORBA::ULong> (handle - 1)] = *rt_info; break; case BaseSchedImplType::FAILED: case BaseSchedImplType::ST_UNKNOWN_TASK: default: ORBSVCS_ERROR ((LM_ERROR, "Config_Scheduler::schedule - lookup_rt_info failed\n")); // TODO: throw something. break; } } // return the set of scheduled Config_Infos if (configs.ptr () == 0) { configs = new RtecScheduler::Config_Info_Set(impl->minimum_priority_queue () + 1); } configs->length (impl->minimum_priority_queue () + 1); for (RtecScheduler::Preemption_Priority_t priority = 0; priority <= static_cast<RtecScheduler::Preemption_Priority_t> (impl->minimum_priority_queue ()); ++priority) { RtecScheduler::Config_Info* config_info = 0; switch (impl->lookup_config_info (priority, config_info)) { case BaseSchedImplType::SUCCEEDED: // We know that handles start at 1. configs[CORBA::ULong(priority)] = *config_info; break; case BaseSchedImplType::FAILED: case BaseSchedImplType::ST_UNKNOWN_TASK: default: ORBSVCS_ERROR ((LM_ERROR, "Config_Scheduler::schedule - " "lookup_config_info failed\n")); // TODO: throw something. break; } } ORBSVCS_DEBUG ((LM_DEBUG, "Schedule prepared.\n")); ORBSVCS_DEBUG ((LM_DEBUG, "Dumping to stdout.\n")); ACE_Scheduler_Factory::dump_schedule (*(infos.ptr()), *(dependencies.ptr()), *(configs.ptr()), *(anomalies.ptr()), 0); ORBSVCS_DEBUG ((LM_DEBUG, "Dump done.\n")); }