diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Sched/Reconfig_Scheduler_T.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/Reconfig_Scheduler_T.cpp | 1523 |
1 files changed, 0 insertions, 1523 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Reconfig_Scheduler_T.cpp b/TAO/orbsvcs/orbsvcs/Sched/Reconfig_Scheduler_T.cpp deleted file mode 100644 index 2dbb7a440eb..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/Reconfig_Scheduler_T.cpp +++ /dev/null @@ -1,1523 +0,0 @@ -// ============================================================================ -// -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// orbsvcs -// -// = FILENAME -// Reconfig_Scheduler_T.cpp -// -// = AUTHOR -// Chris Gill <cdgill@cs.wustl.edu> -// -// ============================================================================ - -#ifndef TAO_RECONFIG_SCHEDULER_T_C -#define TAO_RECONFIG_SCHEDULER_T_C - -// The templatized method parameters needed by this file are -// hopelessly broken on pre-2.8 versions of g++ -#if (! defined (__GNUC__)) || (__GNUC__ > 2) || \ -(__GNUC__ == 2 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 8) - -#include "Reconfig_Scheduler_T.h" -#include "orbsvcs/Time_Utilities.h" -#include "ace/Auto_Ptr.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#if !defined (__ACE_INLINE__) -#include "Reconfig_Scheduler_T.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Sched, Reconfig_Scheduler_T, "$Id$") - -////////////////////////////////////////////// -// Helper function type definition for sort // -////////////////////////////////////////////// - -// This is awkward, but it makes MSVC++ happy. -extern "C" -{ -typedef int (*COMP_FUNC) (const void*, const void*); -} - - -// Default constructor. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::TAO_Reconfig_Scheduler (int enforce_schedule_stability) - : config_info_count_ (0), - rt_info_count_ (0), - next_handle_ (1), - entry_ptr_array_ (0), - entry_ptr_array_size_ (0), - stability_flags_ (SCHED_NONE_STABLE), - enforce_schedule_stability_ (enforce_schedule_stability), - dependency_count_ (0), - last_scheduled_priority_ (0) -{ -} - -// Constructor. Initialize the scheduler from the POD_Config_Info, POD_RT_Info, -// and POD_Dependency arrays, plus stability flag. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -TAO_Reconfig_Scheduler (int config_count, - ACE_Scheduler_Factory::POD_Config_Info config_infos[], - int rt_info_count, - ACE_Scheduler_Factory::POD_RT_Info rt_infos[], - int dependency_count, - ACE_Scheduler_Factory::POD_Dependency_Info dependency_infos[], - u_long stability_flags, - int enforce_schedule_stability) - : config_info_count_ (0), - rt_info_count_ (0), - next_handle_ (1), - stability_flags_ (SCHED_ALL_STABLE), - enforce_schedule_stability_ (enforce_schedule_stability), - dependency_count_ (0), - last_scheduled_priority_ (0) -{ - // The init method can throw an exception, which must be caught - // *inside* the constructor to be portable between compilers that - // differ in whether they support native C++ exceptions. - ACE_TRY_NEW_ENV - { - this->init (config_count, config_infos, - rt_info_count, rt_infos, - dependency_count, dependency_infos, - stability_flags, ACE_TRY_ENV); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA::SystemException, corba_sysex) - { - ACE_ERROR ((LM_ERROR, "TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, " - "ACE_LOCK>::TAO_Reconfig_Scheduler " - "system exception: cannot init scheduler.\n")); - } - ACE_ENDTRY; -} - - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> int -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -init (int config_count, - ACE_Scheduler_Factory::POD_Config_Info config_info[], - int rt_info_count, - ACE_Scheduler_Factory::POD_RT_Info rt_info[], - int dependency_count, - ACE_Scheduler_Factory::POD_Dependency_Info dependency_info[], - u_long stability_flags, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::DUPLICATE_NAME, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::INTERNAL)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK_RETURN (-1); - - int result = 0; - - // Clear out the previous entries, if any. - this->close (ACE_TRY_ENV); - ACE_CHECK_RETURN (-1); - - // (Re)initialize using the new settings. - - // Add the passed config infos to the scheduler - auto_ptr<RtecScheduler::Config_Info> new_config_info_ptr; - for (this->config_info_count_ = 0; - this->config_info_count_ < config_count; - ++this->config_info_count_) - { - RtecScheduler::Config_Info* new_config_info; - ACE_NEW_THROW_EX (new_config_info, - RtecScheduler::Config_Info, - CORBA::NO_MEMORY ()); - ACE_CHECK_RETURN (-1); - - // Make sure the new config info is cleaned up if we exit abruptly. - ACE_AUTO_PTR_RESET (new_config_info_ptr, new_config_info, RtecScheduler::Config_Info); - - result = config_info_map_.bind (config_info [config_info_count_].preemption_priority, - new_config_info); - switch (result) - { - case -1: - // Something bad but unknown occurred while trying to bind in map. - ACE_THROW_RETURN (RtecScheduler::INTERNAL (), -1); - - case 1: - // Tried to bind an operation that was already in the map. - ACE_THROW_RETURN (RtecScheduler::DUPLICATE_NAME (), -1); - - default: - break; - } - - new_config_info->preemption_priority = - config_info [config_info_count_].preemption_priority; - new_config_info->thread_priority = - config_info [config_info_count_].thread_priority; - new_config_info->dispatching_type = - config_info [config_info_count_].dispatching_type; - - if (new_config_info->preemption_priority > - last_scheduled_priority_) - { - this->last_scheduled_priority_ = - new_config_info->preemption_priority; - } - - // Release the auto_ptr so it does not clean - // up the sucessfully bound config info. - new_config_info_ptr.release (); - } - - // Add RT_Infos to scheduler - RtecScheduler::RT_Info* new_rt_info; - for (int num_rt_infos = 0; num_rt_infos < rt_info_count; ++num_rt_infos) - { - new_rt_info = create_i (rt_info [num_rt_infos].entry_point, - rt_info [num_rt_infos].handle, - ACE_TRY_ENV); - ACE_CHECK_RETURN (-1); - - // Fill in the portions to which the user has access. - set_i (new_rt_info, - RtecScheduler::Criticality_t (rt_info [num_rt_infos].criticality), - rt_info [num_rt_infos].worst_case_execution_time, - rt_info [num_rt_infos].typical_execution_time, - rt_info [num_rt_infos].cached_execution_time, - rt_info [num_rt_infos].period, - RtecScheduler::Importance_t (rt_info [num_rt_infos].importance), - rt_info [num_rt_infos].quantum, - rt_info [num_rt_infos].threads, - RtecScheduler::Info_Type_t (rt_info [num_rt_infos].info_type)); - - // Fill in the scheduler managed portions. - new_rt_info->priority = - rt_info [num_rt_infos].priority; - new_rt_info->preemption_subpriority = - rt_info [num_rt_infos].static_subpriority; - new_rt_info->preemption_priority = - rt_info [num_rt_infos].preemption_priority; - new_rt_info->volatile_token = 0; - - // Add dependencies between RT_Infos to scheduler. - for (this->dependency_count_ = 0; - this->dependency_count_ < dependency_count; - ++this->dependency_count_) - { - add_dependency_i (dependency_info [dependency_count_].info_that_depends, - dependency_info [dependency_count_].info_depended_on, - dependency_info [dependency_count_].number_of_calls, - dependency_info [dependency_count_].dependency_type, - ACE_TRY_ENV); - ACE_CHECK_RETURN (-1); - } - - } - - // Set stability flags after the operations are loaded, as the passed flags - // should be respected as being the stability state of the passed schedule. - this->stability_flags_ = stability_flags; - - return result; -} - -// Closes the scheduler, releasing all current resources. -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::close (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // Unbind and delete each RT_Info in the map. - RtecScheduler::RT_Info *rt_info; - RtecScheduler::handle_t handle; - while (rt_info_map_.current_size () > 0) - { - handle = (*rt_info_map_.begin ()).ext_id_; - if (rt_info_map_.unbind (handle, rt_info) == 0) - { - if (rt_info_tree_.unbind (rt_info->entry_point) == 0) - { - delete rt_info; - } - else - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - } - else - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - } - - // Delete each Config_Info in the map. - RtecScheduler::Preemption_Priority_t config_priority; - RtecScheduler::Config_Info *config_info; - while (config_info_map_.current_size () > 0) - { - config_priority = (*config_info_map_.begin ()).ext_id_; - if (config_info_map_.unbind (config_priority, config_info) == 0) - { - delete config_info; - } - else - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - } - - // Zero out the scheduling entry pointer array but do not deallocate it. - if (entry_ptr_array_size_ > 0) - { - ACE_OS::memset (entry_ptr_array_, 0, - sizeof (TAO_Reconfig_Scheduler_Entry *) * - entry_ptr_array_size_); - } - - - // Finally, reset the entry counts and start over with the lowest - // handle number. - this->config_info_count_ = 0; - this->rt_info_count_ = 0; - this->next_handle_ = 1; -} - -// Create an RT_Info. If it does not exist, a new RT_Info is -// created and inserted into the schedule, and the handle of the new -// RT_Info is returned. If the RT_Info already exists, an exception -// is thrown. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::handle_t -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -create (const char *entry_point, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::DUPLICATE_NAME, - RtecScheduler::INTERNAL, - RtecScheduler::SYNCHRONIZATION_FAILURE)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK_RETURN (0); - - RtecScheduler::handle_t handle = next_handle_; - create_i (entry_point, handle, ACE_TRY_ENV); - ACE_CHECK_RETURN (handle); - - // Set affected stability flags. - this->stability_flags_ |= - SCHED_UTILIZATION_NOT_STABLE | - SCHED_PRIORITY_NOT_STABLE; - - return handle; -} - -// Lookup a handle for an RT_Info, and return its handle, or an error -// value if it's not present. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::handle_t -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -lookup (const char * entry_point, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK_RETURN (0); - - RtecScheduler::handle_t handle; - handle = this->lookup_i (entry_point, ACE_TRY_ENV); - ACE_CHECK_RETURN (handle); - - return handle; -} - - -// Return a pointer to the RT_Info corresponding to the passed handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::RT_Info * -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -get (RtecScheduler::handle_t handle, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK_RETURN (0); - - // Find the RT_Info in the hash map. - RtecScheduler::RT_Info *rt_info = 0; - if (rt_info_map_.find (handle, rt_info) != 0) - { - ACE_THROW_RETURN (RtecScheduler::UNKNOWN_TASK (), 0); - } - - // Allocate a new RT_Info - RtecScheduler::RT_Info* new_info; - ACE_NEW_THROW_EX (new_info, - RtecScheduler::RT_Info, - CORBA::NO_MEMORY ()); - ACE_CHECK_RETURN (0); - - *new_info = *rt_info; - - return new_info; -} - - -// Set characteristics of the RT_Info corresponding to the passed handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -set (RtecScheduler::handle_t handle, - RtecScheduler::Criticality_t criticality, - RtecScheduler::Time time, - RtecScheduler::Time typical_time, - RtecScheduler::Time cached_time, - RtecScheduler::Period_t period, - RtecScheduler::Importance_t importance, - RtecScheduler::Quantum_t quantum, - CORBA::Long threads, - RtecScheduler::Info_Type_t info_type, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::INTERNAL, - RtecScheduler::SYNCHRONIZATION_FAILURE)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // Look up the RT_Info by its handle, throw an exception if it's not there. - RtecScheduler::RT_Info *rt_info_ptr = 0; - if (rt_info_map_.find (handle, rt_info_ptr) != 0) - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - - // Call the internal set method. - this->set_i (rt_info_ptr, criticality, time, typical_time, - cached_time, period, importance, quantum, - threads, info_type); - - // Update stability flags, based on changes to operation characteristics. - - // Reference the associated scheduling entry: the double cast is - // needed to ensure that the size of the pointer and the size of the - // stored magic cookie are the same (see the definition of - // ptr_arith_t in ACE to grok how this works portably). - TAO_Reconfig_Scheduler_Entry *sched_entry_ptr = - ACE_LONGLONG_TO_PTR (TAO_Reconfig_Scheduler_Entry *, - rt_info_ptr->volatile_token); - - if (0 == sched_entry_ptr) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - - // Test the utilization difference between the old and new values. - if ((sched_entry_ptr->orig_rt_info_data ().period != rt_info_ptr->period - && sched_entry_ptr->orig_rt_info_data ().worst_case_execution_time - != rt_info_ptr->worst_case_execution_time)) - { - CORBA::Double orig_time = ACE_static_cast ( - CORBA::Double, - ACE_UINT64_DBLCAST_ADAPTER (sched_entry_ptr-> - orig_rt_info_data (). - worst_case_execution_time)); - - CORBA::Double orig_period = - sched_entry_ptr->orig_rt_info_data ().period; - - CORBA::Double new_time = ACE_static_cast ( - CORBA::Double, - ACE_UINT64_DBLCAST_ADAPTER (rt_info_ptr-> - worst_case_execution_time)); - - CORBA::Double new_period = rt_info_ptr->period; - - if ((orig_time / orig_period) - (new_time / new_period) > DBL_EPSILON - || (orig_time / orig_period) - (new_time / new_period) < DBL_EPSILON) - { - this->stability_flags_ |= SCHED_UTILIZATION_NOT_STABLE; - } - } - - // Test the priority difference between the old and new info. - if (RECONFIG_SCHED_STRATEGY::priority_diff (sched_entry_ptr-> - orig_rt_info_data (), - *rt_info_ptr) != 0) - { - this->stability_flags_ |= SCHED_PRIORITY_NOT_STABLE; - } - - // If the period changed, look up the handle in the calling - // dependency map and see if there is anything there: if so, - // the propagation is unstable. - if (sched_entry_ptr->orig_rt_info_data ().period - != rt_info_ptr->period) - { - // Get the dependency set for the current entry. - RtecScheduler::Dependency_Set *dependency_set = 0; - int result = calling_dependency_set_map_.find (rt_info_ptr->handle, - dependency_set); - if (result == 0 && dependency_set->length () > 0) - { - this->stability_flags_ |= SCHED_PROPAGATION_NOT_STABLE; - } - } - - // Update the stored operation characteristics values in the scheduling entry - sched_entry_ptr->orig_rt_info_data (*rt_info_ptr); -} - - -// Returns the priority and subpriority values assigned to an RT_Info, -// based on its handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -priority (RtecScheduler::handle_t handle, - RtecScheduler::OS_Priority& o_priority, - RtecScheduler::Preemption_Subpriority_t& subpriority, - RtecScheduler::Preemption_Priority_t& p_priority, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::NOT_SCHEDULED)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // Check stability flags. - if ((this->stability_flags_ & SCHED_PRIORITY_NOT_STABLE) - && this->enforce_schedule_stability_) - { - ACE_THROW (RtecScheduler::NOT_SCHEDULED ()); - } - - RtecScheduler::RT_Info *rt_info = 0; - if (rt_info_map_.find (handle, rt_info) != 0) - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - - o_priority = rt_info->priority; - subpriority = rt_info->preemption_subpriority; - p_priority = rt_info->preemption_priority; -} - - -// Returns the priority and subpriority values assigned to an RT_Info, -// based on its entry point name. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -entry_point_priority (const char * entry_point, - RtecScheduler::OS_Priority& priority, - RtecScheduler::Preemption_Subpriority_t& subpriority, - RtecScheduler::Preemption_Priority_t& p_priority, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::NOT_SCHEDULED)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - RtecScheduler::handle_t handle = - this->lookup_i (entry_point, ACE_TRY_ENV); - ACE_CHECK; - - this->priority_i (handle, - priority, - subpriority, - p_priority, - ACE_TRY_ENV); - ACE_CHECK; -} - - -// This method registers a dependency between two RT_Infos. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -add_dependency (RtecScheduler::handle_t handle /* RT_Info that has the dependency */, - RtecScheduler::handle_t dependency /* RT_Info on which it depends */, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type_t dependency_type, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::UNKNOWN_TASK)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // Delegate to the internal method. - add_dependency_i (handle, dependency, number_of_calls, - dependency_type, ACE_TRY_ENV); - ACE_CHECK; - - // Since the call graph topology has changed, set *all* - // stability flags before incrementing the dependency count. - this->stability_flags_ |= SCHED_UTILIZATION_NOT_STABLE; - ++dependency_count_; -} - - -// If information has been added or changed since the last stable -// schedule was computed, this method causes scheduling information -// to be computed for all registered RT_Infos. If the schedule is -// already stable, this is a no-op - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -compute_scheduling (CORBA::Long minimum_priority, - CORBA::Long maximum_priority, - RtecScheduler::RT_Info_Set_out infos, - RtecScheduler::Config_Info_Set_out configs, - RtecScheduler::Scheduling_Anomaly_Set_out anomalies, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UTILIZATION_BOUND_EXCEEDED, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::INSUFFICIENT_THREAD_PRIORITY_LEVELS, - RtecScheduler::TASK_COUNT_MISMATCH, - RtecScheduler::INTERNAL, - RtecScheduler::DUPLICATE_NAME)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // @@ TO DO - use these to establish the bounds of priority assignment. - ACE_UNUSED_ARG (minimum_priority); - ACE_UNUSED_ARG (maximum_priority); - - // If everything is already up to date, we're done. - if (SCHED_ALL_STABLE == stability_flags_) - { - return; - } - - // @@ TO DO - use try/catch blocks to catch exceptions and add anomalies - // to scheduling anomaly set, and then perhaps rethrow) - - if (this->stability_flags_ & SCHED_PROPAGATION_NOT_STABLE) - { - // Traverse dependency graph, assigning a topological ordering and identifying threads. - dfs_traverse_i (ACE_TRY_ENV); - ACE_CHECK; - - // Sort an array of RT_info handles in topological order, check - // for loops using the strongly connected components algorithm. - detect_cycles_i (ACE_TRY_ENV); - ACE_CHECK; - - // Propagate effective execution time and period, set total frame size. - propagate_characteristics_i (ACE_TRY_ENV); - ACE_CHECK; - } - - if (this->stability_flags_ & SCHED_PRIORITY_NOT_STABLE) - { - // Sort operations by urgency (done by strategy), then - // assign priorities and subpriorities in one pass. - // Sets last scheduled priority. - assign_priorities_i (ACE_TRY_ENV); - ACE_CHECK; - } - - if (this->stability_flags_ & SCHED_UTILIZATION_NOT_STABLE) - { - // Compute utilization, set last feasible priority. - compute_utilization_i (ACE_TRY_ENV); - ACE_CHECK; - } - - // @@ TODO: record any scheduling anomalies in a set within the scheduler, - // storing the maximum severity level recorded so far. - if (anomalies.ptr () == 0) - { - ACE_NEW_THROW_EX (anomalies, - RtecScheduler::Scheduling_Anomaly_Set (0), - CORBA::NO_MEMORY ()); - ACE_CHECK; - } - - // return the set of scheduled RT_Infos - if (infos.ptr () == 0) - { - ACE_NEW_THROW_EX (infos, - RtecScheduler::RT_Info_Set (this->rt_info_count_), - CORBA::NO_MEMORY ()); - ACE_CHECK; - } - infos->length (this->rt_info_count_); - RtecScheduler::RT_Info* rt_info = 0; - for (ACE_TYPENAME RT_INFO_MAP::iterator info_iter (this->rt_info_map_); - info_iter.done () == 0; - ++info_iter) - { - rt_info = (*info_iter).int_id_; - infos[ACE_static_cast (CORBA::ULong, rt_info->handle - 1)] = *rt_info; - } - - // return the set of scheduled Config_Infos - if (configs.ptr () == 0) - { - ACE_NEW_THROW_EX (configs, - RtecScheduler::Config_Info_Set(this-> - config_info_count_), - CORBA::NO_MEMORY ()); - ACE_CHECK; - } - configs->length (this->config_info_count_); - RtecScheduler::Config_Info* config_info = 0; - for (ACE_TYPENAME CONFIG_INFO_MAP::iterator config_iter (this->config_info_map_); - config_iter.done () == 0; - ++config_iter) - { - config_info = (*config_iter).int_id_; - configs[ACE_static_cast (CORBA::ULong, config_info->preemption_priority)] = *config_info; - } - - ACE_DEBUG ((LM_DEBUG, "Schedule prepared.\n")); - ACE_DEBUG ((LM_DEBUG, "Dumping to stdout.\n")); - ACE_Scheduler_Factory::dump_schedule (*(infos.ptr()), *(configs.ptr()), - *(anomalies.ptr()), 0); - ACE_DEBUG ((LM_DEBUG, "Dump done.\n")); - - // Set stability flags last. - this->stability_flags_ = SCHED_ALL_STABLE; - return; -} - - -// Provides the thread priority and queue type for the given priority -// level. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -dispatch_configuration (RtecScheduler::Preemption_Priority_t p_priority, - RtecScheduler::OS_Priority& t_priority, - RtecScheduler::Dispatching_Type_t & d_type, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::NOT_SCHEDULED, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::UNKNOWN_PRIORITY_LEVEL)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK; - - // Check stability flags - if ((this->stability_flags_ & SCHED_PRIORITY_NOT_STABLE) - && this->enforce_schedule_stability_) - { - ACE_THROW (RtecScheduler::NOT_SCHEDULED ()); - } - - RtecScheduler::Config_Info *config_info; - if (config_info_map_.find (p_priority, config_info) != 0) - { - ACE_THROW (RtecScheduler::UNKNOWN_PRIORITY_LEVEL()); - } - - t_priority = config_info->thread_priority; - d_type = config_info->dispatching_type; -} - - -// Returns the last priority number assigned to an operation in the -// schedule. The number returned is one less than the total number -// of scheduled priorities. All scheduled priorities range from 0 -// to the number returned, inclusive. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::Preemption_Priority_t -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -last_scheduled_priority (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::SYNCHRONIZATION_FAILURE, - RtecScheduler::NOT_SCHEDULED)) -{ - ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_, - RtecScheduler::SYNCHRONIZATION_FAILURE ()); - ACE_CHECK_RETURN (0); - - // Check schedule stability flags. - if ((this->stability_flags_ & SCHED_PRIORITY_NOT_STABLE) - && this->enforce_schedule_stability_) - { - ACE_THROW_RETURN (RtecScheduler::NOT_SCHEDULED (), - (RtecScheduler::Preemption_Priority_t) -1); - } - - return last_scheduled_priority_; -} - -// Internal method to create an RT_Info. If it does not exist, a new RT_Info is -// created and inserted into the schedule, and the handle of the new -// RT_Info is returned. If the RT_Info already exists, an exception -// is thrown. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::RT_Info * -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -create_i (const char *entry_point, - RtecScheduler::handle_t handle, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::DUPLICATE_NAME, - RtecScheduler::INTERNAL)) -{ - RtecScheduler::RT_Info* new_rt_info = 0; - TAO_Reconfig_Scheduler_Entry* new_sched_entry = 0; - int result = 0; - - // Create a new scheduling entry for the RT_Info. - ACE_NEW_THROW_EX (new_rt_info, - RtecScheduler::RT_Info, - CORBA::NO_MEMORY ()); - ACE_CHECK_RETURN (0); - - // Make sure the new scheduling entry is cleaned up if we exit abruptly. - auto_ptr<RtecScheduler::RT_Info> new_rt_info_ptr (new_rt_info); - - // Set some reasonable default values, and store the passed ones. - TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::init_rt_info (*new_rt_info); - new_rt_info->entry_point = CORBA::string_dup(entry_point); - new_rt_info->handle = handle; - - // Bind the new RT_Info to its handle, in the RT_Info map. - result = rt_info_map_.bind (handle, new_rt_info); - switch (result) - { - case -1: - // Something bad but unknown occurred while trying to bind in map. - ACE_THROW_RETURN (RtecScheduler::INTERNAL (), 0); - - case 1: - // Tried to bind an operation that was already in the map. - ACE_THROW_RETURN (RtecScheduler::DUPLICATE_NAME (), 0); - - default: - break; - } - - // Bind the new RT_Info to *its* entry point, in the tree. - result = rt_info_tree_.bind (new_rt_info->entry_point, new_rt_info); - switch (result) - { - case -1: - // Something bad but unknown occurred while trying to bind in tree. - rt_info_map_.unbind (handle); - ACE_THROW_RETURN (RtecScheduler::INTERNAL (), 0); - - case 1: - // Tried to bind an operation that was already in the tree. - rt_info_map_.unbind (handle); - ACE_THROW_RETURN (RtecScheduler::DUPLICATE_NAME (), 0); - - default: - break; - } - - // Create a new scheduling entry for the RT_Info. - ACE_NEW_THROW_EX (new_sched_entry, - TAO_Reconfig_Scheduler_Entry (*new_rt_info), - CORBA::NO_MEMORY ()); - ACE_CHECK_RETURN (0); - - // Make sure the new scheduling entry is cleaned up if we exit abruptly. - auto_ptr<TAO_Reconfig_Scheduler_Entry> new_sched_entry_ptr (new_sched_entry); - - // Make sure there is room in the scheduling entry pointer array: - // expand the array eagerly, to minimize memory allocation overhead - - if (this->entry_ptr_array_size_ <= handle) - { - if (entry_ptr_array_size_ > 0) - { - // Store previous array size. - long new_size = entry_ptr_array_size_; - - // Double the size of the array until sufficient. - do - { - new_size *= 2; - } - while (new_size <= handle); - - // Allocate the new array of the proper size, zero it out. - - TAO_Reconfig_Scheduler_Entry ** new_array; - ACE_NEW_THROW_EX (new_array, - TAO_Reconfig_Scheduler_Entry * [new_size], - CORBA::NO_MEMORY ()); - - ACE_OS::memset (new_array, 0, - sizeof (TAO_Reconfig_Scheduler_Entry *) * - new_size); - - // Copy in the previous array. - ACE_OS::memcpy (new_array, entry_ptr_array_, - sizeof (TAO_Reconfig_Scheduler_Entry *) * - entry_ptr_array_size_); - - // Free the old array and swap to point to the new one. - delete [] entry_ptr_array_; - entry_ptr_array_ = new_array; - entry_ptr_array_size_ = new_size; - } - else - { - // For the first allocation, just start with sufficient space - // for the handle that was given. - ACE_NEW_THROW_EX (entry_ptr_array_, - TAO_Reconfig_Scheduler_Entry * [handle + 1], - CORBA::NO_MEMORY ()); - entry_ptr_array_size_ = handle + 1; - } - } - - // Atore in the scheduling entry pointer array. - entry_ptr_array_ [handle - 1] = new_sched_entry; - - // Store a pointer to the scheduling entry in the scheduling entry - // pointer array and in the RT_Info: the double cast is needed to - // ensure that the size of the pointer and the size of the stored - // magic cookie are the same (see the definition of ptr_arith_t in - // ACE to grok how this works portably). - new_rt_info->volatile_token = - ACE_static_cast (CORBA::ULongLong, - ACE_reinterpret_cast (ptr_arith_t, - new_sched_entry)); - - // Release the auto pointers, so their destruction does not - // remove the new rt_info that is now in the map and tree, - // or the scheduling entry attached to the rt_info. - new_rt_info_ptr.release (); - new_sched_entry_ptr.release (); - - // With everything safely registered in the map and tree, just - // update the next handle and info counter and return the new info. - if (handle >= this->next_handle_) - { - this->next_handle_ = handle + 1; - } - if (handle > this->rt_info_count_) - { - this->rt_info_count_ = handle; - } - - return new_rt_info; -} - - -// Internal method to set characteristics of the passed RT_Info. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -set_i (RtecScheduler::RT_Info *rt_info, - RtecScheduler::Criticality_t criticality, - RtecScheduler::Time time, - RtecScheduler::Time typical_time, - RtecScheduler::Time cached_time, - RtecScheduler::Period_t period, - RtecScheduler::Importance_t importance, - RtecScheduler::Quantum_t quantum, - CORBA::Long threads, - RtecScheduler::Info_Type_t info_type) -{ - 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; -} - - -// Internal method to lookup a handle for an RT_Info, and return its -// handle, or an error value if it's not present. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -RtecScheduler::handle_t -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -lookup_i (const char * entry_point, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)) -{ - RtecScheduler::RT_Info *rt_info = 0; - if (rt_info_tree_.find (entry_point, rt_info) != 0) - { - ACE_THROW_RETURN (RtecScheduler::UNKNOWN_TASK (), 0); - } - - return rt_info->handle; -} - -// Internal method that returns the priority and subpriority values -// assigned to an RT_Info, based on its handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -priority_i (RtecScheduler::handle_t handle, - RtecScheduler::OS_Priority& o_priority, - RtecScheduler::Preemption_Subpriority_t& subpriority, - RtecScheduler::Preemption_Priority_t& p_priority, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK, - RtecScheduler::NOT_SCHEDULED)) -{ - // Check stability flags. - if ((this->stability_flags_ & SCHED_PRIORITY_NOT_STABLE) - && this->enforce_schedule_stability_) - { - ACE_THROW (RtecScheduler::NOT_SCHEDULED ()); - } - - RtecScheduler::RT_Info *rt_info = 0; - if (rt_info_map_.find (handle, rt_info) != 0) - { - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - - o_priority = rt_info->priority; - subpriority = rt_info->preemption_subpriority; - p_priority = rt_info->preemption_priority; -} - - -// This method registers a dependency between two RT_Infos. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -add_dependency_i (RtecScheduler::handle_t handle /* RT_Info that has the dependency */, - RtecScheduler::handle_t dependency /* RT_Info on which it depends */, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type_t dependency_type, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL, - RtecScheduler::UNKNOWN_TASK)) -{ - // All dependencies are mapped by both the calling and called - // operation handles, so that a topological sort can be performed - // once over both one-way and two-way dependencies. The dependency - // specification is in absolute terms, however, so that the calling - // and called handles are reversed for one-way and two way - // dependencies. - - switch (dependency_type) - { - // In a two-way call, the calling operation depends on the - // called operation. - case RtecScheduler::TWO_WAY_CALL: - - // Add the calling dependency map entry - map_dependency_i (handle, // calling handle - dependency, // called handle - calling_dependency_set_map_, // calling map - number_of_calls, - dependency_type, - ACE_TRY_ENV); - ACE_CHECK; - - // Add the called dependency map entry - map_dependency_i (dependency, // called handle - handle, // calling handle - called_dependency_set_map_, // called map - number_of_calls, - dependency_type, - ACE_TRY_ENV); - ACE_CHECK; - - break; - - // In a one-way call, the called operation depends on the - // calling operation. - case RtecScheduler::ONE_WAY_CALL: - - // Add the calling dependency map entry - map_dependency_i (dependency, // calling handle - handle, // called handle - calling_dependency_set_map_, // calling map - number_of_calls, - dependency_type, - ACE_TRY_ENV); - ACE_CHECK; - - // Add the called dependency map entry - map_dependency_i (handle, // called handle - dependency, // calling handle - called_dependency_set_map_, // called map - number_of_calls, - dependency_type, - ACE_TRY_ENV); - ACE_CHECK; - - break; - - default: - - // There should not be any other kinds of dependencies. - ACE_THROW (RtecScheduler::INTERNAL ()); - } - -} - -// This method installs a dependency in a dependency set map. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -map_dependency_i (RtecScheduler::handle_t key, - RtecScheduler::handle_t handle, - ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::DEPENDENCY_SET_MAP &map, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type_t dependency_type, - CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::UNKNOWN_TASK)) -{ - RtecScheduler::Dependency_Set *dependency_set; - - // Look up the dependency set in the passed map - if (map.find (key, dependency_set) != 0) - { - // Create a new one - ACE_NEW_THROW_EX (dependency_set, - RtecScheduler::Dependency_Set, - CORBA::NO_MEMORY ()); - ACE_CHECK; - - if (map.bind (key, dependency_set) != 0) - { - delete dependency_set; - ACE_THROW (RtecScheduler::UNKNOWN_TASK ()); - } - } - - // Insert unconditionally: there can be multiple copies - // of the same dependency, if the user so chooses. - int prev_length = dependency_set->length (); - dependency_set->length (prev_length + 1); - (*dependency_set) [prev_length].rt_info = handle; - (*dependency_set) [prev_length].number_of_calls = number_of_calls; - (*dependency_set) [prev_length].dependency_type = dependency_type; -} - - -// Traverses dependency graph, assigning a topological ordering. -// Resets scheduling entries, do DFS traversal, constructs DFS map. -// Fills in: dfs_status_, discovered_, finished_, is_thread_delineator_, -// has_unresolved_remote_dependencies_, has_unresolved_local_dependencies_, -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -dfs_traverse_i (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL)) -{ - int i; // index into array of scheduling entry pointers - - // Reset registered RT_Infos. - TAO_RSE_Reset_Visitor reset_visitor; - for (i = 0; i < this->rt_info_count_; ++i) - { - if (reset_visitor.visit (* (entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } - - // Traverse registered RT_Infos, assigning DFS start, finish order. - TAO_RSE_DFS_Visitor<RECONFIG_SCHED_STRATEGY, ACE_LOCK> - dfs_visitor (this->calling_dependency_set_map_, - this->rt_info_map_); - for (i = 0; i < this->rt_info_count_; ++i) - { - if (dfs_visitor.visit (* (entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } -} - - - -// Sorts an array of RT_info handles in topological order, then -// checks for loops, marks unresolved remote dependencies. -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -detect_cycles_i (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL, - RtecScheduler::CYCLIC_DEPENDENCIES)) -{ - // Sort the pointers to entries in order of descending forward - // finish times, which produces a topological ordering, with - // callers ahead of called nodes. - ::qsort (ACE_reinterpret_cast (void *, entry_ptr_array_), - this->rt_info_count_, - sizeof (TAO_Reconfig_Scheduler_Entry *), - ACE_reinterpret_cast (COMP_FUNC, - RECONFIG_SCHED_STRATEGY::comp_entry_finish_times)); - - // Traverse entries in reverse topological order, - // looking for strongly connected components (cycles). - TAO_RSE_SCC_Visitor<RECONFIG_SCHED_STRATEGY, ACE_LOCK> - scc_visitor (this->called_dependency_set_map_, - this->rt_info_map_); - for (int i = 0; i < this->rt_info_count_; ++i) - { - // Each new top level entry marks a potential new cycle. - scc_visitor.in_a_cycle (0); - - if (scc_visitor.visit (* (entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } - - // Check whether any cycles were detected. - if (scc_visitor.number_of_cycles () > 0) - { - ACE_THROW (RtecScheduler::CYCLIC_DEPENDENCIES ()); - } -} - -// Propagates effective execution time and period, sets total frame size. -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -propagate_characteristics_i (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL, - RtecScheduler::UNRESOLVED_LOCAL_DEPENDENCIES, - RtecScheduler::THREAD_SPECIFICATION)) -{ - // Traverse entries in topological (DFS finish) order, - // propagating period and effective execution time from - // calling node to called node at each step. - TAO_RSE_Propagation_Visitor<RECONFIG_SCHED_STRATEGY, ACE_LOCK> - prop_visitor (this->calling_dependency_set_map_, - this->rt_info_map_); - for (int i = 0; i < this->rt_info_count_; ++i) - { - if (prop_visitor.visit (* (entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } - - // Check whether any unresolved local dependencies were detected. - if (prop_visitor.unresolved_locals () > 0) - { - ACE_THROW (RtecScheduler::UNRESOLVED_LOCAL_DEPENDENCIES ()); - } - - // Check whether any thread specification errors were detected. - if (prop_visitor.thread_specification_errors () > 0) - { - ACE_THROW (RtecScheduler::THREAD_SPECIFICATION ()); - } -} - -// Sort operations by urgency (done by strategy), then -// assign priorities and subpriorities in one pass. -// Sets last scheduled priority. -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -assign_priorities_i (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL, - RtecScheduler::DUPLICATE_NAME)) -{ - // Sort the pointers to entries in descending order - // of static priority and static subpriority, according - // to our given scheduling strategy. - ::qsort (ACE_reinterpret_cast (void *, entry_ptr_array_), - this->rt_info_count_, - sizeof (TAO_Reconfig_Scheduler_Entry *), - ACE_reinterpret_cast (COMP_FUNC, - RECONFIG_SCHED_STRATEGY::total_priority_comp)); - - // Empty out the previously stored configuration infos, if any. - RtecScheduler::Preemption_Priority_t config_priority; - RtecScheduler::Config_Info *config_info_temp; - while (config_info_map_.current_size () > 0) - { - config_priority = (*config_info_map_.begin ()).ext_id_; - if (config_info_map_.unbind (config_priority, config_info_temp) == 0) - { - delete config_info_temp; - } - else - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } - - // Traverse using a priority assignment visitor, which uses a - // strategy to decide when a new priority or subpriority is reached. - TAO_RSE_Priority_Visitor<RECONFIG_SCHED_STRATEGY> - prio_visitor (this->rt_info_count_, this->entry_ptr_array_); - auto_ptr<RtecScheduler::Config_Info> new_config_info_ptr; - for (int i = 0; i <= this->rt_info_count_; ++i) - { - int result; - - if (i < this->rt_info_count_) - { - // Visit the next entry in the array. - result = prio_visitor.visit (* (this->entry_ptr_array_ [i])); - } - else - { - // Finish up after all enties in the array have been visited. - result = prio_visitor.finish (); - } - - if (result < 0) - { - // Something bad happened with the internal data structures. - ACE_THROW (RtecScheduler::INTERNAL ()); - } - else if (result == 1) - { - RtecScheduler::Config_Info* new_config_info; - ACE_NEW_THROW_EX (new_config_info, - RtecScheduler::Config_Info, - CORBA::NO_MEMORY ()); - ACE_CHECK; - - // Make sure the new config info is cleaned up if we exit abruptly. - ACE_AUTO_PTR_RESET (new_config_info_ptr, new_config_info, RtecScheduler::Config_Info); - - // Have the strategy fill in the new config info for that - // priority level, using the representative scheduling entry. - if (RECONFIG_SCHED_STRATEGY::assign_config (*new_config_info, - *(entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - - if (new_config_info->preemption_priority > - last_scheduled_priority_) - { - this->last_scheduled_priority_ = - new_config_info->preemption_priority; - } - - result = config_info_map_.bind (new_config_info->preemption_priority, - new_config_info); - switch (result) - { - case -1: - // Something bad but unknown occurred while trying to bind in map. - ACE_THROW (RtecScheduler::INTERNAL ()); - - case 1: - // Tried to bind an operation that was already in the map. - ACE_THROW (RtecScheduler::DUPLICATE_NAME ()); - - default: - ++this->config_info_count_; - break; - } - - // Release the auto_ptr so it does not clean - // up the sucessfully bound config info. - new_config_info_ptr.release (); - } - } -} - -// Compute utilization, set last feasible priority. -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>:: -compute_utilization_i (CORBA::Environment &ACE_TRY_ENV) - ACE_THROW_SPEC ((CORBA::SystemException, - RtecScheduler::INTERNAL)) -{ - TAO_RSE_Utilization_Visitor<RECONFIG_SCHED_STRATEGY> util_visitor; - for (int i = 0; i < this->rt_info_count_; ++i) - { - if (util_visitor.visit (* (entry_ptr_array_ [i])) < 0) - { - ACE_THROW (RtecScheduler::INTERNAL ()); - } - } - - // Store the values accumulated by the visitor. - this->noncritical_utilization_ = - util_visitor.noncritical_utilization (); - this->critical_utilization_ = - util_visitor.critical_utilization (); -} - - -// Static helper method to give an RT_Info some reasonable default values. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> void -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::init_rt_info (RtecScheduler::RT_Info &rt_info) - ACE_THROW_SPEC (()) -{ - // Set some reasonable default values. - rt_info.criticality = RtecScheduler::VERY_LOW_CRITICALITY; - rt_info.worst_case_execution_time = 0; - rt_info.typical_execution_time = 0; - rt_info.cached_execution_time = 0; - rt_info.period = 1; - rt_info.importance = RtecScheduler::VERY_LOW_IMPORTANCE; - rt_info.quantum = 0; - rt_info.threads = 0; - rt_info.info_type = RtecScheduler::OPERATION; - rt_info.priority = 0; - rt_info.preemption_subpriority = 0; - rt_info.preemption_priority = 0; - rt_info.volatile_token = 0; -} - - -// Accesses scheduling strategy for the reconfig scheduler. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> RECONFIG_SCHED_STRATEGY & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::sched_strategy () -{ - return this->sched_strategy_; -} - - -// Accesses map for O(1) lookup of Config_Infos by priority level. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::CONFIG_INFO_MAP & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::config_info_map () -{ - return this->config_info_map_; -} - - -// Returns the number of config infos, which is also the number of -// assigned priority levels. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> long -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::config_info_count () -{ - return this->config_info_count_; -} - - -// Accesses map for O(1) lookup of RT_Infos by handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::RT_INFO_MAP & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::rt_info_map () -{ - return this->rt_info_map_; -} - - -// Returns the number of registered RT_Infos. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> long -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::rt_info_count () -{ - return this->rt_info_count_; -} - - -// Accesses tree for O(log n) lookup of RT_Infos by name. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::RT_INFO_TREE & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::rt_info_tree () -{ - return this->rt_info_tree_; -} - - -// Accesses map for O(1) lookup of RT_Info dependency -// set by the caller operation's handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::DEPENDENCY_SET_MAP & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::calling_dependency_set_map () -{ - return this->calling_dependency_set_map_; -} - - -// Accesses map for O(1) lookup of RT_Info dependency -// set by the called operation's handle. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> -ACE_TYPENAME TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::DEPENDENCY_SET_MAP & -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::called_dependency_set_map () -{ - return this->called_dependency_set_map_; -} - - -// Returns the number of dependencies in the dependency lists of all RT_Infos. -// This is used when traversing the dependency graph. - -template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK> int -TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::dependency_count () -{ - return this->dependency_count_; -} - - -#endif /* __GNUC__ */ - -#endif /* TAO_RECONFIG_SCHEDULER_T_C */ |