📄 reconfig_scheduler_t.cpp
字号:
// ============================================================================
//
// Reconfig_Scheduler_T.cpp,v 1.34 2003/08/26 18:36:22 venkita Exp
//
// ============================================================================
//
// = 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
#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__ */
//#ifdef _DEBUG
//#define SCHEDULER_LOGGING 1
//#endif
ACE_RCSID(Sched, Reconfig_Scheduler_T, "Reconfig_Scheduler_T.cpp,v 1.34 2003/08/26 18:36:22 venkita Exp")
//////////////////////////////////////////////
// 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,
const CORBA::Double & critical_utilization_threshold,
const CORBA::Double & noncritical_utilization_threshold)
: config_info_count_ (0),
rt_info_count_ (0),
rt_info_tuple_count_ (0),
next_handle_ (1),
entry_ptr_array_ (0),
entry_ptr_array_size_ (0),
tuple_ptr_array_ (0),
tuple_ptr_array_size_ (0),
stability_flags_ (SCHED_NONE_STABLE),
enforce_schedule_stability_ (enforce_schedule_stability),
dependency_count_ (0),
last_scheduled_priority_ (0),
noncritical_utilization_ (0.0),
critical_utilization_ (0.0),
noncritical_utilization_threshold_ (noncritical_utilization_threshold),
critical_utilization_threshold_ (critical_utilization_threshold)
{
#if defined (SCHEDULER_LOGGING)
ACE_DEBUG ((LM_TRACE,
" TAO_Reconfig_Scheduler default ctor.\n"));
#endif /* SCHEDULER_LOGGING */
}
// 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,
const CORBA::Double & critical_utilization_threshold,
const CORBA::Double & noncritical_utilization_threshold)
: config_info_count_ (0),
rt_info_count_ (0),
rt_info_tuple_count_ (0),
next_handle_ (1),
stability_flags_ (SCHED_ALL_STABLE),
enforce_schedule_stability_ (enforce_schedule_stability),
dependency_count_ (0),
last_scheduled_priority_ (0),
noncritical_utilization_ (0.0),
critical_utilization_ (0.0),
noncritical_utilization_threshold_ (noncritical_utilization_threshold),
critical_utilization_threshold_ (critical_utilization_threshold)
{
#if defined (SCHEDULER_LOGGING)
ACE_DEBUG ((LM_TRACE,
" TAO_Reconfig_Scheduler alternative ctor.\n"));
#endif /* SCHEDULER_LOGGING */
// @ TODO - think about what it means to emit all the tuples as
// well as the established RT_Infos. State is more complex now.
// 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_ENV_ARG_PARAMETER);
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;
}
// Destructor.
template <class RECONFIG_SCHED_STRATEGY, class ACE_LOCK>
TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, ACE_LOCK>::
~TAO_Reconfig_Scheduler ()
{
#if defined (SCHEDULER_LOGGING)
ACE_DEBUG ((LM_TRACE,
" TAO_Reconfig_Scheduler dtor.\n"));
#endif /* SCHEDULER_LOGGING */
ACE_TRY_NEW_ENV
{
this->close (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_CATCH (CORBA::SystemException, corba_sysex)
{
ACE_ERROR ((LM_ERROR, "TAO_Reconfig_Scheduler<RECONFIG_SCHED_STRATEGY, "
"ACE_LOCK>::~TAO_Reconfig_Scheduler "
"exception: cannot close scheduler.\n"));
}
ACE_ENDTRY;
// Delete the entry and tuple pointer arrays.
delete [] entry_ptr_array_;
delete [] tuple_ptr_array_;
}
// Additive initialization: can be called multiple times, with
// new sets of operation, dependency, and config information.
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
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
RtecScheduler::DUPLICATE_NAME,
RtecScheduler::UNKNOWN_TASK,
RtecScheduler::SYNCHRONIZATION_FAILURE,
RtecScheduler::INTERNAL))
{
#if defined (SCHEDULER_LOGGING)
ACE_DEBUG ((LM_TRACE,
" TAO_Reconfig_Scheduler::init.\n"));
#endif /* SCHEDULER_LOGGING */
ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_,
RtecScheduler::SYNCHRONIZATION_FAILURE ());
ACE_CHECK_RETURN (-1);
int result = 0;
int i = 0;
/* WSOA merge - commented out
// Clear out the previous entries, if any.
this->close (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
*/
// Re-map the RT_Info and dependency handle values if necessary.
// Assumes that dependencies only refer to handles within the
// current set: changing that assumption would require us to use
// operation names, and the equivalent of a symbol table and
// relocating linker for RT_Infos to do this correctly in the
// general case.
if (this->next_handle_ > 1)
{
for (i = 0; i < rt_info_count; ++i)
{
rt_info [i].handle += this->next_handle_ - 1;
}
for (i = 0; i < dependency_count; ++i)
{
dependency_info [i].info_that_depends += this->next_handle_ - 1;
dependency_info [i].info_depended_on += this->next_handle_ - 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 (i = 0; i < config_count; ++i)
{
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 [i].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 [i].preemption_priority;
new_config_info->thread_priority =
config_info [i].thread_priority;
new_config_info->dispatching_type =
config_info [i].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 ();
// Increase the count of successfully bound config infos.
++this->config_info_count_;
}
// Add RT_Infos to scheduler
TAO_RT_Info_Ex* 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, 1
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
if (new_rt_info == 0)
{
ACE_THROW_RETURN (RtecScheduler::INTERNAL (), -1);
}
// Set the new info's enabled state
new_rt_info->enabled_state (rt_info [num_rt_infos].enabled);
// Fill in the portions to which the user has access.
this->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)
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
// 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 (i = 0; i < dependency_count; ++i)
{
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,
dependency_info [dependency_count_].enabled
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
++this->dependency_count_;
}
}
// 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 (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
RtecScheduler::INTERNAL,
RtecScheduler::UNKNOWN_TASK,
RtecScheduler::SYNCHRONIZATION_FAILURE))
{
#if defined (SCHEDULER_LOGGING)
ACE_DEBUG ((LM_TRACE,
" TAO_Reconfig_Scheduler::close.\n"));
#endif /* SCHEDULER_LOGGING */
ACE_GUARD_THROW_EX (ACE_LOCK, ace_mon, this->mutex_,
RtecScheduler::SYNCHRONIZATION_FAILURE ());
ACE_CHECK;
// Unbind and delete each RT_Info in the map: this also cleans up
// all the entries and tuples associated with each RT_Info.
TAO_RT_Info_Ex *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 the entry associated with the RT_Info, then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -