diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-05-15 07:48:02 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-05-15 07:48:02 +0000 |
commit | 5d477b4d8152c151940b868790c290f10467b92e (patch) | |
tree | 47aaf390a2896d99a518019ee3f00f6c55e2ef73 /TAO/orbsvcs/orbsvcs/Sched | |
parent | 438d0c8b9b7b135421c872bd4daea8d5bf017e7e (diff) | |
download | ATCD-ACE-4_5_5.tar.gz |
This commit was manufactured by cvs2svn to create tag 'ACE-4_5_5'.ACE-4_5_5
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Sched')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp | 371 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h | 157 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i | 5 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp | 1772 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/DynSched.h | 483 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/DynSched.i | 111 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp | 875 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h | 591 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i | 402 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp | 280 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler.h | 276 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler.i | 20 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp | 262 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h | 129 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i | 21 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp | 1419 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h | 571 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i | 21 |
18 files changed, 0 insertions, 7766 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp deleted file mode 100644 index 17bc1c1b518..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp +++ /dev/null @@ -1,371 +0,0 @@ -// ============================================================================ -// -// $Id$ -// -// ============================================================================ - -#include "orbsvcs/Time_Utilities.h" -#include "orbsvcs/Scheduler_Factory.h" - -#if defined (TAO_USES_STRATEGY_SCHEDULER) -#include "Strategy_Scheduler.h" -#else -#include "Scheduler_Generic.h" -#endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ - -#include "Config_Scheduler.h" - -#if defined (__ACE_INLINE__) -#include "Config_Scheduler.i" -#endif /* __ACE_INLINE__ */ - -ACE_Config_Scheduler::ACE_Config_Scheduler (void) -#if defined (TAO_USES_STRATEGY_SCHEDULER) - : scheduler_strategy_ ((RtecScheduler::Preemption_Priority) TAO_MIN_CRITICAL_PRIORITY) - , impl (new ACE_Strategy_Scheduler (scheduler_strategy_)) -#else - : impl (new Scheduler_Generic) -#endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ -{ - // impl->output_level (10); -} - -ACE_Config_Scheduler::~ACE_Config_Scheduler (void) -{ - delete impl; -} - -RtecScheduler::handle_t -ACE_Config_Scheduler::create (const char * entry_point, - CORBA::Environment &) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::DUPLICATE_NAME)) -{ - typedef RtecScheduler::RT_Info* RT_Info_ptr; - - RtecScheduler::RT_Info** rt_info; - ACE_NEW_RETURN (rt_info, RT_Info_ptr[1], -1); - - ACE_NEW_RETURN (rt_info[0], RtecScheduler::RT_Info, -1); - - rt_info[0]->entry_point = CORBA::string_dup(entry_point); - rt_info[0]->handle = -1; - rt_info[0]->worst_case_execution_time = ORBSVCS_Time::zero; - rt_info[0]->typical_execution_time = ORBSVCS_Time::zero; - rt_info[0]->cached_execution_time = ORBSVCS_Time::zero; - rt_info[0]->period = 0; - rt_info[0]->importance = RtecScheduler::VERY_LOW_IMPORTANCE; - rt_info[0]->quantum = ORBSVCS_Time::zero; - rt_info[0]->threads = 0; - rt_info[0]->priority = 0; - rt_info[0]->dynamic_subpriority = 0; - rt_info[0]->static_subpriority = 0; - rt_info[0]->preemption_priority = 0; - - RtecScheduler::handle_t handle = -1; -#if defined (TAO_USES_STRATEGY_SCHEDULER) - switch (impl->register_task (rt_info[0], handle)) -#else - switch (impl->register_task (rt_info, 1, handle)) -#endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ - - { - case BaseSchedImplType::SUCCEEDED: - break; - case BaseSchedImplType::ST_VIRTUAL_MEMORY_EXHAUSTED: - case BaseSchedImplType::ST_TASK_ALREADY_REGISTERED: - default: - delete rt_info[0]; - delete[] rt_info; - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::create - register_task failed\n")); - // @@ TODO: throw something. - break; - } - return handle; -} - -RtecScheduler::handle_t -ACE_Config_Scheduler::lookup (const char * entry_point, - CORBA::Environment &) - TAO_THROW_SPEC ((CORBA::SystemException)) -{ - RtecScheduler::RT_Info* rt_info = 0; - switch (impl->get_rt_info (entry_point, rt_info)) - { - case BaseSchedImplType::SUCCEEDED: - return rt_info->handle; - ACE_NOTREACHED (break); - case BaseSchedImplType::FAILED: - case BaseSchedImplType::ST_UNKNOWN_TASK: - default: - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::lookup - get_rt_info failed\n")); - // @@ TODO: throw something. - break; - } - return -1; -} - -RtecScheduler::RT_Info* -ACE_Config_Scheduler::get (RtecScheduler::handle_t handle, - CORBA::Environment &) - TAO_THROW_SPEC((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)) -{ - RtecScheduler::RT_Info* rt_info = 0; - switch (impl->lookup_rt_info (handle, rt_info)) - { - case BaseSchedImplType::SUCCEEDED: - { - // IDL memory managment semantics require the we return a copy - RtecScheduler::RT_Info* copy; - ACE_NEW_RETURN (copy, RtecScheduler::RT_Info (*rt_info), 0); - return copy; - } - ACE_NOTREACHED (break); - case BaseSchedImplType::FAILED: - case BaseSchedImplType::ST_UNKNOWN_TASK: - default: - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::get - lookup_rt_info failed\n")); - // @@ TODO: throw something. - break; - } - return 0; -} - -void ACE_Config_Scheduler::set (RtecScheduler::handle_t handle, - RtecScheduler::Criticality criticality, - const RtecScheduler::Time &time, - const RtecScheduler::Time &typical_time, - const RtecScheduler::Time &cached_time, - RtecScheduler::Period period, - RtecScheduler::Importance importance, - const RtecScheduler::Quantum &quantum, - CORBA::Long threads, - RtecScheduler::Info_Type info_type, - CORBA::Environment &) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)) -{ - RtecScheduler::RT_Info* rt_info = 0; - switch (impl->lookup_rt_info (handle, rt_info)) - { - case BaseSchedImplType::SUCCEEDED: - rt_info->criticality = criticality, - rt_info->worst_case_execution_time = time; - rt_info->typical_execution_time = typical_time; - rt_info->cached_execution_time = cached_time; - rt_info->period = period; - rt_info->importance = importance; - rt_info->quantum = quantum; - rt_info->threads = threads; - rt_info->info_type = info_type; - break; - case BaseSchedImplType::FAILED: - case BaseSchedImplType::ST_UNKNOWN_TASK: - default: - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::set - lookup_rt_info failed\n")); - // @@ TODO: throw something. - break; - } -} - -void ACE_Config_Scheduler::priority (RtecScheduler::handle_t handle, - RtecScheduler::OS_Priority& priority, - RtecScheduler::Sub_Priority& subpriority, - RtecScheduler::Preemption_Priority& p_priority, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::NOT_SCHEDULED)) -{ - ACE_UNUSED_ARG (_env); - - if (impl->priority (handle, priority, subpriority, p_priority) == -1) - { - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::priority - priority failed\n")); - // TODO: throw something. - } -} - -void ACE_Config_Scheduler::entry_point_priority (const char * entry_point, - RtecScheduler::OS_Priority& priority, - RtecScheduler::Sub_Priority& subpriority, - RtecScheduler::Preemption_Priority& p_priority, - CORBA::Environment &_env) - TAO_THROW_SPEC((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::NOT_SCHEDULED)) -{ - this->priority (lookup (entry_point, _env), - priority, subpriority, p_priority, - _env); -} - -void ACE_Config_Scheduler::add_dependency (RtecScheduler::handle_t handle, - RtecScheduler::handle_t dependency, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type - dependency_type, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)) -{ - ACE_UNUSED_ARG (_env); - - RtecScheduler::RT_Info* rt_info = 0; - switch (impl->lookup_rt_info (handle, rt_info)) - { - case BaseSchedImplType::SUCCEEDED: - { - RtecScheduler::Dependency_Info dep; - dep.rt_info = dependency; - dep.number_of_calls = number_of_calls; - dep.dependency_type = dependency_type; -#if defined (TAO_USES_STRATEGY_SCHEDULER) - impl->add_dependency (rt_info, dep); -#else - BaseSchedImplType::add_dependency (rt_info, dep); -#endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ - - } - break; - case BaseSchedImplType::FAILED: - case BaseSchedImplType::ST_UNKNOWN_TASK: - default: - ACE_ERROR ((LM_ERROR, - "cannot find %d to add dependency", handle)); - // TODO: throw something. - break; - } -} - -void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority, - CORBA::Long maximum_priority, - RtecScheduler::RT_Info_Set_out infos, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UTILIZATION_BOUND_EXCEEDED, - RtecScheduler::INSUFFICIENT_THREAD_PRIORITY_LEVELS, - RtecScheduler::TASK_COUNT_MISMATCH)) -{ - ACE_UNUSED_ARG (_env); - - impl->init (minimum_priority, maximum_priority); - if (impl->schedule () != BaseSchedImplType::SUCCEEDED) - { - // TODO: throw something. - ACE_ERROR ((LM_ERROR, "schedule failed\n")); - return; - } - if (infos == 0) - { - infos = new RtecScheduler::RT_Info_Set(impl->tasks ()); - } - infos->length (impl->tasks ()); - for (RtecScheduler::handle_t handle = 1; - handle <= (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[CORBA::ULong(handle - 1)] = *rt_info; - break; - case BaseSchedImplType::FAILED: - case BaseSchedImplType::ST_UNKNOWN_TASK: - default: - ACE_ERROR ((LM_ERROR, - "Config_Scheduler::schedule - lookup_rt_info failed\n")); - // TODO: throw something. - break; - } - } - ACE_DEBUG ((LM_DEBUG, "schedule prepared\n")); - - ACE_DEBUG ((LM_DEBUG, "dumping to stdout\n")); - ACE_Scheduler_Factory::dump_schedule (*(infos.ptr()), 0); - ACE_DEBUG ((LM_DEBUG, "dump done\n")); -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - #if defined (TAO_USES_STRATEGY_SCHEDULER) - #if defined (TAO_USES_MUF_SCHEDULING) - - template class ACE_Strategy_Scheduler_Factory<ACE_MUF_Scheduler_Strategy>; - - #elif defined (TAO_USES_MLF_SCHEDULING) - - template class ACE_Strategy_Scheduler_Factory<ACE_MLF_Scheduler_Strategy>; - - #elif defined (TAO_USES_EDF_SCHEDULING) - - template class ACE_Strategy_Scheduler_Factory<ACE_EDF_Scheduler_Strategy>; - - #elif defined (TAO_USES_RMS_SCHEDULING) - - template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Scheduler_Strategy>; - - #elif defined (TAO_USES_RMS_DYN_SCHEDULING) - - template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Dyn_Scheduler_Strategy>; - - #else - - #error scheduling strategy must be defined - - #endif /* defined (TAO_USES_MUF_SCHEDULING) */ - #endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - #if defined (TAO_USES_STRATEGY_SCHEDULER) - #if defined (TAO_USES_MUF_SCHEDULING) - - #pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_MUF_Scheduler_Strategy> - - #elif defined (TAO_USES_MLF_SCHEDULING) - - #pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_MLF_Scheduler_Strategy> - - #elif defined (TAO_USES_EDF_SCHEDULING) - - #pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_EDF_Scheduler_Strategy> - - #elif defined (TAO_USES_RMS_SCHEDULING) - - #pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_RMS_Scheduler_Strategy> - - #elif defined (TAO_USES_RMS_DYN_SCHEDULING) - - #pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_RMS_Dyn_Scheduler_Strategy> - - #else - - #error scheduling strategy must be defined - - #endif /* defined (TAO_USES_MUF_SCHEDULING) */ - #endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ -#endif /* defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) */ - - - - - - - - - - - - - - - - diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h deleted file mode 100644 index 63cb06961ba..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h +++ /dev/null @@ -1,157 +0,0 @@ -// $Id$ - -#ifndef ACE_CONFIG_SCHEDULER_H -#define ACE_CONFIG_SCHEDULER_H - -#include "ace/OS.h" - -#include "orbsvcs/RtecSchedulerS.h" -#include "orbsvcs/Event_Service_Constants.h" - -class ACE_Scheduler; - -class TAO_ORBSVCS_Export ACE_Config_Scheduler -: public POA_RtecScheduler::Scheduler - // = TITLE - // A (local) implementation for the RtecScheduler::Scheduler service. - // - // = DESCRIPTION - // This class implements a servant for the - // RtecScheduler::Scheduler service, using the Scheduler classes - // distributed with the EC. -{ -public: - - ACE_Config_Scheduler (void); - virtual ~ACE_Config_Scheduler (void); - - virtual RtecScheduler::handle_t create (const char * entry_point, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::DUPLICATE_NAME)); - - virtual RtecScheduler::handle_t lookup (const char * entry_point, - CORBA::Environment &_env) - TAO_THROW_SPEC((CORBA::SystemException)); - - virtual RtecScheduler::RT_Info* get (RtecScheduler::handle_t handle, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::UNKNOWN_TASK)); - - virtual void set (RtecScheduler::handle_t handle, - RtecScheduler::Criticality criticality, - const RtecScheduler::Time &time, - const RtecScheduler::Time &typical_time, - const RtecScheduler::Time &cached_time, - RtecScheduler::Period period, - RtecScheduler::Importance importance, - const RtecScheduler::Quantum &quantum, - CORBA::Long threads, - RtecScheduler::Info_Type info_type, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::UNKNOWN_TASK)); - - virtual void priority (RtecScheduler::handle_t handle, - RtecScheduler::OS_Priority& priority, - RtecScheduler::Sub_Priority& subpriority, - RtecScheduler::Preemption_Priority& p_priority, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::NOT_SCHEDULED)); - - virtual void entry_point_priority (const char * entry_point, - RtecScheduler::OS_Priority& priority, - RtecScheduler::Sub_Priority& subpriority, - RtecScheduler::Preemption_Priority& p_priority, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::NOT_SCHEDULED)); - - virtual void add_dependency (RtecScheduler::handle_t handle, - RtecScheduler::handle_t dependency, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type dependency_type, - CORBA::Environment &_env) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)); - - virtual void compute_scheduling (CORBA::Long minimum_priority, - CORBA::Long maximum_priority, - RtecScheduler::RT_Info_Set_out infos, - CORBA::Environment &_env) - TAO_THROW_SPEC((CORBA::SystemException, - RtecScheduler::UTILIZATION_BOUND_EXCEEDED, - RtecScheduler::INSUFFICIENT_THREAD_PRIORITY_LEVELS, - RtecScheduler::TASK_COUNT_MISMATCH)); - -private: - -#if defined (TAO_USES_STRATEGY_SCHEDULER) - - // trait for the scheduler implementation base class - typedef ACE_DynScheduler BaseSchedImplType; - - // traits for the scheduler strategy -#if defined (TAO_USES_MUF_SCHEDULING) - - typedef ACE_MUF_Scheduler_Strategy Scheduler_Strategy; - -#elif defined (TAO_USES_MLF_SCHEDULING) - - #if ! defined (TAO_MIN_CRITICAL_PRIORITY) - #define TAO_MIN_CRITICAL_PRIORITY 0 - #endif /* ! defined (TAO_MIN_CRITICAL_PRIORITY) */ - - typedef ACE_MLF_Scheduler_Strategy Scheduler_Strategy; - -#elif defined (TAO_USES_EDF_SCHEDULING) - - #if ! defined (TAO_MIN_CRITICAL_PRIORITY) - #define TAO_MIN_CRITICAL_PRIORITY 0 - #endif /* ! defined (TAO_MIN_CRITICAL_PRIORITY) */ - - typedef ACE_EDF_Scheduler_Strategy Scheduler_Strategy; - -#elif defined (TAO_USES_RMS_SCHEDULING) - - typedef ACE_RMS_Scheduler_Strategy Scheduler_Strategy; - -#elif defined (TAO_USES_RMS_DYN_SCHEDULING) - - typedef ACE_RMS_Dyn_Scheduler_Strategy Scheduler_Strategy; - -#else - - #error scheduling strategy must be defined - -#endif /* defined (TAO_USES_MUF_SCHEDULING) */ - - Scheduler_Strategy scheduler_strategy_; - -#else /* ! defined (TAO_USES_STRATEGY_SCHEDULER) */ - - // trait for the scheduler implementation base class - typedef ACE_Scheduler BaseSchedImplType; - -#endif /* defined (TAO_USES_STRATEGY_SCHEDULER) */ - - // implementation base class pointer - BaseSchedImplType* impl; - -}; - -#if defined (__ACE_INLINE__) -#include "Config_Scheduler.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_CONFIG_SCHEDULER_H */ - - - - - - - - - diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i deleted file mode 100644 index a21ea7f9897..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i +++ /dev/null @@ -1,5 +0,0 @@ -// ============================================================================ -// -// $Id$ -// -// ============================================================================ diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp b/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp deleted file mode 100644 index fa110e2522d..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp +++ /dev/null @@ -1,1772 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// DynSched.cpp -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#include "DynSched.h" -#include "ace/Sched_Params.h" -#include "math.h" - -#if ! defined (__ACE_INLINE__) -#include "DynSched.i" -#endif /* __ACE_INLINE__ */ - -////////////////////// -// Helper functions // -////////////////////// - -// compare the DFS finish times of two task entries, order higher time *first* -extern "C" int compare_entry_finish_times (const void *first, const void *second) -{ - // sort blank entries to the end - if (! first) - { - return (second) ? 1 : 0; - } - else if (! second) - { - return -1; - } - - const Task_Entry *first_entry = - * ACE_static_cast (const Task_Entry *const *, first); - const Task_Entry *second_entry = - * ACE_static_cast (const Task_Entry *const *, second); - - // sort blank entries to the end - if (! first_entry) - { - return (second_entry) ? 1 : 0; - } - else if (! second_entry) - { - return -1; - } - - if (first_entry->finished () > second_entry->finished ()) - { - return -1; - } - else if (first_entry->finished () < second_entry->finished ()) - { - return 1; - } - - return 0; -} - -////////////////////////////////////////// -// class ACE_DynScheduler member functions // -////////////////////////////////////////// - -const char * -ACE_DynScheduler::status_message (ACE_DynScheduler::status_t status) -{ - switch (status) - { - case NOT_SCHEDULED : - return "NOT_SCHEDULED"; - case SUCCEEDED : - return "SUCCEEDED"; - case ST_TASK_ALREADY_REGISTERED : - return "TASK_ALREADY_REGISTERED"; - case ST_BAD_DEPENDENCIES_ON_TASK : - return "BAD_DEPENDENCIES_ON_TASK"; - case ST_BAD_INTERNAL_POINTER : - return "BAD_INTERNAL_POINTER"; - case ST_VIRTUAL_MEMORY_EXHAUSTED : - return "VIRTUAL_MEMORY_EXHAUSTED"; - case ST_UNKNOWN_TASK : - return "UNKNOWN_TASK"; - case TASK_COUNT_MISMATCH : - return "TASK_COUNT_MISMATCH"; - case INVALID_PRIORITY : - return "INVALID_PRIORITY"; - - // The following are only used during scheduling (in the case of - // off-line scheduling, they are only used prior to runtime). - // To save a little code space (280 bytes on g++ 2.7.2/Solaris 2.5.1), - // we could conditionally compile them so that they're not in the - // runtime version. - case ST_UTILIZATION_BOUND_EXCEEDED : - return "UTILIZATION_BOUND_EXCEEDED"; - case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS : - return "INSUFFICIENT_THREAD_PRIORITY_LEVELS"; - case ST_CYCLE_IN_DEPENDENCIES : - return "CYCLE_IN_DEPENDENCIES"; - case ST_INVALID_PRIORITY_ORDERING : - return "INVALID_PRIORITY_ORDERING"; - case UNABLE_TO_OPEN_SCHEDULE_FILE : - return "UNABLE_TO_OPEN_SCHEDULE_FILE"; - case UNABLE_TO_WRITE_SCHEDULE_FILE : - return "UNABLE_TO_WRITE_SCHEDULE_FILE"; - // End of config-only status values. - - default: - break; - } - - return "UNKNOWN STATUS"; -} - - -ACE_DynScheduler::ACE_DynScheduler () - // Set the minimum and maximum priority to those for the current platform. - // This shouldn't be necessary, but UPSingleProcessorOrb::initialize_reactors - // creates threads before the Event Channel calls Scheduler::init (). - : minimum_priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, - ACE_SCOPE_PROCESS)) - , maximum_priority_ (ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, - ACE_SCOPE_PROCESS)) - , task_entries_ (0) - , ordered_task_entries_ (0) - , thread_delineators_ (0) - , ordered_thread_dispatch_entries_ (0) - , dispatch_entries_ (0) - , expanded_dispatches_ (0) - , ordered_dispatch_entries_ (0) - , dispatch_entry_count_ (0) - , threads_ (0) - , timeline_ (0) - , lock_ () - , rt_info_entries_ () - , handles_ (0) - , runtime_filename_ (0) - , rt_info_filename_ (0) - , timeline_filename_ (0) - , tasks_ (0) - , status_ (NOT_SCHEDULED) - , output_level_ (0) - , frame_size_ (1) - , critical_set_frame_size_ (0) - , utilization_ (0.0) - , critical_set_utilization_ (0.0) - , minimum_priority_queue_ (0) - , minimum_guaranteed_priority_queue_ (-1) - , up_to_date_ (0) - , min_dispatch_id_ (0) - , max_dispatch_id_ (0) -{ -} - - -ACE_DynScheduler::~ACE_DynScheduler () -{ - // release all resources used for the most recent schedule - reset (); -} - - -void -ACE_DynScheduler::init (const OS_Priority minimum_priority, - const OS_Priority maximum_priority, - const char *runtime_filename, - const char *rt_info_filename, - const char *timeline_filename) -{ - minimum_priority_ = minimum_priority; - maximum_priority_ = maximum_priority; - runtime_filename_ = runtime_filename; - rt_info_filename_ = rt_info_filename; - timeline_filename_ = timeline_filename; -} - // = initializes the scheduler. - -ACE_DynScheduler::status_t -ACE_DynScheduler::register_task (RT_Info *rt_info, handle_t &handle) -{ - ACE_DynScheduler::status_t ret; - - // check the pointer we were passed - if (! rt_info) - { - handle = 0; - return ST_UNKNOWN_TASK; - } - - // try to store the new task's information . . . - switch (rt_info_entries_.insert (rt_info)) - { - case 0 : // successfully inserted - { - rt_info->handle = (handle = ++handles_); - ret = SUCCEEDED; - - // zero out the task entry ACT used by the scheduler - rt_info->volatile_token = 0; - - // make sure the schedule is reset when a new task is registered - reset (); - - if (output_level () >= 5) - { - ACE_OS::printf ("registered task \"%s\" with RT_Info at %X\n", - (const char*)(rt_info->entry_point), - (void *) rt_info); - } - } - break; - - case 1 : // the entry had already been inserted - handle = 0; - ret = ST_TASK_ALREADY_REGISTERED; - break; - - default : - // case -1 : insert failed, probably because virtual memory exhaused - handle = 0; - ret = ST_VIRTUAL_MEMORY_EXHAUSTED; - break; - } - - return ret; -} - // = registers a task. - - - -ACE_DynScheduler::status_t -ACE_DynScheduler::get_rt_info (Object_Name name, - RT_Info* &rtinfo) -{ - handle_t handle; - - // This makes a copy. We can optimize this with our own string - // class. - ACE_CString lookup (name); - // Search the map for the <name>. If found, return the RT_Info. - if (info_collection_.find (lookup, rtinfo) >= 0) - { - // If we find it, return. - return SUCCEEDED; - } - else - // Otherwise, make one, bind it, and register it. - { - rtinfo = new RT_Info; - rtinfo->info_type = RtecScheduler::OPERATION; - rtinfo->entry_point = name; - // Bind the rtinfo to the name. - if (info_collection_.bind (lookup, rtinfo) != 0) - { - delete rtinfo; - rtinfo = 0; - return FAILED; // Error! - } - else - { - // Register the task - status_t result = this->register_task (rtinfo, handle); - if (result == SUCCEEDED) - { - rtinfo->handle = handle; - return ST_UNKNOWN_TASK; // Didn't find it, but made one! - } - else - { - rtinfo->handle = 0; - return FAILED; - } - } - } -} - - - - -int ACE_DynScheduler::priority ( - const RtecScheduler::handle_t handle, - RtecScheduler::OS_Priority &priority, - RtecScheduler::Sub_Priority &subpriority, - RtecScheduler::Preemption_Priority &preemption_prio) -{ - // look up the RT_Info that has the given handle - RT_Info *rt_info = 0; - if (lookup_rt_info (handle, rt_info) == SUCCEEDED) - { - // copy the priority values from the RT_Info - priority = rt_info->priority; - subpriority = rt_info->static_subpriority; - preemption_prio = rt_info->preemption_priority; - - return 0; - } - else - - { - // RT_Info not found: assign default priority values - priority = minimum_priority_; - subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; - preemption_prio = ACE_Scheduler_MAX_PREEMPTION_PRIORITY; - - if (output_level () >= 3) - { - ACE_OS::printf ("preemption_prio %d: min %d, pri %d, min_pri %d\n", - preemption_prio, minimum_priority_queue (), - priority, minimum_priority_); - } - - return -1; - } -} - // "priority" is the OS thread priority that was assigned to the Task that - // was assigned "handle". "subpriority" combines the dynamic and static - // subpriorities of the Task that was assigned handle. "preemption_prio" - // is a platform-independent priority queue number, ranging from a - // highest priority value of 0 to the lowest priority value, which is - // returned by "minimum_priority_queue ()". The current and deadline times - // supplied are used to compute the operation's dynamic subpriority - // Returns 0 on success, or -1 if an invalid handle was supplied. - - -int ACE_DynScheduler::number_of_dependencies(RT_Info* rt_info) -{ - return rt_info->dependencies.length(); -} - -int ACE_DynScheduler::number_of_dependencies(RT_Info& rt_info) -{ - return rt_info.dependencies.length(); -} - -int ACE_DynScheduler::add_dependency(RT_Info* rt_info, - Dependency_Info& d) -{ - RT_Info *temp_info = 0; // temporary pointer to the caller's RT_Info - - switch (d.dependency_type) - { - case RtecScheduler::TWO_WAY_CALL: - - temp_info = rt_info; - break; - - case RtecScheduler::ONE_WAY_CALL: - - // swap the handles and point to the caller instead of the called operation - if (lookup_rt_info (d.rt_info, temp_info) != SUCCEEDED) - { - ACE_ERROR ((LM_ERROR, "cannot find %d to add dependency\n", d.rt_info)); - return -1; - } - - d.rt_info = temp_info->handle; - - default: - - ACE_ERROR ((LM_ERROR, "unrecognized dependency type %d for %s\n", - d.dependency_type, rt_info->entry_point.in ())); - return -1; - } - - ACE_DEBUG ((LM_DEBUG, "adding dependecy to: %s\n", - (const char*)temp_info->entry_point)); - - RtecScheduler::Dependency_Set& set = temp_info->dependencies; - int l = set.length(); - set.length(l + 1); - set[l] = d; - return 0; -} - -void ACE_DynScheduler::export(RT_Info* info, FILE* file) -{ - export(*info, file); -} - -void ACE_DynScheduler::export(RT_Info& info, FILE* file) -{ - // The .low selection is for CosTimeBase::ulonglong support. It - // should change after that is finalized to support 64 bit integers - // on all platforms. - (void) ACE_OS::fprintf (file, - "%s\n%d\n%ld\n%ld\n%ld\n%ld\n%d\n%d\n%ld\n%u\n" - "# begin calls\n%d\n", - info.entry_point.in (), - info.handle, - info.worst_case_execution_time.low, - info.typical_execution_time.low, - info.cached_execution_time.low, - info.period, - info.criticality, - info.importance, - info.quantum.low, - info.threads, - number_of_dependencies(info)); - - for (int i = 0; i < number_of_dependencies(info); ++i) - { - RT_Info tmp; - (void) ACE_OS::fprintf (file, "%s, %d\n", - (const char*)tmp.entry_point, - info.dependencies[i].number_of_calls); - - } - - (void) ACE_OS::fprintf (file, "# end calls\n%d\n%d\n%d\n\n", - info.priority, - info.dynamic_subpriority, - info.static_subpriority); - - -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::lookup_rt_info (handle_t handle, - RT_Info*& rtinfo) -{ - if (handle < 0 || (size_t) handle > rt_info_entries_.size ()) - { - return ST_UNKNOWN_TASK; - } - - RT_Info** entry; - ACE_Unbounded_Set_Iterator <RT_Info *> i (rt_info_entries_); - while (i.next (entry) != 0) - { - i.advance (); - RT_Info* info_ptr = *entry; - if (info_ptr->handle == handle) - { - rtinfo = info_ptr; - return SUCCEEDED; - } - } - - return ST_UNKNOWN_TASK; -} - // obtains an RT_Info based on its "handle". - - -void -ACE_DynScheduler::reset () -{ - // if the schedule is up to date, free resources - // and mark schedule as not being up to date - if (up_to_date_) - { - delete [] task_entries_; - task_entries_ = 0; - - delete [] ordered_task_entries_; - ordered_task_entries_ = 0; - - delete thread_delineators_; - thread_delineators_ = 0; - - delete [] ordered_thread_dispatch_entries_; - ordered_thread_dispatch_entries_ = 0; - - if (dispatch_entries_) - { - // free all the dispatch entries in the list, then the list itself - ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*dispatch_entries_); - Dispatch_Entry **entry = 0; - for (iter.first (); ! iter.done (); iter.advance (), entry = 0) - { - if ((iter.next (entry) != 0) && (entry) && (*entry)) - { - delete (*entry); - } - } - delete dispatch_entries_; - dispatch_entries_ = 0; - } - - if (expanded_dispatches_) - { - // free all the dispatch entries in the list, then the list itself - ACE_Unbounded_Set_Iterator <Dispatch_Entry *> expanded_iter (*expanded_dispatches_); - Dispatch_Entry **expanded_entry = 0; - for (expanded_iter.first (); ! expanded_iter.done (); - expanded_iter.advance (), expanded_entry = 0) - { - if ((expanded_iter.next (expanded_entry) != 0) && - (expanded_entry) && (*expanded_entry)) - { - delete (*expanded_entry); - } - } - delete expanded_dispatches_; - expanded_dispatches_ = 0; - } - - delete [] ordered_dispatch_entries_; - ordered_dispatch_entries_ = 0; - - dispatch_entry_count_ = 0; - threads_ = 0; - - status_ = NOT_SCHEDULED; - - frame_size_ = 1; - critical_set_frame_size_ = 0; - utilization_ = 0.0; - critical_set_utilization_ = 0.0; - minimum_priority_queue_ = 0; - minimum_guaranteed_priority_queue_ = -1; - - if (timeline_) - { - // iterate over and delete the set of timeline entries - ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> t_iter (*timeline_); - TimeLine_Entry_Link *t_entry = 0; - for (t_iter.first (); ! t_iter.done (); t_iter.advance (), t_entry = 0) - { - if ((t_iter.next (t_entry) != 0) && (t_entry)) - { - delete &(t_entry->entry ()); - } - } - delete timeline_; - timeline_ = 0; - } - - up_to_date_ = 0; - } -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::schedule (void) -{ - status_t temp_status = SUCCEEDED; - - ACE_Guard<LOCK> ace_mon (lock_); - - if (up_to_date_) - { - // do nothing if the RT_Infos have not changed - // since the last valid schedule was generated - return SUCCEEDED; - } - else - { - // save the total number of registered RT_Infos - tasks (rt_info_entries_.size ()); - } - - // set up the task entry data structures, check for call cycles - status_ = setup_task_entries (); - - if (status_ == SUCCEEDED) - { - // check for cycles in the dependency graph: as a side effect, leaves - // the ordered_task_entries_ pointer array sorted in topological order, - // which is used by propagate_dispatches () to ensure that dispatches - // are propagated top down in the call graph. - status_ = check_dependency_cycles (); - } - - if (status_ == SUCCEEDED) - { - // task entries are related, now threads can be found - status_ = identify_threads (); - } - - if (status_ == SUCCEEDED) - { - // invokes the internal thread scheduling method of the strategy - status_ = schedule_threads (); - } - - if (status_ == SUCCEEDED) - { - // propagate the dispatch information from the - // threads throughout the call graph - status_ = propagate_dispatches (); - } - - if (status_ == SUCCEEDED) - { - // invokes the internal dispatch scheduling method of the strategy - status_ = schedule_dispatches (); - } - - // calculate utilization, total frame size, critical set - if (status_ == SUCCEEDED) - { - status_ = calculate_utilization_params (); - } - - // generate the scheduling timeline over the total frame size - if ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED)) - { - temp_status = create_timeline (); - } - - if (temp_status != SUCCEEDED) - { - status_ = temp_status; - } - - // store the timeline to a file if one was given - if ((timeline_filename_ != 0) && - ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED))) - { - temp_status = output_timeline (timeline_filename_, 0); - } - - if (temp_status != SUCCEEDED) - { - status_ = temp_status; - } - - // if a valid schedule was not generated, clean up from the attempt - switch (status_) - { - // these are statuses that indicate a reasonable schedule was generated - case SUCCEEDED: - case ST_UTILIZATION_BOUND_EXCEEDED: - - // if we made it here, the schedule is done - up_to_date_ = 1; - - - break; - - default: - - // (try to) remove the output files - if (timeline_filename_ && ACE_OS::unlink (timeline_filename_) && - errno != ENOENT) - { - ACE_OS::perror ("ACE_DynScheduler::schedule (); " - "unable to remove timeline file"); - } - if (runtime_filename_ && ACE_OS::unlink (runtime_filename_) && - errno != ENOENT) - { - ACE_OS::perror ("ACE_DynScheduler::schedule (); " - "unable to remove schedule file"); - } - if (rt_info_filename_ && ACE_OS::unlink (rt_info_filename_) && - errno != ENOENT) - { - ACE_OS::perror ("ACE_DynScheduler::schedule (); " - "unable to remove rt_info file"); - } - - // free resources and remove "up_to_date" mark - reset (); - - break; - } - - - return status_; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::propagate_dispatches () -{ - u_long i; - frame_size_ = 1; - - // iterate through the ordered_task_entries_ array in order - // from highest DFS finishing time to lowest, so that every - // calling dispatch is accessed before those it calls: - // the dispatches propagate top down through the call DAG - for (i = 0; i < tasks (); ++i) - { - if (ordered_task_entries_ [i]->merge_dispatches (*dispatch_entries_) < 0) - { - return ST_UNKNOWN_TASK; - } - - if (ordered_task_entries_ [i]->effective_period () > 0) - { - frame_size_ = - minimum_frame_size (frame_size_, - ordered_task_entries_ [i]->effective_period ()); - } - else - { - return ST_UNKNOWN_TASK; - } - - } - - return SUCCEEDED; -} -// propagate the dispatch information from the -// threads throughout the call graph - - -ACE_DynScheduler::status_t -ACE_DynScheduler::calculate_utilization_params (void) -{ - critical_set_frame_size_ = 0; - utilization_ = 0.0; - critical_set_utilization_ = 0.0; - - minimum_priority_queue_ = - ordered_dispatch_entries_ [0]->priority (); - - minimum_guaranteed_priority_queue_ = -1; - - // iterate through ordered task entries, calculating frame size, utilization - for (u_int i = 0; i < dispatch_entry_count_; ++i) - { - // if we've just finished examining another priority level - if (minimum_priority_queue_ != ordered_dispatch_entries_ [i]->priority ()) - { - // update parameters for the previous priority level - update_priority_level_params (); - - // update the minimum priority queue - minimum_priority_queue_ = ordered_dispatch_entries_ [i]->priority (); - } - - // only consider computation times of dispatches on OPERATION descriptors - if ((ordered_dispatch_entries_ [i]->task_entry ().info_type () == - RtecScheduler::OPERATION) && - (ordered_dispatch_entries_ [i]->task_entry ().effective_period () > 0)) - { - // Just use low 32 bits of worst_case_execution_time. This will - // have to change when CosTimeBase.idl is finalized. - utilization_ += - ACE_static_cast(double, - ordered_dispatch_entries_ [i]-> - task_entry ().rt_info ()-> - worst_case_execution_time.low) / - ACE_static_cast(double, - ordered_dispatch_entries_ [i]-> - task_entry ().effective_period ()); - - } - } - - // update parameters for the lowest priority level - update_priority_level_params (); - - // if the critical set is schedulable, return success - return (1.0 - critical_set_utilization_ > DBL_EPSILON) - ? SUCCEEDED : ST_UTILIZATION_BOUND_EXCEEDED; -} - - - -void -ACE_DynScheduler::update_priority_level_params () -{ - // if we've just finished examining a critical priority level - if (minimum_priority_queue_ <= minimum_critical_priority ()) - { - // update the information about the critical set - critical_set_frame_size_ = frame_size_; - critical_set_utilization_ = utilization_; - } - - // if the lowest priority level considered is schedulable - if (1.0 - utilization_ > DBL_EPSILON) - { - // the minimum guaranteed priority queue is the minimum considered so far - minimum_guaranteed_priority_queue_ = minimum_priority_queue_; - } -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::setup_task_entries (void) -{ - // store number of tasks, based on registrations - tasks (rt_info_entries_.size ()); - - // clear the decks of any previous scheduling information - reset (); - - // allocate new table of task entries (wrappers for rt_infos) - ACE_NEW_RETURN (task_entries_, Task_Entry [tasks ()], - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // allocate new table of pointers to task entries (for sorting) - ACE_NEW_RETURN (ordered_task_entries_, Task_Entry *[tasks ()], - ST_VIRTUAL_MEMORY_EXHAUSTED); - ACE_OS::memset (ordered_task_entries_, 0, - sizeof (Task_Entry *) * tasks ()); - - // allocate new unbounded set for pointers to - // task entries that delineate threads - ACE_NEW_RETURN (thread_delineators_, ACE_Unbounded_Set <Dispatch_Entry *>, - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // allocate new unbounded set for pointers to dispatch entries - ACE_NEW_RETURN (dispatch_entries_, - ACE_Unbounded_Set <Dispatch_Entry *>, - ST_VIRTUAL_MEMORY_EXHAUSTED); - - - // set up links between rt_info_entries_, task_entries_, - // and ordered_task_entries_ tables - ACE_Unbounded_Set_Iterator <RT_Info *> iter (rt_info_entries_); - for (u_int i = 0; i < tasks (); ++i, iter.advance ()) - { - RT_Info** info_entry; - - // tie task entry to corresponding rt_info - if (! iter.next (info_entry)) - { - return ST_UNKNOWN_TASK; - } - task_entries_ [i].rt_info (*info_entry); - - // tie rt_info to corresponding task entry - task_entries_ [i].rt_info ()->volatile_token = (u_long) &(task_entries_ [i]); - - // tie ordered task entry pointer to corresponding task entry - ordered_task_entries_ [i] = &(task_entries_ [i]); - } - - // set up bidirectional links between task entries - return relate_task_entries (); -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::relate_task_entries (void) -{ - status_t status = SUCCEEDED; - - // do DFS traversal of the entire RT_Info handle dependency DAG, replicating - // the handle dependency DAG as a calls DAG of pointers between task - // entries (and creating its transpose, the callers DAG). This is done - // to avoid the O(n) cost of handle lookups in the RT_Infos for further - // traversal of the graph during schedule sorting. One useful side effect - // of this traversal is that is produces a topological ordering of dependencies - // in the traversal finishing times, which can be used to detect call cycles. - long time = 0; - - for (u_int i = 0; i < tasks (); ++i) - { - if ((status = relate_task_entries_recurse (time, task_entries_[i])) - != SUCCEEDED) - { - break; - } - } - - return status; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::relate_task_entries_recurse (long &time, Task_Entry &entry) -{ - - // may have entered at a non-root node previously, so this does - // not necessarily indicate a cycle in the dependency graph - if (entry.dfs_status () != Task_Entry::NOT_VISITED) - { - return SUCCEEDED; - } - - // when a node is discovered, mark it as visited, increment "time" and - // store as the entry's discovery time. This is not currently used in - // the scheduling algorithms, but is left in for possible future use - // as it shows full parenthetization of entry discovery/finishing. - entry.dfs_status (Task_Entry::VISITED); - entry.discovered (++time); - - u_int dependency_count = number_of_dependencies (*entry.rt_info ()); - if (dependency_count > 0) - { - // traverse dependencies of underlying RT_Info - for (u_int i = 0; i < dependency_count; ++i) - { - // obtain a pointer to the corresponding Task_Entry for each dependency - - RT_Info* dependency_info = 0; - lookup_rt_info(entry.rt_info ()->dependencies[i].rt_info, dependency_info); - - if (! dependency_info) - { - return ST_UNKNOWN_TASK; - } - - // obtain a pointer to the Task_Entry from the dependency RT_Info - Task_Entry *dependency_entry_ptr = - (Task_Entry *) dependency_info->volatile_token; - - if (! dependency_entry_ptr) - { - return ST_UNKNOWN_TASK; - } - - // relate the entries according to the direction of the dependency - Task_Entry_Link *link; - ACE_NEW_RETURN (link, - Task_Entry_Link (entry, - *dependency_entry_ptr, - entry.rt_info ()->dependencies[i].number_of_calls, - entry.rt_info ()->dependencies[i].dependency_type), - ST_VIRTUAL_MEMORY_EXHAUSTED); - - dependency_entry_ptr->callers ().insert (link); - entry.calls ().insert (link); - - // depth first recursion on the newly identified entry - relate_task_entries_recurse (time, *dependency_entry_ptr); - } - } - - // when a node is finished, mark it as finished, increment "time" and - // store as the entry's finish time. This produces a topological ordering - // based on dependencies, which is used to check for call cycles. - entry.dfs_status (Task_Entry::FINISHED); - entry.finished (++time); - - return SUCCEEDED; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::identify_threads (void) -{ - u_int i, j; - - // walk array of task entries, picking out thread delineators - for (i = 0; i < tasks_; i++) - { - // if entry has exposed threads or no callers, it may be a thread - if ((task_entries_ [i].rt_info ()->threads > 0) || - (task_entries_ [i].callers ().is_empty ())) - { - // if its period is valued, it's a thread delineator - if (task_entries_ [i].rt_info ()->period > 0) - { - task_entries_ [i].effective_period (task_entries_ [i].rt_info ()->period); - task_entries_ [i].is_thread_delineator (1); - - // create a Dispatch_Entry for each thread of the delimiting Task_Entry - u_int thread_count = (task_entries_ [i].rt_info ()->threads > 0) - ? task_entries_ [i].rt_info ()->threads : 1; - // Just use low 32 bits of effective_period. This will - // have to change when CosTimeBase.idl is finalized. - const TimeBase::ulonglong zero = {0, 0}; - for (j = 0; j < thread_count; j++) - { - Dispatch_Entry *dispatch_ptr; - const TimeBase::ulonglong effective_period = - {task_entries_ [i].effective_period (), 0}; - ACE_NEW_RETURN(dispatch_ptr, - Dispatch_Entry (zero, - effective_period, - task_entries_ [i].rt_info ()->preemption_priority, - task_entries_ [i]), - ST_VIRTUAL_MEMORY_EXHAUSTED); - - if ((task_entries_ [i].dispatches ().insert (Dispatch_Entry_Link (*dispatch_ptr)) < 0) || - (dispatch_entries_->insert (dispatch_ptr) < 0) || - (thread_delineators_->insert (dispatch_ptr) < 0)) - { - return ST_VIRTUAL_MEMORY_EXHAUSTED; - } - - // increase the count of thread dispatches - ++ threads_; - } - } - else - { - // node that no one calls and has neither rate nor threads is suspect - ACE_ERROR_RETURN ( - (LM_ERROR, - "An operation identified by \"%s\" does not specify a period or\n" - "visible threads, and is not called by any other operation. " - "Are there backwards dependencies?\n", - (const char*) task_entries_ [i].rt_info ()->entry_point), - ST_BAD_DEPENDENCIES_ON_TASK); - } - } - } - - return SUCCEEDED; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::check_dependency_cycles (void) -{ - status_t return_status = SUCCEEDED; - - // sort the pointers to entries in order of descending finish time - ::qsort ((void *) ordered_task_entries_, - tasks (), - sizeof (Task_Entry *), - compare_entry_finish_times); - - // set all the dfs_status indicators to NOT_VISITED - u_int i; - for (i = 0; i < tasks (); ++i) - { - ordered_task_entries_ [i]->dfs_status (Task_Entry::NOT_VISITED); - } - - // recurse on each entry, saving most recent status if it is not SUCCEEDED - for (i = 0; i < tasks (); ++i) - { - status_t status = - check_dependency_cycles_recurse (*ordered_task_entries_ [i]); - - if (status != SUCCEEDED) - { - return_status = status; - } - } - - return return_status; -} - // uses strongly connected components algorithm: consider entries - // in order of finishing time from dependency DAG traversal, - // but traverse transpose graph: any entry that has a dependant - // that was not previously visited in this traversal is part - // of a dependency cycle - - -ACE_DynScheduler::status_t -ACE_DynScheduler::check_dependency_cycles_recurse (Task_Entry &entry) -{ - status_t return_status = SUCCEEDED; - - // halt DFS recursion on callers graph if entry has already been visited - if (entry.dfs_status () != Task_Entry::NOT_VISITED) - { - return return_status; - } - - // mark the entry as visited - entry.dfs_status (Task_Entry::VISITED); - - // check all the calling operations: if there is one that has not already been - // visited, mark the return status indicating there is a cycle, print - // an error message to that effect, and recurse on that dependant - Task_Entry_Link **calling_entry_link; - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> i (entry.callers ()); - while (i.next (calling_entry_link) != 0) - { - i.advance (); - if ((*calling_entry_link)->caller ().dfs_status () == Task_Entry::NOT_VISITED) - { - // indicate the two tasks are in (the same) dependency cycle - ACE_ERROR ((LM_ERROR, - "Tasks \"%s\" and \"%s\" are part of a call cycle.\n", - (*calling_entry_link)->caller ().rt_info ()->entry_point.in (), - entry.rt_info ()->entry_point.in ())); - - // set return status, ignore status returned by recursive call: - // we already know there are cycles in the dependencies - return_status = ST_CYCLE_IN_DEPENDENCIES; - check_dependency_cycles_recurse ((*calling_entry_link)->caller ()); - } - } - - // mark the entry as finished - entry.dfs_status (Task_Entry::FINISHED); - - return return_status; -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::schedule_threads (void) -{ - // make sure there are as many thread delineator - // entries in the set as the counter indicates - if (threads_ != thread_delineators_->size ()) - { - return THREAD_COUNT_MISMATCH; - } - - // allocate an array of pointers to the thread delineators - ACE_NEW_RETURN (ordered_thread_dispatch_entries_, - Dispatch_Entry * [threads_], - ST_VIRTUAL_MEMORY_EXHAUSTED); - ACE_OS::memset (ordered_thread_dispatch_entries_, 0, - sizeof (Dispatch_Entry *) * threads_); - - - // copy pointers to the thread delineators from the set to the array - ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*thread_delineators_); - for (u_int i = 0; i < threads_; ++i, iter.advance ()) - { - Dispatch_Entry** dispatch_entry; - - if (! iter.next (dispatch_entry)) - { - return ST_UNKNOWN_TASK; - } - - ordered_thread_dispatch_entries_ [i] = *dispatch_entry; - } - - // sort the thread dispatch entries into priority order - status_t status = sort_dispatches (ordered_thread_dispatch_entries_, threads_); - - if (status == SUCCEEDED) - { - // assign priorities to the thread dispatch entries - status == assign_priorities (ordered_thread_dispatch_entries_, threads_); - } - - return status; -} - // thread scheduling method: sets up array of pointers to task - // entries that are threads, calls internal thread scheduling method - -ACE_DynScheduler::status_t -ACE_DynScheduler::schedule_dispatches (void) -{ - dispatch_entry_count_ = dispatch_entries_->size (); - - ACE_NEW_RETURN (ordered_dispatch_entries_, - Dispatch_Entry * [dispatch_entry_count_], - ST_VIRTUAL_MEMORY_EXHAUSTED); - ACE_OS::memset (ordered_dispatch_entries_, 0, - sizeof (Dispatch_Entry *) * dispatch_entry_count_); - - - - ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*dispatch_entries_); - for (u_int i = 0; i < dispatch_entry_count_; ++i, iter.advance ()) - { - Dispatch_Entry** dispatch_entry; - - if (! iter.next (dispatch_entry)) - { - return ST_UNKNOWN_TASK; - } - - ordered_dispatch_entries_ [i] = *dispatch_entry; - } - - // sort the entries in order of priority and subpriority - sort_dispatches (ordered_dispatch_entries_, dispatch_entry_count_); - - // assign dynamic and static subpriorities to the thread dispatch entries - return assign_subpriorities (ordered_dispatch_entries_, dispatch_entry_count_); -} - // dispatch scheduling method: sets up an array of dispatch entries, - // calls internal dispatch scheduling method. - -ACE_DynScheduler::status_t -ACE_DynScheduler::create_timeline () -{ - // queue of previously scheduled entries that need to be rescheduled - ACE_Unbounded_Queue <Dispatch_Entry *> reschedule_queue; - - status_t status = SUCCEEDED; - - ACE_NEW_RETURN(timeline_, ACE_Ordered_MultiSet <TimeLine_Entry_Link>, - ST_VIRTUAL_MEMORY_EXHAUSTED); - - ACE_NEW_RETURN(expanded_dispatches_, ACE_Unbounded_Set <Dispatch_Entry *>, - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // start with the id of the first entry in the array - min_dispatch_id_ = ordered_dispatch_entries_[0]->dispatch_id (); - max_dispatch_id_ = ordered_dispatch_entries_[0]->dispatch_id (); - - for (u_long i = 0; i < dispatch_entry_count_; ++i) - { - // update the minimal and maximal id values for the schedule - if (ordered_dispatch_entries_[i]->dispatch_id () < min_dispatch_id_) - { - min_dispatch_id_ = ordered_dispatch_entries_[i]->dispatch_id (); - } - if (ordered_dispatch_entries_[i]->dispatch_id () > max_dispatch_id_) - { - max_dispatch_id_ = ordered_dispatch_entries_[i]->dispatch_id (); - } - - // only put OPERATION dispatches into the timeline. - if (ordered_dispatch_entries_[i]->task_entry().info_type () != - RtecScheduler::OPERATION) - { - continue; - } - - // schedule the current dispatch entry into the timeline - status = schedule_timeline_entry (*(ordered_dispatch_entries_[i]), - reschedule_queue); - if (status != SUCCEEDED) - { - break; - } - - // iterate through the set of dispatch entries that need to be rescheduled - Dispatch_Entry *rescheduled_entry; - while (reschedule_queue.is_empty () == 0) - { - - if (reschedule_queue.dequeue_head (rescheduled_entry) < 0) - { - status = ST_UNKNOWN_TASK; - break; - } - - status = schedule_timeline_entry (*rescheduled_entry, reschedule_queue); - if (status != SUCCEEDED) - { - break; - } - } - if (status != SUCCEEDED) - { - break; - } - - - // schedule additional dispatcheds of the entry - // over the total frame size into the timeline - u_long current_frame_offset = 0; - u_long task_period = - ordered_dispatch_entries_[i]->task_entry ().effective_period (); - for (current_frame_offset = task_period; - current_frame_offset < frame_size_; - current_frame_offset += task_period) - { - Dispatch_Entry *new_dispatch_entry; - - // create a new dispatch entry at the current sub-frame offset - // Just use low 32 bits of arrival and deadline. This will - // have to change when CosTimeBase.idl is finalized. - const TimeBase::ulonglong arrival = - {ordered_dispatch_entries_[i]->arrival ().low + current_frame_offset, - 0}; - const TimeBase::ulonglong deadline= - {ordered_dispatch_entries_[i]->deadline ().low + current_frame_offset, - 0}; - - ACE_NEW_RETURN ( - new_dispatch_entry, - Dispatch_Entry (arrival, - deadline, - ordered_dispatch_entries_[i]->priority (), - ordered_dispatch_entries_[i]->task_entry (), - ordered_dispatch_entries_[i]), - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // add the new dispatch entry to the set of expanded dispatches - expanded_dispatches_->insert (new_dispatch_entry); - - // schedule the new dispatch entry into the timeline - status = schedule_timeline_entry (*new_dispatch_entry, reschedule_queue); - if (status != SUCCEEDED) - { - break; - } - - while (reschedule_queue.is_empty () == 0) - { - - if (reschedule_queue.dequeue_head (rescheduled_entry) < 0) - { - status = ST_UNKNOWN_TASK; - break; - } - status = schedule_timeline_entry (*rescheduled_entry, reschedule_queue); - if (status != SUCCEEDED) - { - break; - } - } - if (status != SUCCEEDED) - { - break; - } - } - - if (status != SUCCEEDED) - { - break; - } - } - - return status; -} - // Create a timeline. - - - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_dispatch_priorities (const char *filename) -{ - status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; - - // open the file - FILE *file = ACE_OS::fopen (filename, "w"); - if (file) - { - status = output_dispatch_priorities (file); - fclose (file); - } - - return status; -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_dispatch_priorities (FILE *file) -{ - - u_long dispatch_count = 0; - u_long i = 0; - for (i = 0; i < dispatch_entry_count_; ++i) - { - dispatch_count += frame_size_ / ordered_dispatch_entries_[i]->task_entry ().effective_period (); - } - - if (ACE_OS::fprintf ( - file, "\n\nSCHEDULING RESULTS:\n\n" - "Number of dispatches: %3u\n" - "Number of threads: %3u\n" - "Number of tasks: %3u\n" - "Scheduler Status: [%d] %s\n" - "Total Frame Size: %lu nsec (%lf Hz)\n" - "Critical Set Frame Size: %lu nsec (%lf Hz)\n" - "Utilization: %lf\n" - "Critical Set Utilization: %lf\n" - "Minimum Priority Queue: %3ld\n" - "Minimum Guaranteed Priority Queue: %3ld\n" - "Minimum Critical Priority: %3ld\n\n\n" - - "DISPATCH PRIORITIES:\n\n" - " (critical \n" - " instant) \n" - " dispatch dynamic static \n" - "operation ID priority subpriority subpriority\n" - "--------- -------- -------- ----------- -----------\n", - dispatch_count, threads_, tasks_, status_, - status_message(status_), frame_size_, (double) (10000000.0 / ((double) frame_size_)), - critical_set_frame_size_, (double) (10000000.0 / ((double) critical_set_frame_size_)), - utilization_, critical_set_utilization_, minimum_priority_queue_, - minimum_guaranteed_priority_queue_, minimum_critical_priority ()) < 0) - - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - - for (i = 0; i < dispatch_entry_count_; ++i) - { - if (ACE_OS::fprintf (file, "%-11s %8lu %8lu %11lu %11lu\n", - ordered_dispatch_entries_[i]->task_entry ().rt_info ()->entry_point.in (), - ordered_dispatch_entries_[i]->dispatch_id (), - ordered_dispatch_entries_[i]->priority (), - ordered_dispatch_entries_[i]->dynamic_subpriority (), - ordered_dispatch_entries_[i]->static_subpriority ()) < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - - return SUCCEEDED; -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_dispatch_timeline (const char *filename) -{ - status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; - - // open the file - FILE *file = ACE_OS::fopen (filename, "w"); - if (file) - { - status = output_dispatch_timeline (file); - fclose (file); - } - - return status; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_dispatch_timeline (FILE *file) -{ - if (ACE_OS::fprintf ( - file, "\n\nDISPATCH TIMELINE:\n\n" - " dispatch arrival deadline start stop execution latency laxity\n" - "operation ID (nsec) (nsec) (nsec) (nsec) time (nsec) (nsec) (nsec)\n" - "--------- ----------- ------- -------- ----- ------ ----------- ------- ------\n") < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - - // iterate through timeline, picking out entries whose prev_ pointer - // is null (i.e. those representing the start of a dispatch), find end - // of dispatch, output the operation, dispatch, priority, and time info - ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); - for (iter.first (); iter.done () == 0; iter.advance ()) - { - TimeLine_Entry_Link *link; - if ((iter.next (link) == 0) || (! link)) - { - return ST_BAD_INTERNAL_POINTER; - } - - // for each timeline entry that starts a dispatch - if (link->entry ().prev () == 0) - { - // find the last time slice for the dispatch - TimeLine_Entry *last_entry = &(link->entry ()); - while (last_entry->next ()) - { - last_entry = last_entry->next (); - } - - // Just use low 32 bits of worst_case_execution_time. This will - // have to change when CosTimeBase.idl is finalized. - const ACE_UINT32 tmp = - last_entry->stop () - link->entry ().arrival () - - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - worst_case_execution_time.low; - if (link->entry ().dispatch_entry ().original_dispatch ()) - { - if (ACE_OS::fprintf ( - file, "%-11s [%4lu] %4lu %7lu %8lu %8lu %10lu %11lu %10ld %10ld\n", - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - entry_point.in (), - link->entry ().dispatch_entry ().original_dispatch ()->dispatch_id (), - link->entry ().dispatch_entry ().dispatch_id (), - link->entry ().arrival (), - link->entry ().deadline (), - link->entry ().start (), last_entry->stop (), - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - worst_case_execution_time, - tmp, - link->entry ().deadline () - last_entry->stop ()) < 0) - - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - else - { - if (ACE_OS::fprintf ( - file, "%-11s %11lu %7lu %8lu %8lu %10lu %11lu %10ld %10ld\n", - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - entry_point.in (), - link->entry ().dispatch_entry ().dispatch_id (), - link->entry ().arrival (), - link->entry ().deadline (), - link->entry ().start (), last_entry->stop (), - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - worst_case_execution_time, - tmp, - link->entry ().deadline () - last_entry->stop ()) < 0) - - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - } - } - - return SUCCEEDED; -} - // this prints the entire set of timeline outputs to the specified file - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_preemption_timeline (const char *filename) -{ - status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; - - // open the file - FILE *file = ACE_OS::fopen (filename, "w"); - if (file) - { - status = output_preemption_timeline (file); - fclose (file); - } - - return status; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_preemption_timeline (FILE *file) -{ - if (ACE_OS::fprintf ( - file, "\n\nPREEMPTION TIMELINE:\n\n" - " dispatch start stop \n" - "operation ID (nsec) (nsec)\n" - "--------- ----------- ------ ------\n") < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - - ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); - - TimeLine_Entry_Link *link; - for (iter.first (); iter.done () == 0; iter.advance ()) - { - if ((iter.next (link) == 0) || (! link)) - { - return ST_BAD_INTERNAL_POINTER; - } - - if (link->entry ().dispatch_entry ().original_dispatch ()) - { - if (ACE_OS::fprintf ( - file, "%-9s [%4lu] %4lu %8lu %8lu\n", - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - entry_point.in (), - link->entry ().dispatch_entry ().original_dispatch ()->dispatch_id (), - link->entry ().dispatch_entry ().dispatch_id (), - link->entry ().start (), - link->entry ().stop ()) < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - else - { - if (ACE_OS::fprintf ( - file, "%-9s %11lu %8lu %8lu\n", - link->entry ().dispatch_entry ().task_entry ().rt_info ()-> - entry_point.in (), - link->entry ().dispatch_entry ().dispatch_id (), - link->entry ().start (), - link->entry ().stop ()) < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - } - - return SUCCEEDED; -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_viewer_timeline (const char *filename) -{ - status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; - - // open the file - FILE *file = ACE_OS::fopen (filename, "w"); - if (file) - { - status = output_dispatch_timeline (file); - fclose (file); - } - - return status; -} - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_viewer_timeline (FILE *file) -{ - if (ACE_OS::fprintf ( - file, "\n\nVIEWER TIMELINE:\n\n" - " arrival deadline completion execution \n" - "operation utilization overhead (nsec) (nsec) time (nsec) time (nsec)\n" - "--------- ----------- -------- ------- -------- ----------- -----------\n") < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - - // iterate through timeline, picking out dispatches in chronological - // order of operation completion time - int entries_remain = 1; - u_long accumulated_execution = 0; - u_long current_accumulated_execution = 0; - u_long last_completion = 0; - u_long current_completion = 0; - TimeLine_Entry *current_entry = 0; - TimeLine_Entry *current_last_entry = 0; - - while (entries_remain) - { - last_completion = current_completion; - - accumulated_execution = 0; - current_accumulated_execution = 0; - current_completion = 0; - current_entry = 0; - current_last_entry = 0; - - ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); - for (iter.first (); iter.done () == 0; iter.advance ()) - { - TimeLine_Entry_Link *link; - if ((iter.next (link) == 0) || (! link)) - { - return ST_BAD_INTERNAL_POINTER; - } - - accumulated_execution += link->entry ().stop () - - link->entry ().start (); - - // for each timeline entry that starts a dispatch - if (link->entry ().prev () == 0) - { - // find the last time slice for the dispatch - TimeLine_Entry *last_entry = &(link->entry ()); - while (last_entry->next ()) - { - last_entry = last_entry->next (); - } - - if ((last_entry->stop () > last_completion) && - ((last_entry->stop () < current_completion) || - (current_completion == 0))) - { - current_completion = last_entry->stop (); - current_entry = &(link->entry ()); - current_last_entry = last_entry; - } - } - - // save the accumulated execution if we're at - // the last entry for the current dispatch - if (current_last_entry == &(link->entry ())) - { - current_accumulated_execution = accumulated_execution; - } - } - - // if we found another entry, print it (otherwise we're done) - if (current_entry) - { - if (ACE_OS::fprintf ( - file, "%-11s %9lf %9lf %8lu %8lu %11lu %11lu\n", - current_entry->dispatch_entry ().task_entry ().rt_info ()-> - entry_point.in (), - (double) (((double) current_accumulated_execution) / - ((double) current_completion)), - 0.0, - current_entry->arrival (), - current_entry->deadline (), - current_last_entry->stop (), - current_entry->dispatch_entry ().task_entry ().rt_info ()-> - worst_case_execution_time) < 0) - { - return UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - else - { - entries_remain = 0; - } - } - - return SUCCEEDED; -} - - -ACE_DynScheduler::status_t -ACE_DynScheduler::output_timeline (const char *filename, const char *heading) -{ - status_t status = SUCCEEDED; - FILE *file = 0; - - // bail out if we're not up to date or there is no timeline - if ((! up_to_date_) || (! timeline_)) - { - status = NOT_SCHEDULED; - } - - if (status == SUCCEEDED) - { - // open the file - file = ACE_OS::fopen (filename, "w"); - if (! file) - { - status = UNABLE_TO_OPEN_SCHEDULE_FILE; - } - } - - if ((status == SUCCEEDED) && (heading)) - { - if (ACE_OS::fprintf (file, "%s\n\n", heading) < 0) - { - status = UNABLE_TO_WRITE_SCHEDULE_FILE; - } - } - - if (status == SUCCEEDED) - { - status = output_dispatch_priorities (file); - } - - if (status == SUCCEEDED) - { - status = output_dispatch_timeline (file); - } - - if (status == SUCCEEDED) - { - status = output_preemption_timeline (file); - } - - if (status == SUCCEEDED) - { - status = output_viewer_timeline (file); - } - - if (file) - { - fclose (file); - } - - return status; -} - // this prints the entire set of timeline outputs to the specified file - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Map_Entry<ACE_CString, RtecScheduler::RT_Info *>; -template class ACE_Map_Manager<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex>; -template class ACE_Map_Iterator_Base<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex>; -template class ACE_Map_Iterator<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex>; -template class ACE_Map_Reverse_Iterator<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex>; -template class ACE_DNode<Dispatch_Entry_Link>; -template class ACE_DNode<Dispatch_Proxy_Iterator *>; -template class ACE_DNode<TimeLine_Entry_Link>; -template class ACE_Node<RtecScheduler::RT_Info *>; -template class ACE_Node<Task_Entry_Link *>; -template class ACE_Ordered_MultiSet<Dispatch_Entry_Link>; -template class ACE_Ordered_MultiSet<Dispatch_Proxy_Iterator *>; -template class ACE_Ordered_MultiSet<TimeLine_Entry_Link>; -template class ACE_Ordered_MultiSet_Iterator<Dispatch_Entry_Link>; -template class ACE_Ordered_MultiSet_Iterator<Dispatch_Proxy_Iterator *>; -template class ACE_Ordered_MultiSet_Iterator<TimeLine_Entry_Link>; -template class ACE_Unbounded_Queue<Dispatch_Entry *>; -template class ACE_Unbounded_Queue_Iterator<Dispatch_Entry *>; -template class ACE_Unbounded_Set<RtecScheduler::RT_Info *>; -template class ACE_Unbounded_Set<Task_Entry_Link *>; -template class ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info *>; -template class ACE_Unbounded_Set_Iterator<Task_Entry_Link *>; -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Map_Entry<ACE_CString, RtecScheduler::RT_Info *> -#pragma instantiate ACE_Map_Manager<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex> -#pragma instantiate ACE_Map_Iterator_Base<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex> -#pragma instantiate ACE_Map_Iterator<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex> -#pragma instantiate ACE_Map_Reverse_Iterator<ACE_CString, RtecScheduler::RT_Info *, ACE_Thread_Mutex> -#pragma instantiate ACE_DNode<Dispatch_Entry_Link> -#pragma instantiate ACE_DNode<Dispatch_Proxy_Iterator *> -#pragma instantiate ACE_DNode<TimeLine_Entry_Link> -#pragma instantiate ACE_Node<RtecScheduler::RT_Info *> -#pragma instantiate ACE_Node<Task_Entry_Link *> -#pragma instantiate ACE_Ordered_MultiSet<Dispatch_Entry_Link> -#pragma instantiate ACE_Ordered_MultiSet<Dispatch_Proxy_Iterator *> -#pragma instantiate ACE_Ordered_MultiSet<TimeLine_Entry_Link> -#pragma instantiate ACE_Ordered_MultiSet_Iterator<Dispatch_Entry_Link> -#pragma instantiate ACE_Ordered_MultiSet_Iterator<Dispatch_Proxy_Iterator *> -#pragma instantiate ACE_Ordered_MultiSet_Iterator<TimeLine_Entry_Link> -#pragma instantiate ACE_Unbounded_Queue<Dispatch_Entry *> -#pragma instantiate ACE_Unbounded_Queue_Iterator<Dispatch_Entry *> -#pragma instantiate ACE_Unbounded_Set<RtecScheduler::RT_Info *> -#pragma instantiate ACE_Unbounded_Set<Task_Entry_Link *> -#pragma instantiate ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info *> -#pragma instantiate ACE_Unbounded_Set_Iterator<Task_Entry_Link *> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.h b/TAO/orbsvcs/orbsvcs/Sched/DynSched.h deleted file mode 100644 index 5c8d59b5cb1..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/DynSched.h +++ /dev/null @@ -1,483 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// DynSched.h -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#if ! defined (DYNSCHED_H) -#define DYNSCHED_H - -#include "ace/ACE.h" -#include "ace/Map_Manager.h" -#include "ace/Message_Block.h" -#include "ace/Synch.h" -#include "ace/SString.h" -#include "SchedEntry.h" - -class TAO_ORBSVCS_Export ACE_DynScheduler - // = TITLE - // dispatch scheduling interface. - // - // = DESCRIPTION - // This abstract base class provides the majority of the - // implementation of either an off-line scheduler, or the - // necessary on-line component of the Scheduler. -{ -public: - - ////////////////////////////// - // public type declarations // - ////////////////////////////// - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - typedef ACE_Map_Entry <ACE_CString, RT_Info *> Thread_Map_Entry; - typedef ACE_Map_Manager <ACE_CString, RT_Info *, ACE_Null_Mutex> - Thread_Map; - typedef ACE_Map_Iterator <ACE_CString, RT_Info *, ACE_Null_Mutex> - Thread_Map_Iterator; - - typedef const char *Object_Name; - // Objects are named by unique strings. - - enum status_t { - // The following are used both by the runtime Scheduler and during - // scheduling. - NOT_SCHEDULED = -1 // the schedule () method has not been called yet - , FAILED = -1 - , SUCCEEDED - , ST_UNKNOWN_TASK - , ST_TASK_ALREADY_REGISTERED - , ST_BAD_DEPENDENCIES_ON_TASK - , ST_BAD_INTERNAL_POINTER - , ST_VIRTUAL_MEMORY_EXHAUSTED - - // The following are only used by the runtime Scheduler. - , TASK_COUNT_MISMATCH // only used by schedule () - , THREAD_COUNT_MISMATCH // only used by schedule () - , INVALID_PRIORITY // only used by schedule (): mismatch of - // (off-line, maybe) Scheduler output to - // the runtime Scheduler component. - - // The following are only used during scheduling (in the case of - // off-line scheduling, they are only used prior to runtime). - , ST_UTILIZATION_BOUND_EXCEEDED - , ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS - , ST_CYCLE_IN_DEPENDENCIES - , ST_INVALID_PRIORITY_ORDERING - , UNABLE_TO_OPEN_SCHEDULE_FILE - , UNABLE_TO_WRITE_SCHEDULE_FILE - }; - - - - ///////////////////////////// - // public member functions // - ///////////////////////////// - - virtual ~ACE_DynScheduler (); - // public dtor - - // = Utility function for outputting the textual - // representation of a status_t value. - static const char * status_message (status_t status); - - // = Initialize the scheduler. - void init (const OS_Priority minimum_priority, - const OS_Priority maximum_priority, - const char *runtime_filename = 0, - const char *rt_info_filename = 0, - const char *timeline_filename = 0); - // The minimum and maximum priority are the OS-specific priorities that - // are used when creating the schedule (assigning priorities). The - // minimum_priority is the priority value of the lowest priority. - // It may be numerically higher than the maximum_priority, on OS's such - // as VxWorks that use lower values to indicate higher priorities. - // - // When Scheduler::schedule is called, the schedule is output to the - // file named by "runtime_filename" if it is non-zero. - // This file is compilable; it is linked into the runtime executable - // to provide priorities to the runtime scheduling component. - // If the "rt_info_filename" is non-zero, the RT_Info for - // every task is exported to it. It is not used at runtime. - // If the "timeline_filename" is non-zero, the timeline output - // file is created. It is not used at runtime. - // - // The runtime scheduling component ignores these filenames. It just - // uses the priorities that were linked in to the executable, after - // converting them to platform-specific values. - - void reset (); - // Prepare for another schedule computation: once a reasonable schedule - // has been generated, a new schedule will not be computed unless an - // RT_Info is added, or this method is invoked to clear the previous - // schedule (allows fault correcting alteration of RT_Infos outside the - // scheduler implementation, followed by generation of a new schedule). - - // = Registers a task. - status_t register_task (RT_Info *, handle_t &handle); - // If the Task registration succeeds, this function returns SUCCEEDED - // and sets "handle" to a unique identifier for the task. - // Otherwise, it returns either VIRTUAL_MEMORY_EXHAUSTED or - // TASK_ALREADY_REGISTERED sets the handle to 0. (A task may - // only be registered once.) - - status_t get_rt_info (Object_Name name, RT_Info* &rtinfo); - // Tries to find the RT_Info corresponding to <name> in the RT_Info - // database. Returns SUCCEEDED if <name> was found and <rtinfo> was - // set. Returns UNKNOWN_TASK if <name> was not found, but <rtinfo> - // was set to a newly allocated RT_Info. In this UNKNOWN_TASK case, - // the task must call RT_Info::set to fill in execution properties. - // In the SUCCEEDED and UNKNOWN_TASK cases, this->register_task - // (rtinfo, 0, handle) is called. Returns FAILED if an error - // occurs. - // - // One motivation for allocating RT_Info's from within the Scheduler - // is to allow RT_Infos to persist after the tasks that use them. - // For instance, we may want to call this->schedule right before the - // application exits a configuration run. If the tasks have been - // deleted (deleting their RT_Infos with them), this->schedule will - // fail. - - status_t lookup_rt_info (handle_t handle, RT_Info* &rtinfo); - // Obtains an RT_Info based on its "handle". - - status_t schedule (void); - // This sets up the data structures, invokes the internal scheduling method. - - status_t output_timeline (const char *filename, const char *heading); - // this prints the entire set of timeline outputs to the specified file - - - // = Access a thread priority. - virtual int priority (const handle_t handle, - OS_Priority &priority, - Sub_Priority &subpriority, - Preemption_Priority &preemption_prio); - // "priority" is the OS thread priority that was assigned to the Task that - // was assigned "handle". "subpriority" combines the dynamic and static - // subpriorities of the Task that was assigned handle. "preemption_prio" - // is a platform-independent priority queue number, ranging from a - // highest priority value of 0 to the lowest priority value, which is - // returned by "minimum_priority_queue ()". Returns 0 on success, - // or -1 if an invalid handle was supplied. - - // = Access the platform-independent priority value of the lowest-priority - // thread. - Preemption_Priority minimum_priority_queue () const; - - // = Access the number of tasks. - u_int tasks () const; - - // = Access the number of threads. - u_int threads () const; - - // = Access the current scheduler status. - status_t status () const; - - // = Access the current output (debugging) level. - u_int output_level () const; - // Default is 0; set to 1 to print out schedule, by task. Set - // to higher than one for debugging info. - - // = Set the scheduler output (debugging) level. - void output_level (const u_int level); - // the only supported levels are 0 (quiet), 1 (verbose) and 2 (debug) - - int add_dependency(RT_Info* rt_info, - Dependency_Info& d); - - static int number_of_dependencies(RT_Info* rt_info); - static int number_of_dependencies(RT_Info& rt_info); - - static void export(RT_Info*, FILE* file); - static void export(RT_Info&, FILE* file); - - // accessors for the minimal and maximal dispatch entry id in the schedule - u_long min_dispatch_id () const; - u_long max_dispatch_id () const; - -protected: - - //////////////////////////////// - // protected member functions // - //////////////////////////////// - - ACE_DynScheduler (); - - - status_t schedule_threads (void); - // thread scheduling method: sets up array of pointers to task - // entries that are threads, calls internal thread scheduling method - - status_t schedule_dispatches (void); - // dispatch scheduling method: sets up an array of dispatch entries, - // calls internal dispatch scheduling method. - - // = Set the minimum priority value. - void minimum_priority_queue (const Preemption_Priority minimum_priority_queue_number); - - // = Set the number of tasks. - void tasks (const u_int tasks); - - // = Set the number of threads. - void threads (const u_int threads); - - // = Set the current scheduler status. - void status (const status_t new_status); - - ///////////////////////////////////////////// - // protected pure virtual member functions // - ///////////////////////////////////////////// - - virtual Preemption_Priority minimum_critical_priority () = 0; - // = determine the minimum critical priority number - - virtual status_t sort_dispatches (Dispatch_Entry **, u_int) = 0; - // internal sorting method: this orders the dispatches by - // static priority and dynamic and static subpriority. - - virtual status_t assign_priorities (Dispatch_Entry **dispatches, - u_int count) = 0; - // = assign priorities to the sorted dispatches - - virtual status_t assign_subpriorities (Dispatch_Entry **dispatches, - u_int count) = 0; - // = assign dynamic and static sub-priorities to the sorted dispatches - - virtual status_t - schedule_timeline_entry (Dispatch_Entry &dispatch_entry, - ACE_Unbounded_Queue <Dispatch_Entry *> - &reschedule_queue) = 0; - // = schedule a dispatch entry into the timeline being created - - //////////////////////////// - // protected data members // - //////////////////////////// - - OS_Priority minimum_priority_; - // The minimum OS thread priority value that the application specified (in - // its call to init ()). - - OS_Priority maximum_priority_; - // The maximum OS thread priority value that the application specified (in - // its call to init ()). - - Task_Entry *task_entries_; - // Collection of known tasks. - - Task_Entry **ordered_task_entries_; - // An array of pointers to task entries which wrap RT_Infos. It is - // sorted by the DFS finishing time and then the resulting topological - // over the call graph is used both to check for call chain cycles and - // to correctly propagate scheduling information away from the threads. - - ACE_Unbounded_Set <Dispatch_Entry *> *thread_delineators_; - // identifies dispatch entries whose underlying - // Task Entries delineate threads - - Dispatch_Entry **ordered_thread_dispatch_entries_; - // An array of pointers to task entries which initiate call chains. - // It is sorted by the schedule_threads method defined in the derived class. - - ACE_Unbounded_Set <Dispatch_Entry *> *dispatch_entries_; - // the set of dispatch entries - - ACE_Unbounded_Set <Dispatch_Entry *> *expanded_dispatches_; - // expanded set of dispatch entries (all dispatch entries produced by - // expanding sub-frames to the total frame size during timeline creation) - - Dispatch_Entry **ordered_dispatch_entries_; - // An array of pointers to dispatch entries. It is - // sorted by the schedule_dispatches method. - - u_int dispatch_entry_count_; - // the number of dispatch entries in the schedule - - u_int threads_; - // the number of dispatch entries in the schedule - - ACE_Ordered_MultiSet <TimeLine_Entry_Link> *timeline_; - // Ordered MultiSet of timeline entries. - -private: - - /////////////////////////////// - // private type declarations // - /////////////////////////////// - - typedef ACE_CString EXT; - typedef RT_Info *INT; - -#if defined (ACE_HAS_THREADS) - typedef ACE_Thread_Mutex SYNCH; - typedef ACE_Recursive_Thread_Mutex LOCK; -#else - typedef ACE_Null_Mutex SYNCH; - typedef ACE_Null_Mutex LOCK; -#endif /* ACE_HAS_THREADS */ - - typedef ACE_Map_Manager<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection; - typedef ACE_Map_Iterator<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection_Iterator; - typedef ACE_Map_Entry<EXT, INT> Info_Collection_Entry; - - ////////////////////////////// - // private member functions // - ////////////////////////////// - - status_t create_timeline (); - // Create a timeline. - - status_t output_dispatch_timeline (const char *filename); - status_t output_dispatch_timeline (FILE *file); - // this prints a dispatch timeline to the specified file - - status_t output_preemption_timeline (const char *filename); - status_t output_preemption_timeline (FILE *file); - // this prints a preemption timeline to the specified file - - status_t output_viewer_timeline (const char *filename); - status_t output_viewer_timeline (FILE *file); - // this prints a scheduling viewer timeline to the specified file - - status_t output_dispatch_priorities (const char *filename); - status_t output_dispatch_priorities (FILE *file); - // this prints the scheduling parameters and assigned priorities to the specified file - - // = Set up the task entry data structures - status_t setup_task_entries (void); - - // = Relate the task entries according to the - // dependencies of the underlying RT_Infos - status_t relate_task_entries (void); - - // recursively traverse dependency graph, relating - // task entries and performing DFS start/end marking - status_t relate_task_entries_recurse (long &time, Task_Entry &entry); - - // identify thread delimiters - status_t identify_threads (void); - - // checks for cycles in the dependency graph - status_t check_dependency_cycles (void); - - // recursion used to check for cycles in the dependency graph - status_t check_dependency_cycles_recurse (Task_Entry &entry); - - // = Aggregate the scheduling parameters of the threads - status_t aggregate_thread_parameters (void); - - // = recursion over oneway dependencies used to aggregate thread parameters - status_t aggregate_oneways_recurse (Task_Entry &entry); - - // = recursion over twoway dependencies used to aggregate thread parameters - status_t aggregate_twoways_recurse (Task_Entry &entry); - - // update the scheduling parameters for the previous priority level - void update_priority_level_params (); - - status_t propagate_dispatches (); - // propagate the dispatch information from the - // threads throughout the call graph - - status_t calculate_utilization_params (); - // calculate utilization, frame size, etc. - - // the following functions are not implememented - ACE_UNIMPLEMENTED_FUNC(ACE_DynScheduler (const ACE_DynScheduler &)) - ACE_UNIMPLEMENTED_FUNC(ACE_DynScheduler &operator= (const ACE_DynScheduler &)) - - ////////////////////////// - // private data members // - ////////////////////////// - - LOCK lock_; - // This protects access to the scheduler during configuration runs. - - ACE_Unbounded_Set <RT_Info *> rt_info_entries_; - // Collection of known tasks. - - u_int handles_; - // The number of task handles dispensed so far. - - const char *runtime_filename_; - // Destination file of Scheduler output from the configuration run. - - const char *rt_info_filename_; - // Destination file of all rt_info data from the configuration run. - - const char *timeline_filename_; - // The destination of the timeline. - - Info_Collection info_collection_; - // A binding of name to rt_info. This is the mapping for every - // rt_info in the process. - - u_int tasks_; - - status_t status_; - - u_int output_level_; - - u_long frame_size_; /* 100 nanosec */ - // minimum frame size for all tasks - - u_long critical_set_frame_size_; /* 100 nanosec */ - // minimum frame size for guaranteed schedulable tasks - - double utilization_; - // total utilization for all tasks - - double critical_set_utilization_; - // minimum frame size for guaranteed schedulable tasks - - Preemption_Priority minimum_priority_queue_; - // The platform-independent priority value of the Event Channel's - // minimum priority dispatch queue. The value of the maximum priority - // dispatch queue is always 0. - - Preemption_Priority minimum_guaranteed_priority_queue_; - // The platform-independent priority value of the minimum priority dispatch - // queue whose operations are guaranteed to be schedulable. The value of - // the maximum priority dispatch queue is always 0, -1 indicates none can - // be guaranteed. - - u_int up_to_date_; - // indicates whether the a valid schedule has been generated since the last - // relevant change (addition, alteration or removal of an RT_Info, etc.) - - u_long min_dispatch_id_; - - u_long max_dispatch_id_; - -}; - -#if defined (__ACE_INLINE__) -#include "DynSched.i" -#endif /* __ACE_INLINE__ */ - -#endif /* DYNSCHED_H */ - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.i b/TAO/orbsvcs/orbsvcs/Sched/DynSched.i deleted file mode 100644 index 3eb2a3c0bda..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/DynSched.i +++ /dev/null @@ -1,111 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// DynSched.i -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - - -//////////////////////////// -// Class ACE_DynScheduler // -//////////////////////////// - -ACE_INLINE ACE_DynScheduler::Preemption_Priority -ACE_DynScheduler::minimum_priority_queue () const -{ - return minimum_priority_queue_; -} - // This is intended for use by the Event Channel, so it can determine the - // number of priority dispatch queues to create. - -// = Access the number of tasks. -ACE_INLINE u_int -ACE_DynScheduler::tasks () const -{ - return tasks_; -} - - // = Access the number of threads. -ACE_INLINE u_int -ACE_DynScheduler::threads () const -{ - return threads_; -} - - // = Access the current scheduler status. -ACE_INLINE ACE_DynScheduler::status_t -ACE_DynScheduler::status () const -{ - return status_; -} - - // = Access the current output (debugging) level. -ACE_INLINE u_int -ACE_DynScheduler::output_level () const { - return output_level_; -} - // Default is 0; set to 1 to print out schedule, by task. Set - // to higher than one for debugging info. - - // = Set the scheduler output (debugging) level. -ACE_INLINE void -ACE_DynScheduler::output_level (const u_int level) -{ - output_level_ = level; -} - // the only supported levels are 0 (quiet), 1 (verbose) and 2 - // (debug) - -ACE_INLINE void -ACE_DynScheduler::minimum_priority_queue (const Preemption_Priority minimum_priority_queue_number) -{ - minimum_priority_queue_ = minimum_priority_queue_number; -} - - // = Set the number of tasks. -ACE_INLINE void -ACE_DynScheduler::tasks (const u_int tasks) -{ - tasks_ = tasks; -} - - // = Set the number of threads. -// TBD - remove this - allowing the application to modify this is *not* good -ACE_INLINE void -ACE_DynScheduler::threads (const u_int threads) -{ - threads_ = threads; -} - - // = Set the current scheduler status. -ACE_INLINE void -ACE_DynScheduler::status (const status_t new_status) -{ - status_ = new_status; -} - -ACE_INLINE u_long -ACE_DynScheduler::min_dispatch_id () const -{ - return min_dispatch_id_; -} - -ACE_INLINE u_long -ACE_DynScheduler::max_dispatch_id () const -{ - return max_dispatch_id_; -} - - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp deleted file mode 100644 index 32adf6fc001..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp +++ /dev/null @@ -1,875 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// SchedEntry.cpp -// -// = CREATION DATE -// 7 February 1998 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#include "SchedEntry.h" - -#if ! defined (__ACE_INLINE__) -#include "SchedEntry.i" -#endif /* __ACE_INLINE__ */ - -////////////////////// -// Helper Functions // -////////////////////// - -// TBD - move this to the ACE class -// Euclid's greatest common divisor algorithm -u_long gcd (u_long x, u_long y) -{ - if (y == 0) - { - return x; - } - else - { - return gcd (y, x % y); - } -} - - -// TBD - move this to the ACE class -// calculate the minimum frame size that -u_long minimum_frame_size (u_long period1, u_long period2) -{ - // first, find the greatest common divisor of the two periods - u_long greatest_common_divisor = gcd (period1, period2); - - // explicitly consider cases to reduce risk of possible overflow errors - if (greatest_common_divisor == 1) - { - // periods are relative primes: just multiply them together - return period1 * period2; - } - else if (greatest_common_divisor == period1) - { - // the first period divides the second: return the second - return period2; - } - else if (greatest_common_divisor == period2) - { - // the second period divides the first: return the first - return period1; - } - else - { - // the current frame size and the entry's effective period - // have a non-trivial greatest common divisor: return the - // product of factors divided by those in their gcd. - return (period1 * period2) / greatest_common_divisor; - } -} - - -////////////////////// -// Class Task_Entry // -////////////////////// - -Task_Entry::Task_Entry () - : rt_info_ (0) - , effective_period_(0) - , dfs_status_ (NOT_VISITED) - , discovered_ (-1) - , finished_ (-1) - , is_thread_delineator_ (0) - , calls_ () - , callers_ () -{ -} - -Task_Entry::~Task_Entry () -{ - // zero out the task entry ACT in the corresponding rt_info - rt_info_->volatile_token = 0; - - // iterate through the "calls" set of Task Entry Links and free each one - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter(calls_); - Task_Entry_Link **link = 0; - for (iter.first (); ! iter.done (); iter.advance (), link = 0) - { - if ((iter.next (link) != 0) && (link) && (*link)) - { - // remove the link object pointer from the calling - // entry's "callers" set and destroy the link object - (*link)->called ().callers_.remove (*link); - delete (*link); - } - } -} - -// merge dispatches according to info type and type of call, -// update relevant scheduling characteristics for this entry -int -Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) -{ - int result = 0; - switch (info_type ()) - { - case RtecScheduler::DISJUNCTION: - - // prohibit two-way dispatches of a disjunction group, - // and disjunctively merge its one-way dispatches. - // NOTE: one interpretation of disjunction for two-way calls - // is that the caller calls one OR the other, but this - // is problematic: how do we map the dispatches for this ? - result = prohibit_dispatches (RtecScheduler::TWO_WAY_CALL); - if (result == 0) - { - result = disjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); - } - - break; - - case RtecScheduler::CONJUNCTION: - - // prohibit two-way dispatches of a conjunction group, - // and conjunctively merge its one-way dispatches. - // NOTE: one interpretation of disjunction for two-way calls - // is that the caller calls BOTH, so that there is a - // disjunctive merge of each two-way, as for the OPERATION - // (prohibit for now, as the additional complexity of allowing - // conjunctions of two-ways, but not disjunctions does not - // buy us anything, anyway). - result = prohibit_dispatches (RtecScheduler::TWO_WAY_CALL); - if (result == 0) - { - result = conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); - } - - break; - - case RtecScheduler::OPERATION: - - // disjunctively merge the operation's two-way dispatches, - // and conjunctively merge its one-way dispatches. - result = disjunctive_merge (RtecScheduler::TWO_WAY_CALL, dispatch_entries); - if (result == 0) - { - result = conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); - } - - break; - - - default: - - // there should not be any other kind of RT_Info, or if - // there is, the above switch logic is in need of repair. - result = -1; - break; - } - - return result; -} - - - -// prohibit calls of the given type: currently used to enforce -// the notion that two-way calls to disjunctive or conjunctive -// RT_Infos do not have any defined meaning, and thus should be -// considered dependency specification errors: if these constraints -// are removed in the future, this method should be removed as well -// Returns 0 if all is well, or -1 if an error has occurred. -int -Task_Entry::prohibit_dispatches (Dependency_Type dt) -{ - // iterate over the set of dependencies, ensuring - // none of them has the given dependency type - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); - while (! iter.done ()) - { - Task_Entry_Link **link; - if ((iter.next (link) == 0) || (! link) || (! (*link)) || - ((*link)->dependency_type () == dt)) - { - return -1; - } - - iter.advance (); - } - - return 0; -} - - -// perform disjunctive merge of arrival times of oneway calls: -// all arrival times of all dependencies are duplicated by the -// multiplier and repetition over the new frame size and merged -int -Task_Entry::disjunctive_merge ( - Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) -{ - // iterate over the set of dependencies, ensuring - // none of them has the given dependency type - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); - while (! iter.done ()) - { - Task_Entry_Link **link; - if ((iter.next (link) == 0) || (! link) || (! (*link))) - { - return -1; - } - - // the link matches the dependency type given - if ((*link)->dependency_type () == dt) - { - // merge the caller's dispatches into the current set - if (merge_frames (dispatch_entries, *this, dispatches_, - (*link)->caller ().dispatches_, effective_period_, - (*link)->caller ().effective_period_, - (*link)->number_of_calls ()) < 0) - { - return -1; - } - } - - iter.advance (); - } - - return 0; -} - -// perform conjunctive merge of arrival times of calls: -// all arrival times of all dependencies are duplicated by the -// multiplier and repetition over the new frame size and then -// iteratively merged by choosing the maximal arrival time at -// the current position in each queue (iteration is in lockstep -// over all queues, and ends when any queue ends). -int -Task_Entry::conjunctive_merge ( - Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) -{ - int result = 0; - - // iterate over the dependencies, and determine the total frame size - u_long frame_size = 1; - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> dep_iter (callers_); - for (dep_iter.first (); dep_iter.done () == 0; dep_iter.advance ()) - { - Task_Entry_Link **link; - if ((dep_iter.next (link) == 0) || (! link) || (! (*link))) - { - return -1; - } - - // the link matches the dependency type given - if ((*link)->dependency_type () == dt) - { - frame_size = minimum_frame_size (frame_size, (*link)->caller ().effective_period_); - } - } - - // reframe dispatches in the set to the new frame size - // (expands the set's effective period to be the new enclosing frame) - if (reframe (dispatch_entries, *this, dispatches_, - effective_period_, frame_size) < 0) - { - return -1; - } - - // A set and iterator for virtual dispatch sets - // over which the conjunction will iterate - ACE_Ordered_MultiSet <Dispatch_Proxy_Iterator *> conj_set; - ACE_Ordered_MultiSet_Iterator <Dispatch_Proxy_Iterator *> conj_set_iter (conj_set); - - // iterate over the dependencies, and for each of the given call type, - // create a Dispatch_Proxy_Iterator for the caller's dispatch set, using - // the caller's period, the total frame size, and the number of calls: - // if any of the sets is empty, just return 0; - for (dep_iter.first (); dep_iter.done () == 0; dep_iter.advance ()) - { - Task_Entry_Link **link; - if ((dep_iter.next (link) == 0) || (! link) || (! (*link))) - { - return -1; - } - - // the link matches the dependency type given - if ((*link)->dependency_type () == dt) - { - Dispatch_Proxy_Iterator *proxy_ptr; - ACE_NEW_RETURN (proxy_ptr, - Dispatch_Proxy_Iterator ( - (*link)->caller ().dispatches_, - (*link)->caller ().effective_period_, - frame_size, (*link)->number_of_calls ()), - -1); - - // if there are no entries in the virtual set, we're done - if (proxy_ptr->done ()) - { - return 0; - } - if (conj_set.insert (proxy_ptr, conj_set_iter) < 0) - { - return -1; - } - } - } - - // loop, adding conjunctive dispatches, until one of the conjunctive - // dispatch sources runs out of entries over the total frame - conj_set_iter.first (); - int more_dispatches = (conj_set_iter.done ()) ? 0 : 1; - while (more_dispatches) - { - u_long arrival = 0; - u_long deadline = 0; - long priority = 0; - - for (conj_set_iter.first (); - conj_set_iter.done () == 0; - conj_set_iter.advance ()) - { - // initialize to earliest arrival and deadline, and highest priority - arrival = 0; - deadline = 0; - priority = 0; - - // Policy: conjunctively dispatched operations get the latest deadline of any - // of the dispatches in the conjunction at the time they were dispatched - // - when and if it is useful to change any of the merge policies, this - // should be one of the decisions factored out into the conjunctive merge - // strategy class. - - // Policy: conjunctively dispatched operations get the lowest priority of any - // of the dispatches in the conjunction at the time they were dispatched - // - when and if it is useful to change any of the merge policies, this - // should be one of the decisions factored out into the conjunctive merge - // strategy class. - - // obtain a pointer to the current dispatch proxy iterator - Dispatch_Proxy_Iterator **proxy_iter; - if ((conj_set_iter.next (proxy_iter) == 0) || (! proxy_iter) || (! (*proxy_iter))) - { - return -1; - } - - // use latest arrival, latest deadline, lowest priority (0 is highest) - arrival = (arrival < (*proxy_iter)->arrival ()) - ? arrival : (*proxy_iter)->arrival (); - deadline = (deadline < (*proxy_iter)->deadline ()) - ? deadline : (*proxy_iter)->deadline (); - priority = (priority < (*proxy_iter)->priority ()) - ? priority : (*proxy_iter)->priority (); - - (*proxy_iter)->advance (); - if ((*proxy_iter)->done ()) - { - more_dispatches = 0; - } - } - - Dispatch_Entry *entry_ptr; - // The following two statements should be removed when - // CosTimeBase.idl is finalized. - const TimeBase::ulonglong arrival_tb = {arrival, 0}; - const TimeBase::ulonglong deadline_tb = {deadline, 0}; - ACE_NEW_RETURN (entry_ptr, - Dispatch_Entry (arrival_tb, deadline_tb, priority, *this), - -1); - - // if even one new dispatch was inserted, result is "something happened". - result = 1; - - // add the new dispatch entry to the set of all dispatches, and - // a link to it to the dispatch links for this task entry - if (dispatch_entries.insert (entry_ptr) < 0) - { - return -1; - } - - // use iterator for efficient insertion into the dispatch set - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> insert_iter (dispatches_); - if (dispatches_.insert (Dispatch_Entry_Link (*entry_ptr), insert_iter) < 0) - { - return -1; - } - - // TBD - Clients are not assigned priority, but rather obtain it from - // their call dependencies. We could complain here if there is a - // priority specified that doesn't match (or is lower QoS?) - } - - return result; -} - -// this static method is used to reframe an existing dispatch set -// to the given new period multiplier, creating new instances of -// each existing dispatch (with adjusted arrival and deadline) -// in each successive sub-frame. Returns 1 if the set was reframed -// to a new period, 0 if the set was not changed (the new period -// was not a multiple of the old one), or -1 if an error occurred. -int -Task_Entry::reframe ( - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long &set_period, u_long new_period) -{ - // make sure the new period is greater than the current - // set period, and that they are harmonically related - if (new_period <= set_period) - { - // return an error if they're not harmonically related, - // do nothing if set's frame is a multiple of the new frame - return (set_period % new_period) ? -1 : 0; - } - else if (new_period % set_period) - { - return -1; - } - - // make a shallow copy of the set in a new ordered - // multiset using the Dispatch_Entry_Link smart pointers - ACE_Ordered_MultiSet <Dispatch_Entry_Link> new_set; - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> new_iter (new_set); - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> set_iter (set); - - for (set_iter.first (); set_iter.done () == 0; set_iter.advance ()) - { - Dispatch_Entry_Link *link; - if (set_iter.next (link) == 0) - { - return -1; - } - - if (new_set.insert (*link, new_iter) < 0) - { - return -1; - } - } - - // do a deep copy merge back into the set using the new period and starting - // after the 0th sub-frame: this puts all dispatches after the 0th - // sub-frame of the new period into the set, and leaves existing dispatches - // in the 0th sub-frame of the new period in the set as well. - int result = merge_frames (dispatch_entries, owner, set, - new_set, new_period, set_period, 1, 1); - - // update the set's period to be the new frame - set_period = new_period; - - return result; -} - - -// this static method is used to merge an existing dispatch set, -// multiplied by the given multipliers for the period and number of -// instances in each period of each existing dispatch, into the -// given "into" set, without affecting the "from set". -int -Task_Entry::merge_frames ( - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &dest, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &src, - u_long &dest_period, - u_long src_period, - u_long number_of_calls, - u_long starting_dest_sub_frame) -{ - int status = 0; - - // reframe dispatches in the destination set to the new frame size - // (expands the destination set's period to be the new enclosing frame) - if (reframe (dispatch_entries, owner, dest, dest_period, - minimum_frame_size (dest_period, src_period)) < 0) - { - return -1; - } - - // use iterator for efficient insertion into the destination set - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> dest_iter (dest); - - // do virutal iteration over the source set in the new frame, - // adding adjusted dispatch entries to the destination - Dispatch_Proxy_Iterator src_iter (src, src_period, dest_period, - number_of_calls, - starting_dest_sub_frame); - - for (src_iter.first (starting_dest_sub_frame); src_iter.done () == 0; src_iter.advance ()) - { - - // Policy: disjunctively dispatched operations get their deadline and - // priority from the original dispatch - when and if it is useful - // to change any of the merge policies, this should be one of the - // decisions factored out into the disjunctive merge strategy - // class. - - Dispatch_Entry *entry_ptr; - // The following two statements should be removed when - // CosTimeBase.idl is finalized. - const TimeBase::ulonglong arrival_tb = {src_iter.arrival (), 0}; - const TimeBase::ulonglong deadline_tb = {src_iter.deadline (), 0}; - ACE_NEW_RETURN (entry_ptr, - Dispatch_Entry (arrival_tb, - deadline_tb, - src_iter.priority (), owner), - -1); - - // if even one new dispatch was inserted, status is "something happened". - status = 1; - - // add the new dispatch entry to the set of all dispatches, and - // a link to it to the dispatch links for this task entry - if (dispatch_entries.insert (entry_ptr) < 0) - { - return -1; - } - - if (dest.insert (Dispatch_Entry_Link (*entry_ptr), dest_iter) < 0) - { - return -1; - } - - // TBD - Clients are not assigned priority, but rather obtain it from - // their call dependencies. We could complain here if there is a - // priority specified that doesn't match (or is lower QoS?) - } - - return status; -} - - -/////////////////////////// -// Class Task_Entry_Link // -/////////////////////////// - - -Task_Entry_Link::Task_Entry_Link ( - Task_Entry &caller, - Task_Entry &called, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type dependency_type) - : number_of_calls_ (number_of_calls) - , caller_ (caller) - , called_ (called) - , dependency_type_ (dependency_type) -{ -} - - -////////////////////////// -// Class Dispatch_Entry // -////////////////////////// - -Dispatch_Entry::Dispatch_Id Dispatch_Entry::next_id_ = 0; - -Dispatch_Entry::Dispatch_Entry ( - Time arrival, - Time deadline, - Preemption_Priority priority, - Task_Entry &task_entry, - Dispatch_Entry *original_dispatch) - - : priority_ (priority) - , OS_priority_ (0) - , dynamic_subpriority_ (0) - , static_subpriority_ (0) - , arrival_ (arrival) - , deadline_ (deadline) - , task_entry_ (task_entry) - , original_dispatch_ (original_dispatch) -{ - // obtain, increment the next id - dispatch_id_ = next_id_++; -} - -Dispatch_Entry::Dispatch_Entry (const Dispatch_Entry &d) - : priority_ (d.priority_) - , OS_priority_ (d.OS_priority_) - , dynamic_subpriority_ (d.dynamic_subpriority_) - , static_subpriority_ (d.static_subpriority_) - , arrival_ (d.arrival_) - , deadline_ (d.deadline_) - , task_entry_ (d.task_entry_) - , original_dispatch_ (d.original_dispatch_) -{ - // obtain, increment the next id - dispatch_id_ = next_id_++; -} - - -int -Dispatch_Entry::operator < (const Dispatch_Entry &d) const -{ - // for positioning in the ordered dispatch multiset - - // lowest arrival time first - if (this->arrival_ != d.arrival_) - { - return (this->arrival_ < d.arrival_) ? 1 : 0; - } - - // highest priority second - if (this->priority_ != d.priority_) - { - return (this->priority_ > d.priority_) ? 1 : 0; - } - - // lowest laxity (highest dynamic sub-priority) third - // Just use low 32 bits of worst_case_execution_time. This will - // have to change when CosTimeBase.idl is finalized. - ACE_INT32 /* Time */ this_laxity = deadline_.low - - task_entry ().rt_info ()->worst_case_execution_time.low; - ACE_INT32 /* Time */ that_laxity = d.deadline_.low - - d.task_entry ().rt_info ()->worst_case_execution_time.low; - if (this_laxity != that_laxity) - { - return (this_laxity < that_laxity) ? 1 : 0; - } - - // finally, by higher importance - return (task_entry ().rt_info ()->importance > - d.task_entry ().rt_info ()->importance) ? 1 : 0; -} - - -/////////////////////////////// -// Class Dispatch_Entry_Link // -/////////////////////////////// - - -Dispatch_Entry_Link::Dispatch_Entry_Link (Dispatch_Entry &d) - : dispatch_entry_ (d) -{ -} - // ctor - -Dispatch_Entry_Link::Dispatch_Entry_Link ( - const Dispatch_Entry_Link &d) - : dispatch_entry_ (d.dispatch_entry_) -{ -} - // copy ctor - - -/////////////////////////////////// -// Class Dispatch_Proxy_Iterator // -/////////////////////////////////// - -Dispatch_Proxy_Iterator::Dispatch_Proxy_Iterator - (ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long actual_frame_size, - u_long virtual_frame_size, - u_long number_of_calls, - u_long starting_sub_frame) - : number_of_calls_ (number_of_calls) - , current_call_ (0) - , actual_frame_size_ (actual_frame_size) - , virtual_frame_size_ (virtual_frame_size) - , current_frame_offset_ (actual_frame_size * starting_sub_frame) - , iter_ (set) -{ - first (starting_sub_frame); -} - // ctor - -int -Dispatch_Proxy_Iterator::first (u_int sub_frame) -{ - if (actual_frame_size_ * (sub_frame) >= virtual_frame_size_) - { - // can not position the virtual iterator - // in the given range: do nothing - return 0; - } - - // restart the call counter - current_call_ = 0; - - // use the given sub-frame offset if it's valid - current_frame_offset_ = actual_frame_size_ * sub_frame; - - // restart the iterator - return iter_.first (); -} - // positions the iterator at the first entry of the passed - // sub-frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::last () -{ - // use the last call - current_call_ = number_of_calls_ - 1; - - // use the last sub-frame - current_frame_offset_ = virtual_frame_size_ - actual_frame_size_; - - // position the iterator at the last dispatch - return iter_.first (); -} - // positions the iterator at the last entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::advance () -{ - int result = 1; - - if (iter_.done ()) - { - result = 0; // cannot retreat if we're out of bounds - } - else if (current_call_ < number_of_calls_ - 1) - { - // if we're still in the same set of calls, increment the call counter - ++current_call_; - } - else - { - // roll over the call counter - current_call_ = 0; - - // advance the iterator in the current sub-frame - if (! iter_.advance ()) - { - // if we're not already in the last sub_frame - if (current_frame_offset_ + actual_frame_size_ < virtual_frame_size_) - { - // increment the sub-frame offset - current_frame_offset_ += actual_frame_size_; - - // restart the iterator at the front of the sub-frame - result = iter_.first (); - } - else - { - result = 0; // cannot advance if we're already at the end - } - } - } - - return result; -} - // positions the iterator at the next entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::retreat () -{ - int result = 1; - - if (iter_.done ()) - { - result = 0; // cannot retreat if we're out of bounds - } - else if (current_call_ > 0) - { - // if we're still in the same set of calls, decrement the call counter - --current_call_; - } - else - { - // roll over the call counter - current_call_ = number_of_calls_ - 1; - - // back up the iterator in the current sub-frame - if (!iter_.retreat ()) - { - // if we're not already in the 0th sub_frame - if (current_frame_offset_ > 0) - { - // decrement the sub-frame offset - current_frame_offset_ -= actual_frame_size_; - - // restart the iterator at the tail of the sub-frame - result = iter_.last (); - } - else - { - result = 0; // cannot retreat if we're already at the start - } - } - } - - return result; -} - // positions the iterator at the previous entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - -u_long -Dispatch_Proxy_Iterator::arrival () const -{ - Dispatch_Entry_Link *link; - if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) - { - return 0; - } - - // Just use low 32 bits of arrival. This will - // have to change when CosTimeBase.idl is finalized. - return link->dispatch_entry ().arrival ().low + current_frame_offset_; -} - // returns the adjusted arrival time of the virtual entry - -u_long -Dispatch_Proxy_Iterator::deadline () const -{ - Dispatch_Entry_Link *link; - if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) - { - return 0; - } - - // Just use low 32 bits of deadline. This will - // have to change when CosTimeBase.idl is finalized. - return link->dispatch_entry ().deadline ().low + current_frame_offset_; -} - // returns the adjusted deadline time of the virtual entry - -Dispatch_Proxy_Iterator::Preemption_Priority -Dispatch_Proxy_Iterator::priority () const -{ - Dispatch_Entry_Link *link; - if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) - { - return 0; - } - - return link->dispatch_entry ().priority (); -} - // returns the scheduler priority of the virtual entry - - - -////////////////////////// -// Class TimeLine_Entry // -////////////////////////// - - - // time slice constructor -TimeLine_Entry::TimeLine_Entry (Dispatch_Entry &dispatch_entry, - u_long start, u_long stop, - u_long arrival, u_long deadline, - TimeLine_Entry *next, - TimeLine_Entry *prev) - : dispatch_entry_ (dispatch_entry) - , start_ (start) - , stop_ (stop) - , arrival_ (arrival) - , deadline_ (deadline) - , next_ (next) - , prev_ (prev) -{ -} diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h deleted file mode 100644 index 3178e463b18..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h +++ /dev/null @@ -1,591 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// SchedEntry.h -// -// = CREATION DATE -// 7 February 1998 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#if ! defined (SCHEDENTRY_H) -#define SCHEDENTRY_H - -#include "orbsvcs/RtecSchedulerC.h" -#include "orbsvcs/Event_Service_Constants.h" - -////////////////////// -// Helper Functions // -////////////////////// - -// TBD - move this to the ACE class -// Euclid's greatest common divisor algorithm -u_long gcd (u_long x, u_long y); - -// TBD - move this to the ACE class -// calculate the minimum frame size -u_long minimum_frame_size (u_long period1, u_long period2); - -// forward declaration of classes -class Task_Entry; -class Task_Entry_Link; -class Dispatch_Entry; -class Dispatch_Entry_Link; -class Dispatch_Proxy_Iterator; - - -class TAO_ORBSVCS_Export Dispatch_Entry_Link -// = TITLE -// Dispatch Entry Link -// -// = DESCRIPTION -// Light-weight sortable "smart pointer" to a dispatch entry. -// -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - Dispatch_Entry_Link (Dispatch_Entry &d); - // ctor - - Dispatch_Entry_Link (const Dispatch_Entry_Link &d); - // copy ctor - - ~Dispatch_Entry_Link (); - // dtor - - // TBD - make this a global comparison operator - // instead of a class member function - int operator < (const Dispatch_Entry_Link &d) const; - // LT comparator - - Dispatch_Entry &dispatch_entry () const; - // accessor for reference to dispatch entry - -private: - - Dispatch_Entry &dispatch_entry_; -}; - - -// Wrapper for the RT_Info, which aggregates all its dispatches -class TAO_ORBSVCS_Export Task_Entry -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - // info for DFS traversal, topological sort of call graph - enum DFS_Status {NOT_VISITED, VISITED, FINISHED}; - - // ctor - Task_Entry (); - - // dtor - ~Task_Entry (); - - // merge dispatches according to info type, update - // relevant scheduling characteristics for this entry. - // Returns 0 if all is well, or -1 if an error occurred - int merge_dispatches ( - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); - - // get, set pointer to underlying RT_Info - RT_Info *rt_info () const; - void rt_info (RT_Info *info); - - - // get effective period for the task entry - Period effective_period () const; - void effective_period (Period p); - - // set/get time when node was discovered in DFS traversal - void discovered (long l); - long discovered () const; - - // set/get time when node was finished in DFS traversal - void finished (long l); - long finished () const; - - // set/get DFS traversal status of node - void dfs_status (DFS_Status ds); - DFS_Status dfs_status () const; - - // set/get flag indicating whether node is a thread delineator - void is_thread_delineator (int i); - int is_thread_delineator () const; - - // get set of links to Task Entries which this entry calls - ACE_Unbounded_Set <Task_Entry_Link *> & calls (); - - // get set of links to Task Entries which call this entry - ACE_Unbounded_Set <Task_Entry_Link *> & callers (); - - // get set of arrivals in the effective period - ACE_Ordered_MultiSet<Dispatch_Entry_Link> &dispatches (); - - // get the type of Info the entry wraps - Info_Type info_type () const; - - // effective execution time for the task entry - u_long effective_execution_time () const; - -private: - - // prohibit calls of the given type: currently used to enforce - // the notion that two-way calls to disjunctive or conjunctive - // RT_Infos do not have any defined meaning, and thus should be - // considered dependency specification errors: if these constraints - // are removed in the future, this method should be removed as well - // Returns 0 if all is well, or -1 if an error has occurred. - int prohibit_dispatches (Dependency_Type dt); - - // performs disjunctive merge of arrival times of calls of the given - // type: all arrival times of all callers of that type are duplicated by - // the multiplier and repetition over the new frame size and merged. - // Returns 0 if all is well, or -1 if an error has occurred. - int disjunctive_merge ( - Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); - - // perform conjunctive merge of arrival times of calls of the given - // type: all arrival times of all callers of that type are duplicated - // by the multiplier and repetition over the new frame size and then - // iteratively merged by choosing the maximal arrival time at - // the current position in each queue (iteration is in lockstep - // over all queues, and ends when any queue ends). Returns 0 if - // all is well, or -1 if an error has occurred. - int conjunctive_merge ( - Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); - - - // this static method is used to reframe an existing dispatch set - // to the given new period multiplier, creating new instances of - // each existing dispatch (with adjusted arrival and deadline) - // in each successive sub-frame. Returns 1 if the set was reframed - // to a new period, 0 if the set was not changed (the new period - // was not a multiple of the old one), or -1 if an error occurred. - static int reframe (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long &set_period, u_long new_period); - - // this static method is used to merge an existing dispatch set, - // multiplied by the given multipliers for the period and number of - // instances in each period of each existing dispatch, into the - // given "into" set, without affecting the "from set". Returns 1 if - // the source set was correctly merged into the destination set, - // 0 if nothing happened, and -1 if an error occurred. - static int merge_frames (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &dest, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &src, - u_long &dest_period, - u_long src_period, - u_long number_of_calls = 1, - u_long starting_dest_sub_frame = 0); - - // pointer to the underlying RT_Info - RT_Info *rt_info_; - - // effective period for the task entry - u_long effective_period_; - - // set of arrivals in the effective period - ACE_Ordered_MultiSet<Dispatch_Entry_Link> dispatches_; - - // count of the arrivals in the effective period - u_long arrival_count_; - - DFS_Status dfs_status_; - long discovered_; - long finished_; - - // info for identifying threads in the oneway call graph - int is_thread_delineator_; - - // get set of links to Task Entries which this entry calls - ACE_Unbounded_Set <Task_Entry_Link *> calls_; - - // get set of links to Task Entries which call this entry - ACE_Unbounded_Set <Task_Entry_Link *> callers_; -}; - - -class TAO_ORBSVCS_Export Task_Entry_Link -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - // ctor - Task_Entry_Link (Task_Entry &caller, - Task_Entry &called, - CORBA::Long number_of_calls, - Dependency_Type dependency_type); - - // accessor: number of calls - CORBA::Long number_of_calls () const; - - // accessor: dependency type - Dependency_Type dependency_type () const; - - // accessor: calling task entry - Task_Entry &caller () const; - - // accessor: called task entry - Task_Entry &called () const; - -private: - - // the number of calls of the operation - CORBA::Long number_of_calls_; - - // the calling operation - Task_Entry &caller_; - - // the called operation - Task_Entry &called_; - - // the type of call dependency - Dependency_Type dependency_type_; -}; - - -class TAO_ORBSVCS_Export Dispatch_Entry -{ -// = TITLE -// Dispatch Entry -// -// = DESCRIPTION -// Descriptor object for a single dispatch of an operation. -// -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - typedef u_long Dispatch_Id; - - // ctor - Dispatch_Entry (Time arrival, - Time deadline, - Preemption_Priority priority, - Task_Entry &task_entry, - Dispatch_Entry *original_dispatch = 0); - - // copy ctor - Dispatch_Entry (const Dispatch_Entry &d); - - // id accessor - Dispatch_Id dispatch_id () const; - - // arrival accessor - Time arrival () const; - - // deadline accessor - Time deadline () const; - - // scheduler priority accessor and mutator - Preemption_Priority priority () const; - void priority (Preemption_Priority p); - - // scheduler priority accessor and mutator - OS_Priority OS_priority () const; - void OS_priority (OS_Priority p); - - // dynamic subpriority accessor and mutator - Sub_Priority dynamic_subpriority () const; - void dynamic_subpriority (Sub_Priority p); - - // static subpriority accessor and mutator - Sub_Priority static_subpriority () const; - void static_subpriority (Sub_Priority p); - - // task entry accessor - Task_Entry &task_entry () const; - - // LT comparator - // TBD - make this a global comparison operator - // instead of a class member function - int operator < (const Dispatch_Entry &d) const; - - // accessor for pointer to original dispatch - Dispatch_Entry *original_dispatch (); - -private: - // TBD - add reference counting to Dispatch Entry class, - // make the link a friend, up/down count as links come and go, - // and call entry dtor when ref count drops to 0 - - // stores the next dispatch entry id to be used - static Dispatch_Id next_id_; - - // the id of the current dispatch entry - Dispatch_Id dispatch_id_; - - // scheduler priority of the current dispatch entry - Preemption_Priority priority_; - - // OS priority of the current dispatch entry - OS_Priority OS_priority_; - - // scheduler dynamic subpriority of the current dispatch entry - Sub_Priority dynamic_subpriority_; - - // scheduler static subpriority of the current dispatch entry - Sub_Priority static_subpriority_; - - // the arrival time of the current dispatch entry - Time arrival_; - - // the deadline of the current dispatch entry - Time deadline_; - - // stores the id of the related task entry - Task_Entry &task_entry_; - - // stores a pointer to the original dispatch entry if this - // is a dispatch generated by expanding the original frame - Dispatch_Entry *original_dispatch_; - -}; - -class TAO_ORBSVCS_Export Dispatch_Proxy_Iterator -// = TITLE -// This class implements an iterator abstraction over a virtual -// frame size and number of calls, using an actual ordered -// multiset of dispatch entries over an actual frame size. -// It also serves as a proxy for the virtual dispatch to which -// it refers. Rhetorical question: is it possible to separate -// the iterator and proxy abstractions here without defeating the -// purpose of the design, which is to avoid constructing -// superfluous dispatch entries (per the conjunctive merge use case) ? -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - Dispatch_Proxy_Iterator (ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long actual_frame_size, - u_long virtual_frame_size, - u_long number_of_calls_ = 1, - u_long starting_sub_frame = 0); - // ctor - - //////////////////////// - // iterator interface // - //////////////////////// - - int done () const; - // returns 0 if there are more entries to see, 1 if not - - int first (u_int sub_frame = 0); - // positions the iterator at the first entry of the passed - // sub-frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - - int last (); - // positions the iterator at the last entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - - int advance (); - // positions the iterator at the next entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - - int retreat (); - // positions the iterator at the previous entry of the total - // frame, returns 1 if it could position the iterator - // correctly, 0 if not, and -1 if an error occurred. - - ///////////////////// - // proxy interface // - ///////////////////// - - u_long arrival () const; - // returns the adjusted arrival time of the virtual entry - - u_long deadline () const; - // returns the adjusted deadline time of the virtual entry - - Preemption_Priority priority () const; - // returns the scheduler priority of the virtual entry - - -private: - - u_long number_of_calls_; - // the number of calls corresponding to each actual dispatch - - u_long current_call_; - // the current call number for this dispatch (zero based) - - u_long actual_frame_size_; - // the frame size of the actual dispatches - - u_long virtual_frame_size_; - // the virtaul frame size over which to iterate - - u_long current_frame_offset_; - // the current offset into the virtual frame - // (should be a multiple of the actual frame size) - - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> iter_; -}; - - - -class TAO_ORBSVCS_Export TimeLine_Entry -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - // time slice constructor - TimeLine_Entry (Dispatch_Entry &dispatch_entry, - u_long start, - u_long stop, - u_long arrival, - u_long deadline, - TimeLine_Entry *next = 0, - TimeLine_Entry *prev = 0); - - // dispatch entry accessor - Dispatch_Entry &dispatch_entry () const; - - // accessors for time slice start and stop times (100 nanoseconds) - u_long start () const; - u_long stop () const; - u_long arrival () const; - u_long deadline () const; - - // accessor and mutator for next and prev slices for this dispatch - TimeLine_Entry *next (void) const; - void next (TimeLine_Entry *); - TimeLine_Entry *prev (void) const; - void prev (TimeLine_Entry *); - - int operator < (const TimeLine_Entry&) const; - -private: - - // the dispatch entry to which the time slice corresponds - Dispatch_Entry &dispatch_entry_; - - // priority time slice times (100 nanoseconds) - u_long start_; - u_long stop_; - u_long arrival_; - u_long deadline_; - - // next and previous priority time slices for this dispatch entry - TimeLine_Entry *next_; - TimeLine_Entry *prev_; - -}; - -class TAO_ORBSVCS_Export TimeLine_Entry_Link -{ -public: - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - typedef RtecScheduler::Period Period; - typedef RtecScheduler::Info_Type Info_Type; - typedef RtecScheduler::Dependency_Type Dependency_Type; - - TimeLine_Entry_Link (TimeLine_Entry &t); - // ctor - - TimeLine_Entry &entry () const; - // accessor for the underlying entry - - int operator < (const TimeLine_Entry_Link&) const; - // comparison operator - -private: - - TimeLine_Entry &entry_; - // the underlying entry - -}; - - -#if defined (__ACE_INLINE__) -#include "SchedEntry.i" -#endif /* __ACE_INLINE__ */ - -#endif /* SCHEDENTRY_H */ - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i deleted file mode 100644 index a529b59d50d..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i +++ /dev/null @@ -1,402 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// SchedEntry.i -// -// = CREATION DATE -// 7 February 1998 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -////////////////////// -// Class Task_Entry // -////////////////////// - -// return a pointer to the underlying RT_Info -ACE_INLINE Task_Entry::RT_Info * -Task_Entry::rt_info () const -{ - return rt_info_; -} - -// set the underlying RT_Info pointer -ACE_INLINE void -Task_Entry::rt_info (Task_Entry::RT_Info *info) -{ - rt_info_ = info; -} - -// get effective period for the task entry -ACE_INLINE Task_Entry::Period -Task_Entry::effective_period () const -{ - return effective_period_; -} - -// set effective period for the task entry -ACE_INLINE void -Task_Entry::effective_period (Task_Entry::Period p) -{ - effective_period_ = p; -} - -ACE_INLINE void -Task_Entry::discovered (long l) -{ - discovered_ = l; - dfs_status_ = VISITED; -} - -ACE_INLINE long -Task_Entry::discovered () const -{ - return discovered_; -} - -ACE_INLINE void -Task_Entry::finished (long l) -{ - finished_ = l; - dfs_status_ = FINISHED; -} - -ACE_INLINE long -Task_Entry::finished () const -{ - return finished_; -} - -ACE_INLINE Task_Entry::DFS_Status -Task_Entry::dfs_status () const -{ - return dfs_status_; -} - -ACE_INLINE void -Task_Entry::dfs_status (Task_Entry::DFS_Status ds) -{ - dfs_status_ = ds; -} - -ACE_INLINE void -Task_Entry::is_thread_delineator (int i) -{ - is_thread_delineator_ = i; -} - -ACE_INLINE int -Task_Entry::is_thread_delineator () const -{ - return is_thread_delineator_; -} - -// access set of Task Entries on which this entry depends -ACE_INLINE ACE_Unbounded_Set <Task_Entry_Link *> & -Task_Entry::calls () -{ - return calls_; -} - -// access set of Task Entries which depend on this entry -ACE_INLINE ACE_Unbounded_Set <Task_Entry_Link *> & -Task_Entry::callers () -{ - return callers_; -} - -// get set of arrivals in the effective period -ACE_INLINE ACE_Ordered_MultiSet<Dispatch_Entry_Link> & -Task_Entry::dispatches () -{ - return dispatches_; -} - - -ACE_INLINE Task_Entry::Info_Type -Task_Entry::info_type () const -{ - return rt_info_->info_type; -} - -ACE_INLINE u_long -Task_Entry::effective_execution_time () const -{ - // Just use low 32 bits. This will have to change when CosTimeBase.idl - // is finalized. - ACE_UINT32 worst_case_execution_time = - ACE_static_cast (ACE_UINT32, rt_info_->worst_case_execution_time.low); - - return (rt_info_->info_type == RtecScheduler::OPERATION) - ? worst_case_execution_time * arrival_count_ - : 0; -} - - -/////////////////////////// -// Class Task_Entry_Link // -/////////////////////////// - - -// accessor: number of calls of dependency by dependant -ACE_INLINE CORBA::Long -Task_Entry_Link::number_of_calls () const -{ - return number_of_calls_; -} - -ACE_INLINE Task_Entry_Link::Dependency_Type -Task_Entry_Link::dependency_type () const -{ - return dependency_type_; -} - -// accessor: dependant task entry -ACE_INLINE Task_Entry & -Task_Entry_Link::caller () const -{ - return caller_; -} - -// accessor: dependency task entry -ACE_INLINE Task_Entry & -Task_Entry_Link::called () const -{ - return called_; -} - -////////////////////////// -// Class Dispatch Entry // -////////////////////////// - -ACE_INLINE u_long -Dispatch_Entry::dispatch_id () const -{ - return dispatch_id_; -} - -ACE_INLINE Dispatch_Entry::Preemption_Priority -Dispatch_Entry::priority () const -{ - return priority_; -} - -ACE_INLINE void -Dispatch_Entry::priority (Dispatch_Entry::Preemption_Priority p) -{ - priority_ = p; -} - -ACE_INLINE Dispatch_Entry::OS_Priority -Dispatch_Entry::OS_priority () const -{ - return OS_priority_; -} - -ACE_INLINE void -Dispatch_Entry::OS_priority (Dispatch_Entry::OS_Priority p) -{ - OS_priority_ = p; -} - -ACE_INLINE Dispatch_Entry::Sub_Priority -Dispatch_Entry::dynamic_subpriority () const -{ - return dynamic_subpriority_; -} - -ACE_INLINE void -Dispatch_Entry::dynamic_subpriority (Dispatch_Entry::Sub_Priority p) -{ - dynamic_subpriority_ = p; -} - -ACE_INLINE Dispatch_Entry::Sub_Priority -Dispatch_Entry::static_subpriority () const -{ - return static_subpriority_; -} - -ACE_INLINE void -Dispatch_Entry::static_subpriority (Dispatch_Entry::Sub_Priority p) -{ - static_subpriority_ = p; -} - - -ACE_INLINE Dispatch_Entry::Time -Dispatch_Entry::arrival () const -{ - return arrival_; -} - -ACE_INLINE Dispatch_Entry::Time -Dispatch_Entry::deadline () const -{ - return deadline_; -} - -ACE_INLINE Task_Entry & -Dispatch_Entry::task_entry () const -{ - return task_entry_; -} - - -// accessor for pointer to original dispatch -ACE_INLINE Dispatch_Entry * -Dispatch_Entry::original_dispatch () -{ - return original_dispatch_; -} - - -/////////////////////////////// -// Class Dispatch_Entry_Link // -/////////////////////////////// - -ACE_INLINE -Dispatch_Entry_Link::~Dispatch_Entry_Link () -{ -} - // dtor - -ACE_INLINE int -Dispatch_Entry_Link::operator < (const Dispatch_Entry_Link &d) const -{ - return (this->dispatch_entry_ < d.dispatch_entry_); -} - // GT comparator - - -ACE_INLINE Dispatch_Entry & -Dispatch_Entry_Link::dispatch_entry () const -{ - return dispatch_entry_; -} - // accessor for reference to dispatch entry - - -/////////////////////////////////// -// Class Dispatch_Proxy_Iterator // -/////////////////////////////////// - -ACE_INLINE int -Dispatch_Proxy_Iterator::done () const -{ - return iter_.done (); -} - // returns 0 if there are more entries to see, 1 if not - - -////////////////////////// -// Class TimeLine_Entry // -////////////////////////// - - // dispatch entry accessor -ACE_INLINE Dispatch_Entry & -TimeLine_Entry::dispatch_entry () const -{ - return dispatch_entry_; -} - - -// accessor for time slice start time (100 nanoseconds) -ACE_INLINE u_long -TimeLine_Entry::start () const -{ - return start_; -} - -// accessor for time slice stop time (100 nanoseconds) -ACE_INLINE u_long -TimeLine_Entry::stop () const -{ - return stop_; -} - -// accessor for time slice stop time (100 nanoseconds) -ACE_INLINE u_long -TimeLine_Entry::arrival () const -{ - return arrival_; -} - -// accessor for time slice stop time (100 nanoseconds) -ACE_INLINE u_long -TimeLine_Entry::deadline () const -{ - return deadline_; -} - - -// accessor for next slice for this dispatch -ACE_INLINE TimeLine_Entry * -TimeLine_Entry::next (void) const -{ - return next_; -} - -// mutator for next slice for this dispatch -ACE_INLINE void -TimeLine_Entry::next (TimeLine_Entry *t) -{ - next_ = t; -} - -// accessor for previous slice for this dispatch -ACE_INLINE TimeLine_Entry * -TimeLine_Entry::prev (void) const -{ - return prev_; -} - -// mutator for previous slice for this dispatch -ACE_INLINE void -TimeLine_Entry::prev (TimeLine_Entry *t) -{ - prev_ = t; -} - - -ACE_INLINE int -TimeLine_Entry::operator < (const TimeLine_Entry &t) const -{ - return (start_ < t.start_) ? 1 : 0; -} - // comparison operator - - -/////////////////////////////// -// Class TimeLine_Entry_Link // -/////////////////////////////// - - -ACE_INLINE TimeLine_Entry_Link::TimeLine_Entry_Link (TimeLine_Entry &t) - : entry_ (t) -{ -} - // ctor - -ACE_INLINE TimeLine_Entry & -TimeLine_Entry_Link::entry () const -{ - return entry_; -} - // accessor for the underlying entry - -ACE_INLINE int -TimeLine_Entry_Link::operator < (const TimeLine_Entry_Link &l) const -{ - return (entry_ < l.entry_) ? 1 : 0; -} - // comparison operator - diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp deleted file mode 100644 index 4caf5bb269b..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp +++ /dev/null @@ -1,280 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler.cpp -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - -#include "ace/Sched_Params.h" -#include "orbsvcs/Time_Utilities.h" -#include "Scheduler.h" - -#if ! defined (__ACE_INLINE__) -#include "Scheduler.i" -#endif /* __ACE_INLINE__ */ - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class Scheduler static members -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -const ACE_Scheduler::mode_t ACE_Scheduler::CURRENT_MODE = 0xFFFFFFFF; - -ACE_Scheduler *ACE_Scheduler::instance_ = 0; - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class ACE_Scheduler static functions -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -void -ACE_Scheduler::output (FILE *file, const status_t status) -{ - switch (status) - { - case NOT_SCHEDULED : - ACE_OS::fprintf (file, "NOT_SCHEDULED"); - break; - case SUCCEEDED : - ACE_OS::fprintf (file, "SUCCEEDED"); - break; - case ST_TASK_ALREADY_REGISTERED : - ACE_OS::fprintf (file, "TASK_ALREADY_REGISTERED"); - break; - case ST_VIRTUAL_MEMORY_EXHAUSTED : - ACE_OS::fprintf (file, "VIRTUAL_MEMORY_EXHAUSTED"); - break; - case ST_UNKNOWN_TASK : - ACE_OS::fprintf (file, "UNKNOWN_TASK"); - break; - case INVALID_MODE : - ACE_OS::fprintf (file, "INVALID_MODE"); - break; - case MODE_COUNT_MISMATCH : - ACE_OS::fprintf (file, "MODE_COUNT_MISMATCH"); - break; - case TASK_COUNT_MISMATCH : - ACE_OS::fprintf (file, "TASK_COUNT_MISMATCH"); - break; - case INVALID_PRIORITY : - ACE_OS::fprintf (file, "INVALID_PRIORITY"); - break; - - // The following are only used during scheduling (in the case of - // off-line scheduling, they are only used prior to runtime). - // To save a little code space (280 bytes on g++ 2.7.2/Solaris 2.5.1), - // we could conditionally compile them so that they're not in the - // runtime version. - case ST_UTILIZATION_BOUND_EXCEEDED : - ACE_OS::fprintf (file, "UTILIZATION_BOUND_EXCEEDED"); - break; - case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS : - ACE_OS::fprintf (file, "INSUFFICIENT_THREAD_PRIORITY_LEVELS"); - break; - case ST_CYCLE_IN_DEPENDENCIES : - ACE_OS::fprintf (file, "CYCLE_IN_DEPENDENCIES"); - break; - case UNABLE_TO_OPEN_SCHEDULE_FILE : - ACE_OS::fprintf (file, "UNABLE_TO_OPEN_SCHEDULE_FILE"); - break; - case UNABLE_TO_WRITE_SCHEDULE_FILE : - ACE_OS::fprintf (file, "UNABLE_TO_WRITE_SCHEDULE_FILE"); - break; - // End of config-only status values. - - default: - ACE_OS::fprintf (file, "UNKNOWN STATUS: %d", status); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class ACE_Scheduler member functions -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -ACE_Scheduler::ACE_Scheduler () : - minimum_priority_queue_ (0), // Could initialize this to -1, but it's - // unsigned and we don't really need to - // distinguish between no queues and one - // queue. - modes_ (0), - tasks_ (0), - threads_ (0), - mode_ (0), - status_ (NOT_SCHEDULED), - output_level_ (0) -{ -} - - -ACE_Scheduler::~ACE_Scheduler () -{ -} - - -// ************************************************************ - -ACE_Scheduler::status_t -ACE_Scheduler::get_rt_info (Object_Name name, - RT_Info* &rtinfo) -{ - handle_t handle; - - // This makes a copy. We can optimize this with our own string - // class. - ACE_CString lookup (name); - // Search the map for the <name>. If found, return the RT_Info. - RT_Info **info_array = 0; - if (info_collection_.find (lookup, info_array) >= 0) - { - rtinfo = info_array[0]; - // If we find it, return. - return SUCCEEDED; - } - else - // Otherwise, make one, bind it, and register it. - { - rtinfo = new RT_Info; - rtinfo->entry_point = name; - // Create and array (size one) of RT_Info* - info_array = new RT_Info*[1]; - info_array[0] = rtinfo; - // Bind the rtinfo to the name. - if (info_collection_.bind (lookup, info_array) != 0) - { - delete rtinfo; - delete info_array; - rtinfo = 0; - return FAILED; // Error! - } - else - { - // Register the array. - status_t result = this->register_task (info_array, 1, handle); - if (result == SUCCEEDED) - { - rtinfo->handle = handle; - return ST_UNKNOWN_TASK; // Didn't find it, but made one! - } - else - { - rtinfo->handle = 0; - return FAILED; - } - } - } -} - - - -int ACE_Scheduler::number_of_dependencies(RT_Info* rt_info) -{ - return rt_info->dependencies.length(); -} - -int ACE_Scheduler::number_of_dependencies(RT_Info& rt_info) -{ - return rt_info.dependencies.length(); -} - -int ACE_Scheduler::add_dependency(RT_Info* rt_info, - const Dependency_Info& d) -{ - ACE_DEBUG ((LM_DEBUG, "adding dependecy to: %s\n", - (const char*)rt_info->entry_point)); - RtecScheduler::Dependency_Set& set = rt_info->dependencies; - int l = set.length(); - set.length(l + 1); - set[l] = d; - return 0; -} - -void ACE_Scheduler::export(RT_Info* info, FILE* file) -{ - export(*info, file); -} - -void ACE_Scheduler::export(RT_Info& info, FILE* file) -{ - // The divide-by-1 is for ACE_U_LongLong support. - (void) ACE_OS::fprintf (file, - "%s\n%d\n%ld\n%ld\n%ld\n%ld\n%d\n%ld\n%u\n" - "# begin dependencies\n%d\n", - (const char*)info.entry_point, - info.handle, - ORBSVCS_Time::to_hrtime (info.worst_case_execution_time) / 1, - ORBSVCS_Time::to_hrtime (info.typical_execution_time) / 1, - ORBSVCS_Time::to_hrtime (info.cached_execution_time) / 1, - info.period, - info.importance, - ORBSVCS_Time::to_hrtime (info.quantum) / 1, - info.threads, - number_of_dependencies(info)); - - for (int i = 0; i < number_of_dependencies(info); ++i) - { - RT_Info tmp; - // TODO: info.dependencies [i].rt_info >>= &tmp; - (void) ACE_OS::fprintf (file, "%s, %d\n", - (const char*)tmp.entry_point, - info.dependencies[i].number_of_calls); - - } - - (void) ACE_OS::fprintf (file, "# end dependencies\n%d\n%d\n%d\n\n", - info.priority, - info.dynamic_subpriority, - info.static_subpriority); - - -} - - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **>; - -template class ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX>; -template class ACE_Map_Manager<ACE_CString, - ACE_Scheduler::RT_Info **, - ACE_SYNCH_MUTEX>; -template class ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, - ACE_SYNCH_MUTEX>; -template class ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, - ACE_SYNCH_MUTEX>; -template class ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, - ACE_SYNCH_MUTEX>; -template class ACE_Read_Guard<ACE_SYNCH_MUTEX>; -template class ACE_Write_Guard<ACE_SYNCH_MUTEX>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **> - -#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Map_Manager<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Read_Guard<ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Write_Guard<ACE_SYNCH_MUTEX> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h deleted file mode 100644 index 9f22254088e..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h +++ /dev/null @@ -1,276 +0,0 @@ -/* -*- C++ -*- */ -// -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler.h -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - -#if ! defined (SCHEDULER_H) -#define SCHEDULER_H - -#include "ace/ACE.h" -#include "ace/Map_Manager.h" -#include "ace/Message_Block.h" -#include "ace/Synch.h" -#include "ace/SString.h" - -#include "orbsvcs/RtecSchedulerC.h" -#include "orbsvcs/Event_Service_Constants.h" - -class TAO_ORBSVCS_Export ACE_Scheduler - // = TITLE - // Thread scheduler interface. - // - // = DESCRIPTION - // This virtual base class is the interface to either an off-line - // scheduler, or to the necessary on-line component of the Scheduler. -{ -public: - typedef u_int mode_t; - - typedef RtecScheduler::handle_t handle_t; - typedef RtecScheduler::Dependency_Info Dependency_Info; - typedef RtecScheduler::Preemption_Priority Preemption_Priority; - typedef RtecScheduler::OS_Priority OS_Thread_Priority; - typedef RtecScheduler::Sub_Priority Sub_Priority; - typedef RtecScheduler::RT_Info RT_Info; - typedef RtecScheduler::Time Time; - - // Map some types to simplify re-use. - - typedef const char *Object_Name; - // Objects are named by unique strings. - - static const mode_t CURRENT_MODE; - - enum status_t { - // The following are used both by the runtime Scheduler and during - // scheduling. - NOT_SCHEDULED = -1 // the schedule () method has not been called yet - , FAILED = -1 - , SUCCEEDED - , ST_UNKNOWN_TASK - , ST_TASK_ALREADY_REGISTERED - , ST_VIRTUAL_MEMORY_EXHAUSTED - - // The following are only used by the runtime Scheduler. - , INVALID_MODE - , MODE_COUNT_MISMATCH // only used by schedule () - , TASK_COUNT_MISMATCH // only used by schedule () - , INVALID_PRIORITY // only used by schedule (): mismatch of - // (off-line, maybe) Scheduler output to - // the runtime Scheduler component. - - // The following are only used during scheduling (in the case of - // off-line scheduling, they are only used prior to runtime). - , ST_UTILIZATION_BOUND_EXCEEDED - , ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS - , ST_CYCLE_IN_DEPENDENCIES - , UNABLE_TO_OPEN_SCHEDULE_FILE - , UNABLE_TO_WRITE_SCHEDULE_FILE - }; - - virtual ~ACE_Scheduler (); - - // = Utility function for outputting the textual representation of a - // status_t value to a FILE. - static void output (FILE *, const status_t); - - // = Initialize the scheduler. - virtual void init (const int minimum_priority, - const int maximum_priority, - const char *runtime_filename = 0, - const char *rt_info_filename = 0, - const char *timeline_filename = 0) = 0; - // The minimum and maximum priority are the OS-specific priorities that - // are used when creating the schedule (assigning priorities). The - // minimum_priority is the priority value of the lowest priority. - // It may be numerically higher than the maximum_priority, on OS's such - // as VxWorks that use lower values to indicate higher priorities. - // - // When Scheduler::schedule is called, the schedule is output to the - // file named by "runtime_filename" if it is non-zero. - // This file is compilable; it is linked into the runtime executable - // to provide priorities to the runtime scheduling component. - // If the "rt_info_filename" is non-zero, the RT_Info for - // every task is exported to it. It is not used at runtime. - // If the "timeline_filename" is non-zero, the timeline output - // file is created. It is not used at runtime. - // - // The runtime scheduling component ignores these filenames. It just - // uses the priorities that were linked in to the executable, after - // converting them to platform-specific values. - - // = Registers a task. - virtual status_t register_task (RT_Info *[], - const u_int number_of_modes, - handle_t &handle) = 0; - // If the Task registration succeeds, this function returns SUCCEEDED - // and sets "handle" to a unique identifier for the task. - // Otherwise, it returns either VIRTUAL_MEMORY_EXHAUSTED or - // TASK_ALREADY_REGISTERED sets the handle to 0. (A task may - // only be registered once.) - // The RT_Info * array is indexed by mode; there must be one element for - // each mode, as specified by number_of_modes. If a task does not - // run in a mode, then its entry in the array for that mode must - // be 0. - - virtual status_t get_rt_info (Object_Name name, - RT_Info* &rtinfo); - // Tries to find the RT_Info corresponding to <name> in the RT_Info - // database. Returns SUCCEEDED if <name> was found and <rtinfo> was - // set. Returns UNKNOWN_TASK if <name> was not found, but <rtinfo> - // was set to a newly allocated RT_Info. In this UNKNOWN_TASK case, - // the task must call RT_Info::set to fill in execution properties. - // In the SUCCEEDED and UNKNOWN_TASK cases, this->register_task - // (rtinfo, 0, handle) is called. Returns FAILED if an error - // occurs. - // - // One motivation for allocating RT_Info's from within the Scheduler - // is to allow RT_Infos to persist after the tasks that use them. - // For instance, we may want to call this->schedule right before the - // application exits a configuration run. If the tasks have been - // deleted (deleting their RT_Infos with them), this->schedule will - // fail. - - virtual status_t lookup_rt_info (handle_t handle, - RT_Info* &rtinfo) = 0; - // Obtains an RT_Info based on its "handle". - - // = Computes the schedule. - virtual status_t schedule (void) = 0; - // This actually generates the files. - - // = Access a thread priority. - virtual int priority (const handle_t handle, - OS_Thread_Priority &priority, - Sub_Priority &subpriority, - Preemption_Priority &preemption_prio, - const mode_t = CURRENT_MODE) const = 0; - // Defines "priority" as the priority that was assigned to the Task that - // was assigned "handle", for the specified mode. Defines "subpriority" - // as the relative ordering (due to dependencies) within the priority. - // Returns 0 on success, or -1 if an invalid mode or handle are supplied. - // Queue numbers are platform-independent priority values, ranging from - // a highest priority value of 0 to the lowest priority value, which is - // returned by "minimum_priority_queue ()". The current and deadline times - // are part of the scheduling service implementation interface, but may be - // ignored by some implementations and used by others. - - // = Access the platform-independent priority value of the lowest-priority - // thread. - u_int minimum_priority_queue () const { return minimum_priority_queue_; } - // This is intended for use by the Event Channel, so it can determine the - // number of priority dispatch queues to create. - - // = Access the number of modes. - u_int modes () const { return modes_; } - - // = Access the number of tasks. - u_int tasks () const { return tasks_; } - - // = Access the number of threads. - u_int threads () const { return threads_; } - - // = Access the current mode. - mode_t mode () const { return mode_; } - - // = Set the current mode. - void mode (const mode_t mode) { mode_ = mode; } - - // = Access the current scheduler status. - status_t status () const { return status_; } - - // = Access the current output (debugging) level. - u_int output_level () const { return output_level_; } - // Default is 0; set to 1 to print out schedule, by task. Set - // to higher than one for debugging info. - - // = Set the scheduler output (debugging) level. - void output_level (const u_int level) { output_level_ = level; } - // the only supported levels are 0 (quiet), 1 (verbose) and 2 - // (debug) - - static int add_dependency(RT_Info* rt_info, - const Dependency_Info& d); - - static int number_of_dependencies(RT_Info* rt_info); - static int number_of_dependencies(RT_Info& rt_info); - - static void export(RT_Info*, FILE* file); - static void export(RT_Info&, FILE* file); - -protected: - ACE_Scheduler (); - - // = Set the minimum priority value. - void minimum_priority_queue (const u_int minimum_priority_queue_number) - { minimum_priority_queue_ = minimum_priority_queue_number; } - - // = Set the number of modes. - void modes (const u_int modes) { modes_ = modes; } - - // = Set the number of tasks. - void tasks (const u_int tasks) { tasks_ = tasks; } - - // = Set the number of threads. - void threads (const u_int threads) { threads_ = threads; } - - // = Set the current scheduler status. - void status (const status_t new_status) { status_ = new_status; } - -private: - typedef ACE_CString EXT; - typedef RT_Info **INT; - - typedef ACE_Map_Manager<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection; - typedef ACE_Map_Iterator<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection_Iterator; - typedef ACE_Map_Entry<EXT, INT> Info_Collection_Entry; - - Info_Collection info_collection_; - // A binding of name to rt_info. This is the mapping for every - // rt_info in the process. - - static ACE_Scheduler *instance_; - - u_int minimum_priority_queue_; - // The platform-independent priority value of the Event Channel's - // minimum priority dispatch queue. The value of the maximum priority - // dispatch queue is always 0. - - u_int modes_; - u_int tasks_; - u_int threads_; - - mode_t mode_; - status_t status_; - u_int output_level_; - - // the following functions are not implememented - ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler (const ACE_Scheduler &)) - ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler &operator= (const ACE_Scheduler &)) -}; - -typedef ACE_Scheduler Scheduler; - -#if defined (__ACE_INLINE__) -#include "Scheduler.i" -#endif /* __ACE_INLINE__ */ - -#endif /* SCHEDULER_H */ - - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i deleted file mode 100644 index 57875ae26d1..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i +++ /dev/null @@ -1,20 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler.i -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - -// EOF - diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp deleted file mode 100644 index 1b36d49e1d6..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp +++ /dev/null @@ -1,262 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler_Generic.cpp -// -// = CREATION DATE -// 19 November 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - -#include "ace/Sched_Params.h" - -#include "Scheduler_Generic.h" - -#if ! defined (__ACE_INLINE__) -#include "Scheduler_Generic.i" -#endif /* __ACE_INLINE__ */ - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// static functions -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -// Structure for storing the RT_Info information for each task, per mode. -struct Mode_Entry -{ - RtecScheduler::RT_Info *rt_info_; - u_long start_time_; // microseconds - u_long stop_time_; // microseconds - - Mode_Entry() : - rt_info_ (0), - start_time_ (0), - stop_time_ (0) - { - } - - Mode_Entry(RtecScheduler::RT_Info *const rt_info, - const u_long start_time = 0, - const u_long stop_time = 0) : - rt_info_ (rt_info), - start_time_ (start_time), - stop_time_ (stop_time) - { - } - - ~Mode_Entry () {} - - Mode_Entry &operator= (const Mode_Entry &entry) - { - if (this != &entry) - { - rt_info_ = entry.rt_info_; - start_time_ = entry.start_time_; - stop_time_ = entry.stop_time_; - } - - return *this; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class Scheduler_Generic member functions -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -Scheduler_Generic::Scheduler_Generic () : - Scheduler (), - handles_ (0), - // Set the minimum priority to that for the current platform. This - // shouldn't be necessary, but UPSingleProcessorOrb::initialize_reactors - // creates threads before the Event Channel calls Scheduler::init (). - minimum_priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, - ACE_SCOPE_THREAD)), - increasing_priority_ (-1), - task_entries_ () -{ -} - - -Scheduler_Generic::~Scheduler_Generic () -{ - reset (); -} - - -void -Scheduler_Generic::reset () -{ -} - -Scheduler::status_t -Scheduler_Generic::lookup_rt_info (handle_t handle, - RT_Info*& rtinfo) -{ - if (handle < 0 || (size_t) handle > task_entries_.size ()) - { - return ST_UNKNOWN_TASK; - } - RT_Info*** entry; - ACE_Unbounded_Set_Iterator <RT_Info **> i (task_entries_); - while (i.next (entry) != 0) - { - i.advance (); - RT_Info** array = *entry; - if (array[0]->handle == handle) - { - rtinfo = array[0]; - return SUCCEEDED; - } - } - - return ST_UNKNOWN_TASK; -} - - -Scheduler::status_t -Scheduler_Generic::register_task (RT_Info *rt_info [], - const u_int number_of_modes, - handle_t &handle) -{ - status_t ret; - - // try to store the new task's information . . . - switch (task_entries_.insert (rt_info)) - { - case 0 : // successfully inserted - { - rt_info [0]->handle = (handle = ++handles_); - - // assigned the same handle to the RT_Info for each of its modes - for (u_int i = 1; i < number_of_modes; ++i) - { - if (rt_info [i] != 0) - rt_info [i]->handle = handle; - } - - if (number_of_modes > modes ()) - { - modes (number_of_modes); - } - - ret = SUCCEEDED; - - if (output_level () >= 5) - { - ACE_OS::printf ("registered task \"%s\" with RT_Info starting " - "at %X\n", - (const char*)rt_info[0]->entry_point, - (void *) rt_info[0]); - } - } - break; - - case 1 : // the entry had already been inserted - handle = 0; - ret = ST_TASK_ALREADY_REGISTERED; - break; - - default : - // case -1 : insert failed, probably because virtual memory exhaused - handle = 0; - ret = ST_VIRTUAL_MEMORY_EXHAUSTED; - break; - } - - return ret; -} - - -void -Scheduler_Generic::init (const int minimum_priority, - const int maximum_priority, - const char *runtime_filename, - const char *rt_info_filename, - const char *timeline_filename) -{ - minimum_priority_ = minimum_priority; - maximum_priority_ = maximum_priority; - runtime_filename_ = runtime_filename; - rt_info_filename_ = rt_info_filename; - timeline_filename_ = timeline_filename; -} - - -Scheduler::status_t -Scheduler_Generic::schedule (void) -{ - ACE_Guard<LOCK> ace_mon (lock_); - - // here goes . . . - - increasing_priority_ = maximum_priority_ >= minimum_priority_; - - status_t status = ACE_Scheduler::SUCCEEDED; - - // store number of tasks, based on registrations - tasks (task_entries_.size ()); - - if (output_level () > 0) - { - print_schedule (); - } - - return status; -} - - -int -Scheduler_Generic::priority (const handle_t handle, - OS_Thread_Priority &priority, - Sub_Priority &subpriority, - Preemption_Priority &preemption_prio, - const mode_t requested_mode) const -{ - ACE_UNUSED_ARG (handle); - ACE_UNUSED_ARG (requested_mode); - - priority = minimum_priority_; - subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; - preemption_prio = ACE_Scheduler_MAX_PREEMPTION_PRIORITY; - - if (output_level () >= 3) - { - ACE_OS::printf ("preemption_prio %d: min %d, pri %d, min_pri %d\n", - preemption_prio, minimum_priority_queue (), - priority, minimum_priority_); - } - - return 0; -} - - -void -Scheduler_Generic::print_schedule () -{ -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Node<RtecScheduler::RT_Info **>; -template class ACE_Unbounded_Set<RtecScheduler::RT_Info **>; -template class ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info **>; -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Node<RtecScheduler::RT_Info **> -#pragma instantiate ACE_Unbounded_Set<RtecScheduler::RT_Info **> -#pragma instantiate ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info **> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h deleted file mode 100644 index 4e27a9999ce..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler_Generic.h -// -// = CREATION DATE -// 19 November 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - -#if ! defined (SCHEDULER_INTERNAL_H) -#define SCHEDULER_INTERNAL_H - -#include "Scheduler.h" - -class TAO_ORBSVCS_Export Scheduler_Generic : public ACE_Scheduler - // = TITLE - // Implementation of an off-line scheduler. - // - // = DESCRIPTION - // Schedules tasks, assigning the same priority to all of them. -{ -public: - Scheduler_Generic (); - virtual ~Scheduler_Generic (); - - // = Initialize the scheduler. - virtual void init (const int minimum_priority, - const int maximum_priority, - const char *runtime_filename = 0, - const char *rt_info_filename = 0, - const char *timeline_filename = 0); - - // = Registers a task. - virtual status_t register_task (RT_Info *[], - const u_int number_of_modes, - handle_t &handle); - - virtual status_t lookup_rt_info (handle_t handle, - RT_Info* &rtinfo); - // Obtains an RT_Info based on its "handle". - - // = Computes the schedule. - virtual status_t schedule (void); - - // = Access a thread priority. - virtual int priority (const handle_t handle, - OS_Thread_Priority &priority, - Sub_Priority &subpriority, - Preemption_Priority &preemption_prio, - const mode_t = CURRENT_MODE) const; - // Defines "priority" as the priority that was assigned to the Task that - // was assigned "handle", for the specified mode. Defines "subpriority" - // as the relative ordering (due to dependencies) within the priority. - // Returns 0 on success, or 1 if an invalid mode or handle are supplied. - -private: - u_int handles_; - // The number of task handles dispensed so far. - - int minimum_priority_; - // The minimum priority value that the application specified (in - // its call to init ()). - - int maximum_priority_; - // The maximum priority value that the application specified (in - // its call to init ()). - - const char *runtime_filename_; - // Destination file of Scheduler output from the configuration run. - - const char *rt_info_filename_; - // Destination file of all rt_info data from the configuration run. - - const char *timeline_filename_; - // The destination of the timeline. - - int increasing_priority_; - // Set to 1 if priority values increase with increasing priority, - // such as on Solaris and Win32, or 0 if they decrease, such as on - // VxWorks. - - ACE_Unbounded_Set <RT_Info **> task_entries_; - // Collection of known tasks. - -#if defined (ACE_HAS_THREADS) - typedef ACE_Recursive_Thread_Mutex LOCK; -#else - typedef ACE_Null_Mutex LOCK; -#endif /* ACE_HAS_THREADS */ - - LOCK lock_; - // This protects access to the scheduler during configuration runs. - - - /////////////////////////////////////// - // member functions for internal use // - /////////////////////////////////////// - - void reset (); - // Prepare for another schedule computation, but do not - // disturb the "output" (priorities that have already been assigned). - - void print_schedule (); - // Display the schedule, task-by-task. - - ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic (const Scheduler_Generic &)) - ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic &operator= ( - const Scheduler_Generic &)) -}; - - -#if defined (__ACE_INLINE__) -#include "Scheduler_Generic.i" -#endif /* __ACE_INLINE__ */ - -#endif /* SCHEDULER_INTERNAL_H */ - - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i deleted file mode 100644 index 71e3695dc35..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i +++ /dev/null @@ -1,21 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Scheduler_Generic.i -// -// = CREATION DATE -// 23 January 1997 -// -// = AUTHOR -// David Levine -// -// ============================================================================ - - -// EOF - diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp deleted file mode 100644 index 6bf1ec951fb..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp +++ /dev/null @@ -1,1419 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Strategy_Scheduler.cpp -// -// = CREATION DATE -// 22 December 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#include "Strategy_Scheduler.h" -#include "ace/Sched_Params.h" -#include "math.h" - -#if ! defined (__ACE_INLINE__) -#include "Strategy_Scheduler.i" -#endif /* __ACE_INLINE__ */ - -////////////////////////////////////////////// -// helper function type definition for sort // -////////////////////////////////////////////// - -// this is awkward, but it makes MSVC++ happy -extern "C" -{ -typedef int (*COMP_FUNC) (const void*, const void*); -} - -/////////////////////////////////////////////////// -// class ACE_Strategy_Scheduler member functions // -/////////////////////////////////////////////////// - -ACE_Strategy_Scheduler::ACE_Strategy_Scheduler (ACE_Scheduler_Strategy &strategy) - : ACE_DynScheduler (), - strategy_ (strategy) -{ -} - // = ctor - - -ACE_Strategy_Scheduler::~ACE_Strategy_Scheduler () -{ -} - // = virtual dtor - - -ACE_DynScheduler::status_t -ACE_Strategy_Scheduler::sort_dispatches (Dispatch_Entry **dispatches, - u_int count) -{ - // sort the entries in order of priority and subpriority - strategy_.sort (dispatches, count); - - return ACE_DynScheduler::SUCCEEDED; -} - // = sets up the schedule in the order generated - // by the strategy's comparison operators - -ACE_DynScheduler::status_t -ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches, - u_int count) -{ - // start with happy status - ACE_DynScheduler::status_t status = ACE_DynScheduler::SUCCEEDED; - - // start with the highest OS priority in the given range and work downward: - // if we run out of values to assign, return an error. - int current_OS_priority = maximum_priority_; - - // start scheduler priority at 0 (highest priority queue number) - // NOTE: 0 is highest for priority, lowest for dynamic and static subpriority - Preemption_Priority current_scheduler_priority = 0; - - // value the OS and scheduler priorities in 0th dispatch entry - dispatches[0]->OS_priority (current_OS_priority); - dispatches[0]->priority (current_scheduler_priority); - // set OS priority and Scheduler priority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [0]->task_entry ().rt_info ()->priority = - current_OS_priority; - dispatches [0]->task_entry ().rt_info ()->preemption_priority = - current_scheduler_priority; - - // traverse ordered dispatch entry array, assigning priority - // (array is sorted from highest to lowest priority) - for (u_int i = 1; i < count; ++i) - { - switch (strategy_.priority_comp (*(dispatches[i-1]), - *(dispatches[i]))) - { - case -1: // the current entry is at lower priority than the previous - { - // decrease priority by incrementing the current scheduling priority - // number: 0 is the highest priority number. - ++current_scheduler_priority; - - // check for OS priority level boundaries: because OS priority values - // can run in either increasing or decreasing order, there is no easy, - // portable way to check other than exact comparison to the bounds - // that were given in init () or that came from the platform itself. - if ((current_OS_priority == minimum_priority_) || - (current_OS_priority == ACE_Sched_Params::previous_priority ( - ACE_SCHED_FIFO, - current_OS_priority, - ACE_SCOPE_PROCESS))) - { - // if we have run out of priority levels to assign, indicate - // this in the return status, but keep right on assigning the - // minimum OS priority in the range to the remaining tasks. - status = ACE_DynScheduler::ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS; - } - else - { - // we're still in range, so decrement the current OS priority level - current_OS_priority = - ACE_Sched_Params::previous_priority (ACE_SCHED_FIFO, - current_OS_priority, - ACE_SCOPE_PROCESS); - } - - break; - } - case 0: // still at the same priority level - - break; - - default: // should never reach here: something *bad* has happened - - ACE_ERROR_RETURN (( - LM_ERROR, - "Priority assignment failure: tasks" - " \"%s\" and \"%s\" are out of order.\n", - dispatches [i-1]->task_entry ().rt_info ()->entry_point.in (), - dispatches [i]->task_entry ().rt_info ()->entry_point.in ()), - ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING); - } - - // set OS priority of the current dispatch entry - dispatches[i]->OS_priority (current_OS_priority); - - // set scheduler priority of the current dispatch entry - dispatches[i]->priority (current_scheduler_priority); - - // set OS priority and Scheduler priority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i]->task_entry ().rt_info ()->priority = - current_OS_priority; - dispatches [i]->task_entry ().rt_info ()->preemption_priority = - current_scheduler_priority; - } - - return status; -} - // = assigns priorities and sub-priorities to the sorted schedule, - // according to the strategy's priority comparison operator. - -ACE_DynScheduler::status_t -ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches, - u_int count) -{ - // start subpriority levels and element counts at 1, set level values in - // the first entry, increment the static subpriority level, - Sub_Priority dynamic_subpriority_level = 0; - Sub_Priority static_subpriority_level = 0; - u_int dynamic_subpriority_elements = 1; - u_int static_subpriority_elements = 1; - dispatches [0]->dynamic_subpriority (dynamic_subpriority_level); - dispatches [0]->static_subpriority (static_subpriority_level); - - // set dynamic and static subpriority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [0]->task_entry ().rt_info ()->dynamic_subpriority = - dynamic_subpriority_level; - dispatches [0]->task_entry ().rt_info ()->static_subpriority = - static_subpriority_level; - - // advance the static subpriority level - static_subpriority_level++; - - u_int i,j; - // traverse ordered dispatch entry array, assigning priority - // (array is sorted from highest to lowest priority) - for (i = 1; i < count; ++i) - { - switch (strategy_.priority_comp (*(dispatches [i-1]), - *(dispatches [i]))) - { - case -1: // the current entry is at lower priority than the previous - { - // fill in the high to low dynamic subpriority values by subtracting - // the previously assigned subpriority value of each of element in the - // current priority level from the value of last subpriority level - for (j = 1; j <= dynamic_subpriority_elements; ++j) - { - dispatches [i - j]-> - dynamic_subpriority (dynamic_subpriority_level - - dispatches [i - j]-> dynamic_subpriority ()); - - // set dynamic subpriority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i - j]->task_entry ().rt_info ()->dynamic_subpriority = - dispatches [i - j]-> dynamic_subpriority (); - } - for (j = 1; j <= static_subpriority_elements; ++j) - { - dispatches [i - j]-> - static_subpriority (static_subpriority_level - - dispatches [i - j]-> static_subpriority () - 1); - - // set static subpriority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i - j]->task_entry ().rt_info ()->static_subpriority = - dispatches [i - j]-> static_subpriority (); - } - - // reset the subpriority counters, set these values in the - // current entry, and increment the static subpriority counter - dynamic_subpriority_elements = 1; - static_subpriority_elements = 1; - dynamic_subpriority_level = 0; - static_subpriority_level = 0; - dispatches [i]->dynamic_subpriority (dynamic_subpriority_level); - dispatches [i]->static_subpriority (static_subpriority_level); - - // set dynamic and static subpriority of underlying RT_Info - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i]->task_entry ().rt_info ()->dynamic_subpriority = - dynamic_subpriority_level; - dispatches [i]->task_entry ().rt_info ()->static_subpriority = - static_subpriority_level; - - // advance the static subpriority level - static_subpriority_level++; - - break; - } - - case 0: // still at the same priority level - - // compare the dynamic subpriorities - switch (strategy_.dynamic_subpriority_comp (*(dispatches[i-1]), - *(dispatches[i]))) - { - case -1: // the current entry is at lower dynamic subpriority - - // increment dynamic subpriority level - ++dynamic_subpriority_level; - - // update the static subpriority as well: this avoids problems - // with non-determinism if due to run-time conditions, two - // dispatches line up with identical dynamic subpriority that - // were considered different with respect to the critical instant - dispatches [i]->static_subpriority (static_subpriority_level); - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i]->task_entry ().rt_info ()->static_subpriority = - static_subpriority_level; - static_subpriority_level++; - static_subpriority_elements++; - - break; - - case 0: // still at the same dynamic subpriority level - - { - switch (strategy_.static_subpriority_comp (*(dispatches[i-1]), - *(dispatches[i]))) - { - case -1: - case 0: - - // assign and then increment the static subpriority: even if - // still at the same dynamic or static subpriority level as - // far as the scheduling strategy is concerned, assign a new - // one anyway, to give a completely deterministic schedule - // even if the dynamic subpriorities happen to align due to - // run-time variation - dispatches [i]->static_subpriority (static_subpriority_level); - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i]->task_entry ().rt_info ()->static_subpriority = - static_subpriority_level; - static_subpriority_level++; - static_subpriority_elements++; - break; - - default: // should never reach here: something *bad* has happened - - ACE_ERROR_RETURN (( - LM_ERROR, - "Static subpriority assignment failure: tasks" - " \"%s\" and \"%s\" are out of order.\n", - dispatches [i-1]->task_entry ().rt_info ()->entry_point.in (), - dispatches [i]->task_entry ().rt_info ()->entry_point.in ()), - ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING); - } - - break; - } - - default: // should never reach here: something *bad* has happened - - ACE_ERROR_RETURN (( - LM_ERROR, - "Dynamic subpriority assignment failure: tasks" - " \"%s\" and \"%s\" are out of order.\n", - dispatches [i-1]->task_entry ().rt_info ()->entry_point.in (), - dispatches [i]->task_entry ().rt_info ()->entry_point.in ()), - ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING); - } - - dispatches [i]->dynamic_subpriority (dynamic_subpriority_level); - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i]->task_entry ().rt_info ()->dynamic_subpriority = - dynamic_subpriority_level; - - dynamic_subpriority_elements++; - - break; - - default: // should never reach here: something *bad* has happened - - ACE_ERROR_RETURN (( - LM_ERROR, - "Priority assignment failure: tasks" - " \"%s\" and \"%s\" are out of order.\n", - dispatches [i-1]->task_entry ().rt_info ()->entry_point.in (), - dispatches [i]->task_entry ().rt_info ()->entry_point.in ()), - ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING); - } - } - - // fill in the high to low subpriority values for the last priority - // level by subtracting the previously assigned subpriorities from - // the total number of subpriorities - for (j = 1; j <= dynamic_subpriority_elements; ++j) - { - dispatches [i - j]-> - dynamic_subpriority (dynamic_subpriority_level - - dispatches [i - j]->dynamic_subpriority ()); - - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i - j]->task_entry ().rt_info ()->dynamic_subpriority = - dispatches [i - j]->dynamic_subpriority (); - } - for (j = 1; j <= static_subpriority_elements; ++j) - { - dispatches [i - j]-> - static_subpriority (static_subpriority_level - - dispatches [i - j]->static_subpriority () - 1); - - // TBD - assign values into a map of priorities and RT_Infos: - // an RT_Info can be dispatched at multiple priorities - dispatches [i - j]->task_entry ().rt_info ()->static_subpriority = - dispatches [i - j]->static_subpriority (); - } - - return ACE_DynScheduler::SUCCEEDED; -} - - -ACE_DynScheduler::Preemption_Priority -ACE_Strategy_Scheduler::minimum_critical_priority () -{ - return strategy_.minimum_critical_priority (); -} - // = determine the minimum critical priority number - - -ACE_DynScheduler::status_t -ACE_Strategy_Scheduler::schedule_timeline_entry ( - Dispatch_Entry &dispatch_entry, - ACE_Unbounded_Queue <Dispatch_Entry *> &reschedule_queue) -{ - status_t status = SUCCEEDED; - - // timeline entries cover the execution time of the dispatch - CORBA::ULong remaining_time = - dispatch_entry.task_entry().rt_info ()->worst_case_execution_time.low; - - // initialize last stop time to arrival time of the dispatch - CORBA::ULong last_stop = dispatch_entry.arrival ().low; - - TimeLine_Entry *last_entry = 0; - TimeLine_Entry *current_entry = 0; - ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); - for (iter.first (); (remaining_time > 0) && (iter.done () == 0); - iter.advance ()) - { - TimeLine_Entry_Link *link; - if ((iter.next (link) == 0) || (! link)) - { - return ST_BAD_INTERNAL_POINTER; - } - - // for each entry already in the timeline that is the first one for a - // dispatch, and has lower dynamic subpriority and does not have greater - // static priority, and starts in the period in which the new entry would - // execute, then advance the iterator to the next timeline entry - // having a different dispatch entry (if there is such), add its dispatch - // entry to the reschedule set, remove all TimeLine_Entry_Links that - // correspond to that dispatch entry, and delete all its TimeLine_Entry - // objects as well. NOTE: 0 is highest priority, 1 next, etc. - while ((iter.done () == 0) && - (link->entry ().start() < last_stop + remaining_time) && - (link->entry ().start() >= last_stop) && - (link->entry ().prev () == 0) && - (link->entry ().dispatch_entry().priority () >= - dispatch_entry.priority ()) && - (strategy_.dynamic_subpriority (dispatch_entry, link->entry ().start ()) > - strategy_.dynamic_subpriority (link->entry ().dispatch_entry (), - link->entry ().start ()))) - { - // point to the dispatch entry whose timeline entries will be removed and - // rescheduled, and to the timeline entry heading the bilinked list of - // timeline entries to be removed - Dispatch_Entry *removed_dispatch_entry - = &(link->entry ().dispatch_entry()); - TimeLine_Entry *remove_entry = & (link->entry ()); - - // put the dispatch entry into the set of entries that will be - // rescheduled at the end of this method (tail recursively) - reschedule_queue.enqueue_tail (removed_dispatch_entry); - - // advance the iterator to the next timeline entry (if there is one) - // that is not for the dispatch entry being removed - while (iter.done () == 0) - { - // point to the current link - if ((iter.next (link) == 0) || (! link)) - { - return ST_BAD_INTERNAL_POINTER; - } - - // advance until a different dispatch entry is found, - // or we run off the end of the timeline - if (&(link->entry ().dispatch_entry ()) == - removed_dispatch_entry) - { - iter.advance (); - } - else - { - break; - } - } - - // remove entries corresponding to the rescheduled - // dispatch from the timeline and destroy them - TimeLine_Entry *next_remove_entry = 0; - while (remove_entry) - { - next_remove_entry = remove_entry->next (); - - timeline_->remove (TimeLine_Entry_Link (*remove_entry)); - delete remove_entry; - - remove_entry = next_remove_entry; - } - } - - // exit the outer loop if there are no more entries in the timeline - if (iter.done () != 0) - { - break; - } - - // if there's room, schedule a new timeline entry for the dispatch - if (link->entry ().start() > last_stop) - { - ACE_NEW_RETURN ( - current_entry, - TimeLine_Entry ( - dispatch_entry, - last_stop, - (((remaining_time + last_stop) < link->entry ().start()) - ? (remaining_time + last_stop) : link->entry ().start()), - dispatch_entry.arrival ().low, - dispatch_entry.deadline ().low, - (TimeLine_Entry *) 0, last_entry), - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // patch up the pointers within the list of entries for this dispatch - if (last_entry) - { - last_entry->next (current_entry); - } - last_entry = current_entry; - - timeline_->insert(TimeLine_Entry_Link(*current_entry)); - - // update the remaining time and last stop values - remaining_time -= ((remaining_time < (link->entry ().start() - last_stop)) - ? remaining_time : (link->entry ().start() - last_stop)); - } - - // update the last stop time - if (last_stop < link->entry ().stop ()) - { - last_stop = link->entry ().stop (); - } - } - - // if there is still dispatch time remaining, and we've - // reached the end of the list, insert what's left - if (remaining_time > 0) - { - ACE_NEW_RETURN ( - current_entry, - TimeLine_Entry ( - dispatch_entry, - last_stop, - remaining_time + last_stop, - dispatch_entry.arrival ().low, - dispatch_entry.deadline ().low, - 0, last_entry), - ST_VIRTUAL_MEMORY_EXHAUSTED); - - // patch up the pointers within the list of entries for this dispatch - if (last_entry) - { - last_entry->next (current_entry); - } - - timeline_->insert(TimeLine_Entry_Link(*current_entry)); - } - - return status; -} - - - -//////////////////////////////////////////////////////////////////// -// class template ACE_Strategy_Scheduler_Factory member functions // -//////////////////////////////////////////////////////////////////// - -template <class STRATEGY> ACE_Strategy_Scheduler * -ACE_Strategy_Scheduler_Factory<STRATEGY>::create (RtecScheduler::Preemption_Priority minimum_critical_priority) -{ - ACE_Strategy_Scheduler *the_scheduler = 0; - STRATEGY *the_strategy; - - ACE_NEW_RETURN(the_strategy, STRATEGY(minimum_critical_priority), 0); - - ACE_NEW_RETURN (the_scheduler, ACE_Strategy_Scheduler (*the_strategy), 0); - - return the_scheduler; -} - // construct and return a scheduler strategized with - // an instance of the the parameterized strategy type - - - -///////////////////////////////////////////////////////////////// -// abstract base class ACE_Scheduler_Strategy member functions // -///////////////////////////////////////////////////////////////// - - -ACE_Scheduler_Strategy::ACE_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - : minimum_critical_priority_ (minimum_critical_priority) -{ -} - // ctor - -int -ACE_Scheduler_Strategy::sort_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order first by the priority ordering - int result = priority_comp (first_entry, second_entry); - - // within same priority, order by dynamic subpriority - if (result == 0) - { - result = dynamic_subpriority_comp (first_entry, second_entry); - } - - // if same dynamic subpriority, order by static subpriority - if (result == 0) - { - result = static_subpriority_comp (first_entry, second_entry); - } - - return result; -} - // = comparison of two dispatch entries using the specific priority, dynamic - // subpriority, and static subpriority method definitions provided by - // the derived strategy class to produce the strategy specific sort - // ordering: returns -1 if the first Dispatch_Entry is greater in the order, - // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in - // the order - - -int -ACE_Scheduler_Strategy::static_subpriority_comp ( - const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order first by importance assigned to underlying RT_Info (descending) - if (first_entry.task_entry ().rt_info ()->importance > - second_entry.task_entry ().rt_info ()->importance) - { - return -1; - } - else if (first_entry.task_entry ().rt_info ()->importance < - second_entry.task_entry ().rt_info ()->importance) - { - return 1; - } - else - { - // order last by the topological sort finishing time (ascending) - if (first_entry.task_entry ().finished () < - second_entry.task_entry ().finished ()) - { - return -1; - } - else if (first_entry.task_entry ().finished () > - second_entry.task_entry ().finished ()) - { - return 1; - } - else - { - return 0; - } - } -} - -ACE_DynScheduler::Preemption_Priority -ACE_Scheduler_Strategy::minimum_critical_priority () -{ - return 0; -} - // = returns 0 for minimum critical priority number - - -///////////////////////////////////////////////////////////////////////// -// class ACE_MUF_Scheduler_Strategy static data member initializations // -///////////////////////////////////////////////////////////////////////// - -ACE_MUF_Scheduler_Strategy * ACE_MUF_Scheduler_Strategy::instance_ = 0; - -/////////////////////////////////////////////////////// -// class ACE_MUF_Scheduler_Strategy member functions // -/////////////////////////////////////////////////////// - -ACE_MUF_Scheduler_Strategy * -ACE_MUF_Scheduler_Strategy::instance () -{ - if (0 == ACE_MUF_Scheduler_Strategy::instance_) - { - ACE_NEW_RETURN (ACE_MUF_Scheduler_Strategy::instance_, - ACE_MUF_Scheduler_Strategy, 0); - } - - return ACE_MUF_Scheduler_Strategy::instance_; -} - -int -ACE_MUF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order by criticality (descending) - if (first_entry.task_entry ().rt_info ()->criticality > - second_entry.task_entry ().rt_info ()->criticality) - { - return -1; - } - else if (first_entry.task_entry ().rt_info ()->criticality < - second_entry.task_entry ().rt_info ()->criticality) - { - return 1; - } - else - { - return 0; // same priority level - } -} - // = comparison of two dispatch entries by maximum criticality: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, or - // 1 if the second Dispatch_Entry is greater in the order. - - -void -ACE_MUF_Scheduler_Strategy::sort (Dispatch_Entry **dispatch_entries, u_int size) -{ - ::qsort ((void *) dispatch_entries, - size, - sizeof (Dispatch_Entry *), - (COMP_FUNC) ACE_MUF_Scheduler_Strategy::sort_function); -} - // = sort the dispatch entry pointer array in descending urgency order - - -ACE_MUF_Scheduler_Strategy::ACE_MUF_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - :ACE_Scheduler_Strategy (minimum_critical_priority) -{ -} - // = default ctor - -ACE_MUF_Scheduler_Strategy::~ACE_MUF_Scheduler_Strategy () -{ -} - // = virtual dtor - -long -ACE_MUF_Scheduler_Strategy::dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) -{ - long laxity = - entry.deadline ().low - current_time - - entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - return (laxity > 0) ? LONG_MAX - laxity : laxity; -} - // = returns a dynamic subpriority value for the given entry and the - // current time: if the operation has non-negative laxity, then the - // value is positive, and a lower laxity gives a higher dynamic - // subpriority; if the operation has negative laxity, the value - // is the (negative) laxity value - - -int -ACE_MUF_Scheduler_Strategy::dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order by descending dynamic priority according to ascending laxity - u_long laxity1 = - first_entry.deadline ().low - first_entry.arrival ().low - - first_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - u_long laxity2 = - second_entry.deadline ().low - first_entry.arrival ().low - - second_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - - if (laxity1 < laxity2) - { - return -1; - } - else if (laxity1 > laxity2) - { - return 1; - } - else - { - return 0; - } -} - // = orders of two dispatch entries by ascending laxity: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // 1 if the second Dispatch_Entry is greater in the order. - - -int -ACE_MUF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) -{ - return ACE_MUF_Scheduler_Strategy::instance ()-> - sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), - ** ACE_static_cast (Dispatch_Entry **, arg2)); -} - // comparison function to pass to qsort - -ACE_DynScheduler::Preemption_Priority -ACE_MUF_Scheduler_Strategy::minimum_critical_priority () -{ - return minimum_critical_priority_; -} - // = returns minimum critical priority number - -///////////////////////////////////////////////////////////////////////// -// class ACE_RMS_Scheduler_Strategy static data member initializations // -///////////////////////////////////////////////////////////////////////// - -ACE_RMS_Scheduler_Strategy * ACE_RMS_Scheduler_Strategy::instance_ = 0; - -/////////////////////////////////////////////////////// -// class ACE_RMS_Scheduler_Strategy member functions // -/////////////////////////////////////////////////////// - -ACE_RMS_Scheduler_Strategy * -ACE_RMS_Scheduler_Strategy::instance () -{ - if (0 == ACE_RMS_Scheduler_Strategy::instance_) - { - ACE_NEW_RETURN (ACE_RMS_Scheduler_Strategy::instance_, - ACE_RMS_Scheduler_Strategy, 0); - } - - return ACE_RMS_Scheduler_Strategy::instance_; -} - -int -ACE_RMS_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // compare by decreasing dispatch period - if ((first_entry.deadline ().low - first_entry.arrival ().low) < - (second_entry.deadline ().low - second_entry.arrival ().low)) - { - return -1; - } - else if ((first_entry.deadline ().low - first_entry.arrival ().low) > - (second_entry.deadline ().low - second_entry.arrival ().low)) - { - return 1; - } - else - { - return 0; // same priority level - } -} - // = comparison of two dispatch entries by minimum period: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - -void -ACE_RMS_Scheduler_Strategy::sort ( - Dispatch_Entry **dispatch_entries_, u_int size) -{ - ::qsort ((void *) dispatch_entries_, - size, - sizeof (Dispatch_Entry *), - (COMP_FUNC) ACE_RMS_Scheduler_Strategy::sort_function); -} - // = sort the dispatch entry pointer array in descending RMS (rate) order - -ACE_RMS_Scheduler_Strategy::ACE_RMS_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - :ACE_Scheduler_Strategy (minimum_critical_priority) -{ -} - // = default ctor - -ACE_RMS_Scheduler_Strategy::~ACE_RMS_Scheduler_Strategy () -{ -} - // = virtual dtor - -long -ACE_RMS_Scheduler_Strategy::dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) -{ - return 0; -} - // = all entries have the same dynamic subpriority value - -int -ACE_RMS_Scheduler_Strategy::dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - return 0; -} - // = all tasks in a given priority level have the same dynamic - // subpriority under RMS - - -int -ACE_RMS_Scheduler_Strategy::sort_function (void *arg1, void *arg2) -{ - return ACE_RMS_Scheduler_Strategy::instance ()-> - sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), - ** ACE_static_cast (Dispatch_Entry **, arg2)); -} - // comparison function to pass to qsort - - -ACE_DynScheduler::Preemption_Priority -ACE_RMS_Scheduler_Strategy::minimum_critical_priority () -{ - return minimum_critical_priority_; -} - // = returns minimum critical priority number - -///////////////////////////////////////////////////////////////////////// -// class ACE_MLF_Scheduler_Strategy static data member initializations // -///////////////////////////////////////////////////////////////////////// - -ACE_MLF_Scheduler_Strategy * ACE_MLF_Scheduler_Strategy::instance_ = 0; - -/////////////////////////////////////////////////////// -// class ACE_MLF_Scheduler_Strategy member functions // -/////////////////////////////////////////////////////// - -ACE_MLF_Scheduler_Strategy * -ACE_MLF_Scheduler_Strategy::instance () -{ - if (0 == ACE_MLF_Scheduler_Strategy::instance_) - { - ACE_NEW_RETURN (ACE_MLF_Scheduler_Strategy::instance_, - ACE_MLF_Scheduler_Strategy, 0); - } - - return ACE_MLF_Scheduler_Strategy::instance_; -} - -int -ACE_MLF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - return 0; -} - // = just returns 0, as all dispatch entries are of equivalent priority under MLF. - -void -ACE_MLF_Scheduler_Strategy::sort ( - Dispatch_Entry **dispatch_entries_, u_int size) -{ - ::qsort ((void *) dispatch_entries_, - size, - sizeof (Dispatch_Entry *), - (COMP_FUNC) ACE_MLF_Scheduler_Strategy::sort_function); -} - // = sort the dispatch entry pointer array in ascending laxity order - - -ACE_MLF_Scheduler_Strategy::ACE_MLF_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - :ACE_Scheduler_Strategy (0) -{ -} - // = default ctor - -ACE_MLF_Scheduler_Strategy::~ACE_MLF_Scheduler_Strategy () -{ -} - // = virtual dtor - - -long -ACE_MLF_Scheduler_Strategy::dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) -{ - long laxity = - entry.deadline ().low - current_time - - entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - return (laxity > 0) ? LONG_MAX - laxity : laxity; -} - // = returns a dynamic subpriority value for the given entry and the - // current time relative to its arrival - -int -ACE_MLF_Scheduler_Strategy::dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order by laxity (ascending) - // order by descending dynamic priority according to ascending laxity - u_long laxity1 = - first_entry.deadline ().low - first_entry.arrival ().low - - first_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - u_long laxity2 = - second_entry.deadline ().low - first_entry.arrival ().low - - second_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - if (laxity1 < laxity2) - { - return -1; - } - else if (laxity1 > laxity2) - { - return 1; - } - else - { - return 0; - } -} - // = orders two dispatch entries by ascending laxity: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - - -int -ACE_MLF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) -{ - return ACE_MLF_Scheduler_Strategy::instance ()-> - sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), - ** ACE_static_cast (Dispatch_Entry **, arg2)); -} - // comparison function to pass to qsort - - -///////////////////////////////////////////////////////////////////////// -// class ACE_EDF_Scheduler_Strategy static data member initializations // -///////////////////////////////////////////////////////////////////////// - -ACE_EDF_Scheduler_Strategy * ACE_EDF_Scheduler_Strategy::instance_ = 0; - -/////////////////////////////////////////////////////// -// class ACE_EDF_Scheduler_Strategy member functions // -/////////////////////////////////////////////////////// - -ACE_EDF_Scheduler_Strategy * -ACE_EDF_Scheduler_Strategy::instance () -{ - if (0 == ACE_EDF_Scheduler_Strategy::instance_) - { - ACE_NEW_RETURN (ACE_EDF_Scheduler_Strategy::instance_, - ACE_EDF_Scheduler_Strategy, 0); - } - - return ACE_EDF_Scheduler_Strategy::instance_; -} - - -int -ACE_EDF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - return 0; -} - // = just returns 0, as all dispatch entries are of equivalent priority under EDF. - -void -ACE_EDF_Scheduler_Strategy::sort ( - Dispatch_Entry **dispatch_entries_, u_int size) -{ - ::qsort ((void *) dispatch_entries_, - size, - sizeof (Dispatch_Entry *), - (COMP_FUNC) ACE_EDF_Scheduler_Strategy::sort_function); -} - // = sort the dispatch entry pointer array in ascending deadline (period) order - - -ACE_EDF_Scheduler_Strategy::ACE_EDF_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - :ACE_Scheduler_Strategy (0) -{ -} - // = default ctor - -ACE_EDF_Scheduler_Strategy::~ACE_EDF_Scheduler_Strategy () -{ -} - // = virtual dtor - -long -ACE_EDF_Scheduler_Strategy::dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) -{ - long time_to_deadline = entry.deadline ().low - current_time; - return (time_to_deadline > 0) - ? LONG_MAX - time_to_deadline : time_to_deadline; -} - // = returns a dynamic subpriority value for the given entry and the - // current time relative to its arrival - -int -ACE_EDF_Scheduler_Strategy::dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // order by dispatchable interval (ascending) - if (first_entry.deadline ().low - first_entry.arrival ().low < - second_entry.deadline ().low - first_entry.arrival ().low) - { - return -1; - } - else if (first_entry.deadline ().low - first_entry.arrival ().low > - second_entry.deadline ().low - first_entry.arrival ().low) - { - return 1; - } - else - { - return 0; - } -} - // = orders two dispatch entries by ascending time to deadline: returns -1 if - // the first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - - -int -ACE_EDF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) -{ - return ACE_EDF_Scheduler_Strategy::instance ()-> - sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), - ** ACE_static_cast (Dispatch_Entry **, arg2)); -} - // comparison function to pass to qsort - -///////////////////////////////////////////////////////////////////////////// -// class ACE_RMS_Dyn_Scheduler_Strategy static data member initializations // -///////////////////////////////////////////////////////////////////////////// - -ACE_RMS_Dyn_Scheduler_Strategy * ACE_RMS_Dyn_Scheduler_Strategy::instance_ = 0; - -/////////////////////////////////////////////////////////// -// class ACE_RMS_Dyn_Scheduler_Strategy member functions // -/////////////////////////////////////////////////////////// - -ACE_RMS_Dyn_Scheduler_Strategy * -ACE_RMS_Dyn_Scheduler_Strategy::instance () -{ - if (0 == ACE_RMS_Dyn_Scheduler_Strategy::instance_) - { - ACE_NEW_RETURN (ACE_RMS_Dyn_Scheduler_Strategy::instance_, - ACE_RMS_Dyn_Scheduler_Strategy, 0); - } - - return ACE_RMS_Dyn_Scheduler_Strategy::instance_; -} - - -int -ACE_RMS_Dyn_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - if ((first_entry.task_entry ().rt_info ()->criticality >= - RtecScheduler::HIGH_CRITICALITY) && - (second_entry.task_entry ().rt_info ()->criticality >= - RtecScheduler::HIGH_CRITICALITY)) - { - // if they're both in the high criticality bracket, - // order by dispatch period as in RMS scheduling - if ((first_entry.deadline ().low - first_entry.arrival ().low) < - (second_entry.deadline ().low - second_entry.arrival ().low)) - { - return -1; - } - else if ((first_entry.deadline ().low - first_entry.arrival ().low) > - (second_entry.deadline ().low - second_entry.arrival ().low)) - { - return 1; - } - - return 0; // same priority level - } - else if ((first_entry.task_entry ().rt_info ()->criticality < - RtecScheduler::HIGH_CRITICALITY) && - (second_entry.task_entry ().rt_info ()->criticality < - RtecScheduler::HIGH_CRITICALITY)) - { - // if they're both in the low criticality bracket, they have the same priority - return 0; - } - - // they're in different criticality brackets: order by criticality (descending) - return (first_entry.task_entry ().rt_info ()->criticality > - second_entry.task_entry ().rt_info ()->criticality) - ? -1 : 1; -} - // = comparison of two dispatch entries by maximum criticality: returns -1 - // if the first Dispatch_Entry is greater in the order, 0 if they're - // equivalent, or 1 if the second Dispatch_Entry is greater in the order. - - -void -ACE_RMS_Dyn_Scheduler_Strategy::sort ( - Dispatch_Entry **dispatch_entries_, u_int size) -{ - ::qsort ((void *) dispatch_entries_, - size, - sizeof (Dispatch_Entry *), - (COMP_FUNC) ACE_RMS_Dyn_Scheduler_Strategy::sort_function); -} - // = sort the dispatch entry pointer array in descending priority order - - -ACE_RMS_Dyn_Scheduler_Strategy::ACE_RMS_Dyn_Scheduler_Strategy ( - ACE_DynScheduler::Preemption_Priority minimum_critical_priority) - :ACE_Scheduler_Strategy (minimum_critical_priority) -{ -} - // = default ctor - -ACE_RMS_Dyn_Scheduler_Strategy::~ACE_RMS_Dyn_Scheduler_Strategy () -{ -} - // = virtual dtor - -long -ACE_RMS_Dyn_Scheduler_Strategy::dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) -{ - if (entry.task_entry ().rt_info ()->criticality < - RtecScheduler::HIGH_CRITICALITY) - { - long laxity = - entry.deadline ().low - current_time - - entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - return (laxity > 0) ? LONG_MAX - laxity : laxity; - } - - return 0; -} - // = returns a dynamic subpriority value for the given entry and the - // current time relative to its arrival - -int -ACE_RMS_Dyn_Scheduler_Strategy::dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) -{ - // if either is in the high criticality bracket, we do not - // distinguish between them on the basis of dynamic subpriority - if ((first_entry.task_entry ().rt_info ()->criticality >= - RtecScheduler::HIGH_CRITICALITY) || - (second_entry.task_entry ().rt_info ()->criticality >= - RtecScheduler::HIGH_CRITICALITY)) - { - // for HIGH_CRITICALITY and VERY_HIGH_CRITICALITY, all - // entries have the same dynamic subpriority as in RMS - return 0; - } - else - { - // for VERY_LOW_CRITICALITY, LOW_CRITICALITY and MEDIUM_CRITICALITY, - // order second by laxity (ascending) - u_long laxity1 = - first_entry.deadline ().low - first_entry.arrival ().low - - first_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - u_long laxity2 = - second_entry.deadline ().low - first_entry.arrival ().low - - second_entry.task_entry ().rt_info ()->worst_case_execution_time.low; - - if (laxity1 < laxity2) - { - return -1; - } - else if (laxity1 > laxity2) - { - return 1; - } - else - { - return 0; - } - } -} - // = comparison of two dispatch entries within the very high and high - // criticality sets by minimum period (RMS) or of two dispatch entries - // within the medium, low, and very low criticality sets by minimum - // laxity: returns -1 if the first Dispatch_Entry is greater in the order, - // 0 if they're equivalent, or 1 if the second Dispatch_Entry is greater - // in the order. - -int -ACE_RMS_Dyn_Scheduler_Strategy::sort_function (void *arg1, void *arg2) -{ - return ACE_RMS_Dyn_Scheduler_Strategy::instance ()-> - sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), - ** ACE_static_cast (Dispatch_Entry **, arg2)); -} - // comparison function to pass to qsort - - -ACE_DynScheduler::Preemption_Priority -ACE_RMS_Dyn_Scheduler_Strategy::minimum_critical_priority () -{ - return minimum_critical_priority_; -} - // = returns 0 for minimum critical priority number - - -///////////////////////////////////////////// -// Runtime Dispatch Subpriority Strategies // -///////////////////////////////////////////// - -ACE_Dispatch_Subpriority_Strategy::ACE_Dispatch_Subpriority_Strategy (long frame_size) - : frame_size_ (frame_size) - , dynamic_max_ (LONG_MAX) - , static_max_ (0) - , static_bits_ (0) -{ - // some platforms don't support floating point numbers, so compute delimiters - // for static and dynamic subpriority representations the long way (once) - long doubler = 1; - while ((dynamic_max_ / 2) > frame_size) - { - dynamic_max_ /= 2; - doubler *= 2; - static_max_ = doubler - 1; - ++static_bits_; - } - - max_time_.set (0, dynamic_max_); - min_time_.set (0, - dynamic_max_ - 1); -} - - -RtecScheduler::Sub_Priority -ACE_Dispatch_Subpriority_Strategy::response_function ( - const ACE_Time_Value &time_metric, - RtecScheduler::Sub_Priority static_subpriority) -{ - RtecScheduler::Sub_Priority dynamic_subpriority; - - if (time_metric < min_time_) - { - dynamic_subpriority = - dynamic_max_ - 1; - static_subpriority = static_max_; - } - else if (time_metric > max_time_) - { - dynamic_subpriority = dynamic_max_; - static_subpriority = static_max_; - } - else - { - dynamic_subpriority = time_metric.usec () + - time_metric.sec () * ACE_ONE_SECOND_IN_USECS; - - if (static_subpriority > static_max_) - { - static_subpriority = static_max_; - } - } - - return (dynamic_subpriority > 0) - ? (LONG_MAX - - (dynamic_subpriority << static_bits_) - - static_subpriority) - : (LONG_MIN + - ((-dynamic_subpriority) << static_bits_) + - static_subpriority); -} - - -ACE_Deadline_Subpriority_Strategy::ACE_Deadline_Subpriority_Strategy (long frame_size) - : ACE_Dispatch_Subpriority_Strategy (frame_size) -{ -} - -RtecScheduler::Sub_Priority -ACE_Deadline_Subpriority_Strategy::runtime_subpriority ( - const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority) -{ - ACE_Time_Value time_to_deadline (deadline_time); - time_to_deadline -= current_time; - - return response_function (time_to_deadline, static_subpriority); -} - -ACE_Laxity_Subpriority_Strategy::ACE_Laxity_Subpriority_Strategy (long frame_size) - : ACE_Dispatch_Subpriority_Strategy (frame_size) -{ -} - -RtecScheduler::Sub_Priority -ACE_Laxity_Subpriority_Strategy::runtime_subpriority ( - const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority) -{ - ACE_Time_Value laxity (deadline_time); - laxity -= current_time; - laxity -= execution_time; - - return response_function (laxity, static_subpriority); -} - -RtecScheduler::Sub_Priority -ACE_Static_Subpriority_Strategy::runtime_subpriority ( - const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority) -{ - // map passed static subpriority directly to dispatch subpriority - return static_subpriority; -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Node<Dispatch_Entry *>; -template class ACE_Unbounded_Set<Dispatch_Entry *>; -template class ACE_Unbounded_Set_Iterator<Dispatch_Entry *>; -template class ACE_Strategy_Scheduler_Factory<ACE_MUF_Scheduler_Strategy>; -template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Scheduler_Strategy>; -template class ACE_Strategy_Scheduler_Factory<ACE_MLF_Scheduler_Strategy>; -template class ACE_Strategy_Scheduler_Factory<ACE_EDF_Scheduler_Strategy>; -template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Dyn_Scheduler_Strategy>; -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Node<Dispatch_Entry *> -#pragma instantiate ACE_Unbounded_Set<Dispatch_Entry *> -#pragma instantiate ACE_Unbounded_Set_Iterator<Dispatch_Entry *> -#pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_MUF_Scheduler_Strategy> -#pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_RMS_Scheduler_Strategy> -#pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_MLF_Scheduler_Strategy> -#pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_EDF_Scheduler_Strategy> -#pragma instantiate ACE_Strategy_Scheduler_Factory<ACE_RMS_Dyn_Scheduler_Strategy> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h deleted file mode 100644 index 60051a4f5a2..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h +++ /dev/null @@ -1,571 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Strategy_Scheduler.h -// -// = CREATION DATE -// 22 December 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#if ! defined (STRATEGY_SCHEDULER_H) -#define STRATEGY_SCHEDULER_H - -#include "DynSched.h" - -// forward declaration of the abstract base class for scheduler strategies -class ACE_Scheduler_Strategy; - -///////////////////////////////// -// Strategized scheduler class // -///////////////////////////////// - -class TAO_ORBSVCS_Export ACE_Strategy_Scheduler : public ACE_DynScheduler - // = TITLE - // ACE_Strategy_Scheduler - // - // = DESCRIPTION - // Strategized scheduler implementation. Provides an implementation - // of all strategy specific scheduling mechanisms, which relies on the - // methods of the associated strategy class. -{ -// public interface -public: - - ACE_Strategy_Scheduler (ACE_Scheduler_Strategy &strategy); - // = strategized ctor - - virtual ~ACE_Strategy_Scheduler (); - // = virtual dtor - - status_t assign_priorities (Dispatch_Entry **dispatches, u_int count); - // = assigns priorities to the sorted dispatch schedule, - // according to the strategy's priority comparison operator. - - status_t assign_subpriorities (Dispatch_Entry **dispatches, u_int count); - // = assigns dynamic and static sub-priorities to the sorted dispatch - // schedule, according to the strategy's subpriority comparisons. - - virtual Preemption_Priority minimum_critical_priority (); - // = determine the minimum critical priority number - -private: - - virtual status_t schedule_timeline_entry (Dispatch_Entry &dispatch_entry, - ACE_Unbounded_Queue <Dispatch_Entry *> - &reschedule_queue); - // = schedules a dispatch entry into the timeline being created - - virtual status_t sort_dispatches (Dispatch_Entry **dispatches, u_int count); - // = sets up the schedule in the order generated by the strategy - - ACE_Scheduler_Strategy &strategy_; - // = strategy for comparison, sorting of dispatch entries - - ACE_UNIMPLEMENTED_FUNC (ACE_Strategy_Scheduler (const ACE_Strategy_Scheduler &)) - ACE_UNIMPLEMENTED_FUNC (ACE_Strategy_Scheduler &operator= ( - const ACE_Strategy_Scheduler &)) -}; - - - -//////////////////////////////////////// -// Factory for strategized schedulers // -//////////////////////////////////////// - -template <class STRATEGY> -class ACE_Strategy_Scheduler_Factory - // = TITLE - // ACE_Strategy_Scheduler_Factory - // - // = DESCRIPTION - // Provides a type parameterized factory method that constructs - // and returns a scheduler that uses the given scheduling strategy -{ -public: - - static ACE_Strategy_Scheduler * create (RtecScheduler::Preemption_Priority minimum_critical_priority); - // construct and return a scheduler strategized with - // an instance of the the parameterized strategy type -}; - - -////////////////////////// -// Scheduler Strategies // -////////////////////////// - -class TAO_ORBSVCS_Export ACE_Scheduler_Strategy - // = TITLE - // ACE_Scheduler_Strategy - // - // = DESCRIPTION - // Abstract Base Class for scheduling strategies: each derived class - // must define an ordering strategy for dispatch entries based on a specific - // scheduling algorithm. -{ -public: - - ACE_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // ctor - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) = 0; - // = comparison of two dispatch entries in strategy specific high to low priority - // ordering: returns -1 if the first Dispatch_Entry is greater in the order, - // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in - // the order - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count) = 0; - // = sort the dispatch entry link pointer array according to - // the specific sort order defined by the strategy - - virtual ACE_DynScheduler::Preemption_Priority minimum_critical_priority (); - // = determine the minimum critical priority number - - virtual int dynamic_subpriority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry) = 0; - // = comparison of two dispatch entries in strategy specific high to low - // dynamic subpriority ordering: returns -1 if the first Dispatch_Entry - // is greater in the order, 0 if they are equivalent, or 1 if the - // second Dispatch_Entry is greater in the order - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time) = 0; - // = returns a dynamic subpriority value - // for the given timeline entry at the current time - - virtual int static_subpriority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = provide a lowest level ordering based first on importance (descending), - // and then on the dependency topological sort finishing time (ascending). - - -protected: - - int sort_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = comparison of two dispatch entries using the specific priority, dynamic - // subpriority, and static subpriority method definitions provided by - // the derived strategy class to produce the strategy specific sort - // ordering: returns -1 if the first Dispatch_Entry is greater in the order, - // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in - // the order. This is an example of the Template Method pattern (and also - // of Pree's Unification Metapattern), in which derived classes provide - // definitions of the methods on which the sort_comp Template Method relies. - - ACE_DynScheduler::Preemption_Priority minimum_critical_priority_; - // = the minimum critical priority number for the strategy -}; - - - -class TAO_ORBSVCS_Export ACE_MUF_Scheduler_Strategy : public ACE_Scheduler_Strategy - // = TITLE - // ACE_MUF_Scheduler_Strategy - // - // = DESCRIPTION - // Defines "schedule" method using Maximum Urgency First - // scheduling algorithm. -{ -public: - - ACE_MUF_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // ctor - - virtual ~ACE_MUF_Scheduler_Strategy (); - // = virtual dtor - - - static ACE_MUF_Scheduler_Strategy *instance (); - // returns an instance of the strategy - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = comparison of two dispatch entries by maximum criticality: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, or - // 1 if the second Dispatch_Entry is greater in the order. - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count); - // = sort the dispatch entry link pointer array in descending urgency order - - virtual ACE_DynScheduler::Preemption_Priority minimum_critical_priority (); - // = determine the minimum critical priority number - -protected: - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time); - // = returns a dynamic subpriority value at the current time for - // the given timeline entry: if the operation has - // non-negative laxity, then the value is positive, and a lower - // laxity gives a higher dynamic subpriority; if the operation - // has negative laxity, the value is the (negative) laxity value - - virtual int dynamic_subpriority_comp ( - const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = orders of two dispatch entries by ascending laxity: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // 1 if the second Dispatch_Entry is greater in the order. - -private: - - static int sort_function (void *arg1, void *arg2); - // comparison function to pass to qsort: calls instance ()->sort_comp (); - - static ACE_MUF_Scheduler_Strategy *instance_; - // instance of the strategy -}; - - -class TAO_ORBSVCS_Export ACE_RMS_Scheduler_Strategy : public ACE_Scheduler_Strategy - // = TITLE - // ACE_RMS_Scheduler_Strategy - // - // = DESCRIPTION - // Defines "schedule" method using Rate Monotonic - // Scheduling algorithm. -{ -public: - - ACE_RMS_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // ctor - - virtual ~ACE_RMS_Scheduler_Strategy (); - // = virtual dtor - - static ACE_RMS_Scheduler_Strategy *instance (); - // returns an instance of the strategy - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = comparison of two dispatch entries by minimum period: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count); - // = sort the dispatch entry link pointer array in descending RMS (rate) order - - virtual ACE_DynScheduler::Preemption_Priority minimum_critical_priority (); - // = determine the minimum critical priority number - -protected: - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time); - // = just returns 0: all operations have - // the same dynamic subpriority value - - virtual int dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = all dispatches in a given priority level have the same dynamic - // subpriority under RMS: just returns 0 - -private: - - static int sort_function (void *arg1, void *arg2); - // comparison function to pass to qsort: calls instance ()->sort_comp (); - - static ACE_RMS_Scheduler_Strategy *instance_; - // instance of the strategy - -}; - - - - - -class TAO_ORBSVCS_Export ACE_MLF_Scheduler_Strategy : public ACE_Scheduler_Strategy - // = TITLE - // ACE_MLF_Scheduler_Strategy - // - // = DESCRIPTION - // Defines "schedule" method using Minimum Laxity First - // scheduling algorithm. -{ -public: - - ACE_MLF_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // = ctor - - virtual ~ACE_MLF_Scheduler_Strategy (); - // = virtual dtor - - static ACE_MLF_Scheduler_Strategy *instance (); - // returns an instance of the strategy - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = just returns 0, as all dispatch entries are of equivalent priority under MLF. - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count); - // = sort the dispatch entry link pointer array in ascending laxity order - -protected: - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time); - // = returns a dynamic subpriority value at the current time for - // the given timeline entry: if the operation has - // non-negative laxity, then the value is positive, and a lower - // laxity gives a higher dynamic subpriority; if the operation - // has negative laxity, the value is the (negative) laxity value - - virtual int dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = orders two dispatch entries by ascending laxity: returns -1 if the - // first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - -private: - - static int sort_function (void *arg1, void *arg2); - // comparison function to pass to qsort: calls instance ()->sort_comp (); - - static ACE_MLF_Scheduler_Strategy *instance_; - // instance of the strategy - -}; - - -class TAO_ORBSVCS_Export ACE_EDF_Scheduler_Strategy : public ACE_Scheduler_Strategy - // = TITLE - // ACE_EDF_Scheduler_Strategy - // - // = DESCRIPTION - // Defines "schedule" method using Earliest Deadline First - // scheduling algorithm. -{ -public: - - ACE_EDF_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // = default ctor - - virtual ~ACE_EDF_Scheduler_Strategy (); - // = virtual dtor - - static ACE_EDF_Scheduler_Strategy *instance (); - // returns an instance of the strategy - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = returns 0, as all dispatch entries are of equivalent priority under EDF. - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count); - // = sort the dispatch entry link pointer array in ascending deadline (period) order - -protected: - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time); - // = returns a dynamic subpriority value at the current time for the - // given timeline entry: if the operation has non-negative - // time to deadline, then value is positive, and a shorter time to - // deadline gives a higher dynamic subpriority; if the operation has a - // negative time to deadline, the value is (negative) time to deadline - - - virtual int dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = orders two dispatch entries by ascending time to deadline: returns -1 if - // the first Dispatch_Entry is greater in the order, 0 if they're equivalent, - // or 1 if the second Dispatch_Entry is greater in the order. - -private: - - static int sort_function (void *arg1, void *arg2); - // comparison function to pass to qsort: calls instance ()->sort_comp (); - - static ACE_EDF_Scheduler_Strategy *instance_; - // instance of the strategy - -}; - - -class TAO_ORBSVCS_Export ACE_RMS_Dyn_Scheduler_Strategy : public ACE_Scheduler_Strategy - // = TITLE - // ACE_RMS_Dyn_Scheduler_Strategy - // - // = DESCRIPTION - // Defines "schedule" method using Rate Monotonic priority assignment for - // the critical set, single priority for the dynamic (non-critical) set. -{ -public: - - ACE_RMS_Dyn_Scheduler_Strategy (ACE_DynScheduler::Preemption_Priority minimum_critical_priority = 0); - // = ctor - - virtual ~ACE_RMS_Dyn_Scheduler_Strategy (); - // = virtual dtor - - static ACE_RMS_Dyn_Scheduler_Strategy *instance (); - // returns an instance of the strategy - - virtual int priority_comp (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = comparison of two dispatch entries by maximum criticality: returns -1 - // if the first Dispatch_Entry is greater in the order, 0 if they're - // equivalent, or 1 if the second Dispatch_Entry is greater in the order. - - virtual void sort (Dispatch_Entry **dispatch_entries, - u_int count); - // = sort the dispatch entry pointer array in descending priority order - - virtual ACE_DynScheduler::Preemption_Priority minimum_critical_priority (); - // = determine the minimum critical priority number - -protected: - - virtual long dynamic_subpriority (Dispatch_Entry &entry, - u_long current_time); - // = returns a dynamic subpriority value at the current time for the - // given timeline entry: if the operation is in the - // critical set, the dynamic subpriority value is always 0; if the - // operation is non-critical and has non-negative laxity, then the - // dynamic subpriority value is positive, and a lower laxity gives a - // higher dynamic subpriority if the operation is non-critical and has - // negative laxity, the value is the (negative) laxity value - - - virtual int dynamic_subpriority_comp - (const Dispatch_Entry &first_entry, - const Dispatch_Entry &second_entry); - // = comparison of two dispatch entries within the very high and high - // criticality sets by minimum period (RMS) or of two dispatch entries - // within the medium, low, and very low criticality sets by minimum - // laxity: returns -1 if the first Dispatch_Entry is greater in the order, - // 0 if they're equivalent, or 1 if the second Dispatch_Entry is greater - // in the order. - -private: - - static int sort_function (void *arg1, void *arg2); - // comparison function to pass to qsort: calls instance ()->sort_comp (); - - static ACE_RMS_Dyn_Scheduler_Strategy *instance_; - // instance of the strategy - -}; - - -///////////////////////////////////////////// -// Runtime Dispatch Subpriority Strategies // -///////////////////////////////////////////// - -class TAO_ORBSVCS_Export ACE_Dispatch_Subpriority_Strategy -{ -public: - - ACE_Dispatch_Subpriority_Strategy (long frame_size = ACE_ONE_SECOND_IN_USECS); - // ctor: frame size is the number of microseconds in a complete - // dispatch frame (defaults to one million = one second). - - virtual RtecScheduler::Sub_Priority - runtime_subpriority (const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority) = 0; - // abstract method to compute the dispatch subpriority for an operation - - virtual RtecScheduler::Sub_Priority - response_function (const ACE_Time_Value &time_metric, - RtecScheduler::Sub_Priority static_subpriority); - // response function for run time subpriority: stepwise linear function that - // gives appoximately the same dispatching behavior as a hyperbolic function, - // but does not require us to use floating point math. - - -protected: - - long frame_size_; - // number of microseconds per scheduling frame - - long dynamic_max_; - // max value that a dynamic priority representation can have - - long static_max_; - // number of bits available for static subpriority representation - - u_int static_bits_; - // number of bits available for static subpriority representation - - ACE_Time_Value max_time_; - // maximum time value that can be represented - - ACE_Time_Value min_time_; - // minimum time value that can be represented - -}; - - -class TAO_ORBSVCS_Export ACE_Deadline_Subpriority_Strategy - : public ACE_Dispatch_Subpriority_Strategy -{ -public: - - ACE_Deadline_Subpriority_Strategy (long frame_size = ACE_ONE_SECOND_IN_USECS); - // ctor: frame size is the number of microseconds in a complete - // dispatch frame (defaults to one million = one second). - - - virtual RtecScheduler::Sub_Priority - runtime_subpriority (const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority); -}; - -class TAO_ORBSVCS_Export ACE_Laxity_Subpriority_Strategy - : public ACE_Dispatch_Subpriority_Strategy -{ -public: - - ACE_Laxity_Subpriority_Strategy (long frame_size = ACE_ONE_SECOND_IN_USECS); - // ctor: frame size is the number of microseconds in a complete - // dispatch frame (defaults to one million = one second). - - - virtual RtecScheduler::Sub_Priority - runtime_subpriority (const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority); -}; - -class TAO_ORBSVCS_Export ACE_Static_Subpriority_Strategy - : public ACE_Dispatch_Subpriority_Strategy -{ -public: - - virtual RtecScheduler::Sub_Priority - runtime_subpriority (const ACE_Time_Value ¤t_time, - const ACE_Time_Value &deadline_time, - const ACE_Time_Value &execution_time, - RtecScheduler::Sub_Priority static_subpriority); -}; - - -#if defined (__ACE_INLINE__) -#include "Strategy_Scheduler.i" -#endif /* __ACE_INLINE__ */ - -#endif /* STRATEGY_SCHEDULER_H */ - -// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i deleted file mode 100644 index c84e9e2da77..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i +++ /dev/null @@ -1,21 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// Strategy_Scheduler.i -// -// = CREATION DATE -// 22 December 1997 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - - -// EOF - |