summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Sched
diff options
context:
space:
mode:
authornobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-05-15 07:48:02 +0000
committernobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-05-15 07:48:02 +0000
commit5d477b4d8152c151940b868790c290f10467b92e (patch)
tree47aaf390a2896d99a518019ee3f00f6c55e2ef73 /TAO/orbsvcs/orbsvcs/Sched
parent438d0c8b9b7b135421c872bd4daea8d5bf017e7e (diff)
downloadATCD-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.cpp371
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h157
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i5
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp1772
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/DynSched.h483
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/DynSched.i111
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp875
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h591
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i402
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp280
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler.h276
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler.i20
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp262
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h129
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i21
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp1419
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h571
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i21
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 &current_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 &current_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 &current_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 &current_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 &current_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 &current_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 &current_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
-