summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-11-09 23:54:14 +0000
committercdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-11-09 23:54:14 +0000
commit9df5e0df391ee8d80ab36ae86edf720f82374d91 (patch)
treef5ead0dbc00d73fafe342caeb8ffce75ee08b146
parent587806dc9c2d2fa965f01bdd48cf447f1cadedb8 (diff)
downloadATCD-9df5e0df391ee8d80ab36ae86edf720f82374d91.tar.gz
added complete anomaly recording to scheduler
-rw-r--r--ChangeLog-98b7
-rw-r--r--TAO/orbsvcs/orbsvcs/RtecScheduler.idl32
-rw-r--r--TAO/orbsvcs/orbsvcs/Runtime_Scheduler.cpp4
-rw-r--r--TAO/orbsvcs/orbsvcs/Runtime_Scheduler.h1
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp153
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h1
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp683
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/DynSched.h47
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp84
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h19
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i16
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler.h6
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp3
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h3
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp130
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h8
-rw-r--r--TAO/orbsvcs/orbsvcs/Scheduler_Factory.cpp72
-rw-r--r--TAO/orbsvcs/orbsvcs/Scheduler_Factory.h14
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.cpp11
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.dsw12
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.cpp385
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.dsp102
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies_Runtime.h47
-rw-r--r--TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Runtime.h30
24 files changed, 1580 insertions, 290 deletions
diff --git a/ChangeLog-98b b/ChangeLog-98b
index 7ac0cf10d40..c73158e5940 100644
--- a/ChangeLog-98b
+++ b/ChangeLog-98b
@@ -729,6 +729,13 @@ Fri Oct 23 21:11:03 1998 Douglas C. Schmidt <schmidt@mambo.cs.wustl.edu>
* ace/OS.h: Changed a comment to be consistent. Thanks to Serge
Kolgan <skolgan@cisco.com> for reporting this.
+Fri Oct 23 20:39:00 1998 Chris Gill <cdgill@cs.wustl.edu>
+
+ * Paul Christopher Gill was born Friday October 23, 1998, at
+ 20:39 CDT, weighing 6 lbs. 7 oz., at 19 3/4 inches in length.
+ A true hacker in the making, Paul decided to work through the
+ evening even though it was a Friday night. ;-)
+
Fri Oct 23 11:37:38 1998 Steve Huston <shuston@riverace.com>
* include/makeinclude/platform_aix4.2.GNU: Removed -qinitauto=5F from
diff --git a/TAO/orbsvcs/orbsvcs/RtecScheduler.idl b/TAO/orbsvcs/orbsvcs/RtecScheduler.idl
index 4b0477c20b3..aeb8e9d6352 100644
--- a/TAO/orbsvcs/orbsvcs/RtecScheduler.idl
+++ b/TAO/orbsvcs/orbsvcs/RtecScheduler.idl
@@ -169,6 +169,35 @@ module RtecScheduler
typedef sequence<Config_Info> Config_Info_Set;
+ enum Anomaly_Severity
+ // Defines the type of prioritization strategy
+ // to be used by a dispatching queue
+ {
+ ANOMALY_FATAL,
+ ANOMALY_ERROR,
+ ANOMALY_WARNING,
+ ANOMALY_NONE
+ };
+
+ struct Scheduling_Anomaly
+ // = TITLE
+ // Describes an anomalous condition encountered during scheduling.
+ //
+ // = DESCRIPTION
+ // The severity and description of an anomolous
+ // condition encountered during schedule computation
+ // is described by the following information.
+ {
+ // Application-defined string that describes
+ // the anomalous condition.
+ string description;
+
+ // Severity of the anomaly
+ Anomaly_Severity severity;
+ };
+
+ typedef sequence<Scheduling_Anomaly> Scheduling_Anomaly_Set;
+
exception DUPLICATE_NAME {};
// The application is trying to register the same task again.
@@ -269,7 +298,8 @@ module RtecScheduler
void compute_scheduling (in long minimum_priority,
in long maximum_priority,
out RT_Info_Set infos,
- out Config_Info_Set configs)
+ out Config_Info_Set configs,
+ out Scheduling_Anomaly_Set anomalies)
raises (UTILIZATION_BOUND_EXCEEDED,
INSUFFICIENT_THREAD_PRIORITY_LEVELS,
TASK_COUNT_MISMATCH);
diff --git a/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.cpp
index a2dc0c1362a..18f2ebdcdff 100644
--- a/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.cpp
+++ b/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.cpp
@@ -196,7 +196,9 @@ void ACE_Runtime_Scheduler::add_dependency (RtecScheduler::handle_t handle,
void ACE_Runtime_Scheduler::compute_scheduling (CORBA::Long minimum_priority,
CORBA::Long maximum_priority,
RtecScheduler::RT_Info_Set_out infos,
- RtecScheduler::Config_Info_Set_out configs,
+ RtecScheduler::Config_Info_Set_out configs,
+ RtecScheduler::Scheduling_Anomaly_Set_out anomalies,
+
CORBA::Environment &_env)
TAO_THROW_SPEC ((CORBA::SystemException,
RtecScheduler::UTILIZATION_BOUND_EXCEEDED,
diff --git a/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.h b/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.h
index 81fcc5773eb..3b8200a21bd 100644
--- a/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.h
+++ b/TAO/orbsvcs/orbsvcs/Runtime_Scheduler.h
@@ -81,6 +81,7 @@ public:
CORBA::Long maximum_priority,
RtecScheduler::RT_Info_Set_out infos,
RtecScheduler::Config_Info_Set_out configs,
+ RtecScheduler::Scheduling_Anomaly_Set_out anomalies,
CORBA::Environment &_env)
TAO_THROW_SPEC ((CORBA::SystemException,
RtecScheduler::UTILIZATION_BOUND_EXCEEDED,
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp
index 0dc1025acee..ec5da0f4ae5 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp
+++ b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp
@@ -113,7 +113,7 @@ ACE_Config_Scheduler::get (RtecScheduler::handle_t handle,
{
case BaseSchedImplType::SUCCEEDED:
{
- // IDL memory managment semantics require the we return a copy
+ // IDL memory managment semantics require that we return a copy.
RtecScheduler::RT_Info* copy;
ACE_NEW_RETURN (copy, RtecScheduler::RT_Info (*rt_info), 0);
return copy;
@@ -243,6 +243,7 @@ void ACE_Config_Scheduler::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 &_env)
TAO_THROW_SPEC ((CORBA::SystemException,
RtecScheduler::UTILIZATION_BOUND_EXCEEDED,
@@ -251,35 +252,128 @@ void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority,
{
ACE_UNUSED_ARG (_env);
+ // Initialize the scheduler implementation.
impl->init (minimum_priority, maximum_priority);
+ // Construct an unbounded set to hold any scheduling anomalies.
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> anomaly_set;
+
+ // Invoke the imlementation's scheduling method.
BaseSchedImplType::status_t schedule_status;
- schedule_status = impl->schedule ();
- switch (schedule_status)
+ schedule_status = impl->schedule (anomaly_set);
+
+ // Iterate over the set of anomalies, reporting each one, storing
+ // it in the set of anomalies to return, and determining the worst
+ // anomaly severity.
+ RtecScheduler::Anomaly_Severity severity = RtecScheduler::ANOMALY_NONE;
+ RtecScheduler::Scheduling_Anomaly **anomaly = 0;
+ char *anomaly_severity_msg = "NONE";
+ CORBA::ULong anomaly_index = 0;
+ if (anomalies.ptr () == 0)
{
- // If we succeeded with no warnings, do nothing.
- case BaseSchedImplType::SUCCEEDED:
- break;
+ anomalies =
+ new RtecScheduler::Scheduling_Anomaly_Set (anomaly_set.size ());
+ }
+ anomalies->length (anomaly_set.size ());
+ ACE_Unbounded_Set_Iterator<RtecScheduler::Scheduling_Anomaly *>
+ anomaly_iter (anomaly_set);
+ for (anomaly_iter.first (), anomaly_index = 0;
+ anomaly_iter.next (anomaly);
+ anomaly_iter.advance (), ++anomaly_index)
+ {
+ if (0 == *anomaly)
+ {
+ // if for some reason we stored a null anomaly pointer,
+ // just give default values to that entry in the sequence.
+ anomalies[anomaly_index].severity = RtecScheduler::ANOMALY_NONE;
+ anomalies[anomaly_index].description = "";
+ continue;
+ }
- // Issue a warning if there were unresolved remote dependencies.
- case BaseSchedImplType::ST_UNRESOLVED_REMOTE_DEPENDENCIES:
+ // Keep track of the *worst* anomaly severity
+ switch ((*anomaly)->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL:
+ anomaly_severity_msg = "FATAL";
+ severity = RtecScheduler::ANOMALY_FATAL;
+ break;
+
+ case RtecScheduler::ANOMALY_ERROR:
+ anomaly_severity_msg = "ERROR";
+ if (severity != RtecScheduler::ANOMALY_FATAL)
+ {
+ severity = RtecScheduler::ANOMALY_ERROR;
+ }
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING:
+ anomaly_severity_msg = "WARNING";
+ if ((severity != RtecScheduler::ANOMALY_FATAL) &&
+ (severity != RtecScheduler::ANOMALY_ERROR))
+ {
+ severity = RtecScheduler::ANOMALY_WARNING;
+ }
+ break;
+
+ case RtecScheduler::ANOMALY_NONE:
+ anomaly_severity_msg = "UNKNOWN";
+ break;
+ }
+
+ // Output the anomaly message
ACE_DEBUG ((LM_DEBUG,
- "Warning: schedule has unresolved "
- "remote dependencies\n."));
- break;
+ "%s: %s\n",
+ anomaly_severity_msg,
+ (*anomaly)->description));
- // Issue a warning if the schedule is not feasible.
- case BaseSchedImplType::ST_UTILIZATION_BOUND_EXCEEDED:
- ACE_DEBUG ((LM_DEBUG,
- "Warning: schedule exceeds utilization bound\n."));
- break;
+ // Store the anomaly in the anomaly sequence out parameter
+ anomalies[anomaly_index] = **anomaly;
- // On any other kind of scheduling error,
- // abort without generating a schedule.
- default:
+ // Release the anomaly node.
+ delete (*anomaly);
+ }
+
+ switch (severity)
+ {
+ // On a fatal anomaly abort without generating a schedule.
+ case RtecScheduler::ANOMALY_FATAL:
// TODO: throw something.
- ACE_ERROR ((LM_ERROR, "Schedule failed\n"));
+ ACE_ERROR ((LM_ERROR, "Schedule failed due to FATAL anomaly.\n"));
return;
+
+ // Otherwise, make sure we didn't get a fatal return type.
+ default:
+ switch (schedule_status)
+ {
+ case BaseSchedImplType::ST_BAD_INTERNAL_POINTER :
+ // TODO: throw something.
+ ACE_ERROR ((LM_ERROR,
+ "Schedule failed due to bad internal pointer.\n"));
+ return;
+
+ case BaseSchedImplType::ST_VIRTUAL_MEMORY_EXHAUSTED :
+ // TODO: throw something.
+ ACE_ERROR ((LM_ERROR,
+ "Schedule failed due to insufficient memory.\n"));
+ return;
+
+ case BaseSchedImplType::THREAD_COUNT_MISMATCH :
+ // TODO: throw something.
+ ACE_ERROR ((LM_ERROR,
+ "Schedule failed due to thread count mismatch.\n"));
+ return;
+
+ case BaseSchedImplType::TASK_COUNT_MISMATCH :
+ // TODO: throw something.
+ ACE_ERROR ((LM_ERROR,
+ "Schedule failed due to task count mismatch.\n"));
+ return;
+
+ // Otherwise, go ahead and generate a schedule.
+ default:
+ break;
+ }
+ break;
}
// return the set of scheduled RT_Infos
@@ -312,11 +406,13 @@ void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority,
// return the set of scheduled Config_Infos
if (configs.ptr () == 0)
{
- configs = new RtecScheduler::Config_Info_Set(impl->minimum_priority_queue () + 1);
+ configs =
+ new RtecScheduler::Config_Info_Set(impl->minimum_priority_queue () + 1);
}
configs->length (impl->minimum_priority_queue () + 1);
for (RtecScheduler::Preemption_Priority priority = 0;
- priority <= (RtecScheduler::Preemption_Priority) impl->minimum_priority_queue ();
+ priority <=
+ (RtecScheduler::Preemption_Priority) impl->minimum_priority_queue ();
++priority)
{
RtecScheduler::Config_Info* config_info = 0;
@@ -330,17 +426,18 @@ void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority,
case BaseSchedImplType::ST_UNKNOWN_TASK:
default:
ACE_ERROR ((LM_ERROR,
- "Config_Scheduler::schedule - lookup_config_info failed\n"));
+ "Config_Scheduler::schedule - "
+ "lookup_config_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()), *(configs.ptr()), 0);
- ACE_DEBUG ((LM_DEBUG, "dump done\n"));
+ 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"));
}
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h
index 866b373dd72..58d2084e31a 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h
@@ -89,6 +89,7 @@ public:
CORBA::Long maximum_priority,
RtecScheduler::RT_Info_Set_out infos,
RtecScheduler::Config_Info_Set_out configs,
+ RtecScheduler::Scheduling_Anomaly_Set_out anomalies,
CORBA::Environment &_env)
TAO_THROW_SPEC((CORBA::SystemException,
RtecScheduler::UTILIZATION_BOUND_EXCEEDED,
diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp b/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp
index 8ba959ee59d..6f71fd94198 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp
+++ b/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp
@@ -83,10 +83,10 @@ ACE_DynScheduler::status_message (ACE_DynScheduler::status_t status)
return "NOT_SCHEDULED";
case SUCCEEDED :
return "SUCCEEDED";
+ case ST_NO_TASKS_REGISTERED :
+ return "ST_NO_TASKS_REGISTERED";
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 :
@@ -95,8 +95,16 @@ ACE_DynScheduler::status_message (ACE_DynScheduler::status_t status)
return "UNKNOWN_TASK";
case TASK_COUNT_MISMATCH :
return "TASK_COUNT_MISMATCH";
+ case THREAD_COUNT_MISMATCH :
+ return "THREAD_COUNT_MISMATCH";
case INVALID_PRIORITY :
return "INVALID_PRIORITY";
+ case TWO_WAY_DISJUNCTION :
+ return "TWO_WAY_DISJUNCTION (IGNORED)";
+ case TWO_WAY_CONJUNCTION :
+ return "TWO_WAY_CONJUNCTION (IGNORED)";
+ case UNRECOGNIZED_INFO_TYPE :
+ return "UNRECOGNIZED_INFO_TYPE (IGNORED)";
// The following are only used during scheduling (in the case of
// off-line scheduling, they are only used prior to runtime).
@@ -111,6 +119,8 @@ ACE_DynScheduler::status_message (ACE_DynScheduler::status_t status)
return "CYCLE_IN_DEPENDENCIES";
case ST_UNRESOLVED_REMOTE_DEPENDENCIES :
return "ST_UNRESOLVED_REMOTE_DEPENDENCIES";
+ case ST_UNRESOLVED_LOCAL_DEPENDENCIES :
+ return "ST_UNRESOLVED_LOCAL_DEPENDENCIES";
case ST_INVALID_PRIORITY_ORDERING :
return "INVALID_PRIORITY_ORDERING";
case UNABLE_TO_OPEN_SCHEDULE_FILE :
@@ -126,6 +136,66 @@ ACE_DynScheduler::status_message (ACE_DynScheduler::status_t status)
return "UNKNOWN STATUS";
}
+// = Utility function for creating an entry for determining
+// the severity of an anomaly detected during scheduling.
+ACE_DynScheduler::Anomaly_Severity
+ACE_DynScheduler::anomaly_severity (ACE_DynScheduler::status_t status)
+{
+ // Determine severity of the anomaly
+ switch (status)
+ {
+ // Fatal anomalies reflect unrecoverable internal scheduler errors
+ case ST_BAD_INTERNAL_POINTER :
+ case ST_VIRTUAL_MEMORY_EXHAUSTED :
+ case THREAD_COUNT_MISMATCH :
+ case TASK_COUNT_MISMATCH :
+ return RtecScheduler::ANOMALY_FATAL;
+
+ // Errors reflect severe problems with given scheduling information
+ case UNABLE_TO_OPEN_SCHEDULE_FILE :
+ case UNABLE_TO_WRITE_SCHEDULE_FILE :
+ case NOT_SCHEDULED :
+ case ST_UNRESOLVED_LOCAL_DEPENDENCIES :
+ case ST_UNKNOWN_TASK :
+ case ST_CYCLE_IN_DEPENDENCIES :
+ case ST_INVALID_PRIORITY_ORDERING :
+ return RtecScheduler::ANOMALY_ERROR;
+ break;
+
+ // Warnings reflect serious problems with given scheduling information
+ case ST_TASK_ALREADY_REGISTERED :
+ case ST_UNRESOLVED_REMOTE_DEPENDENCIES :
+ case ST_UTILIZATION_BOUND_EXCEEDED :
+ case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS :
+ case TWO_WAY_DISJUNCTION :
+ case TWO_WAY_CONJUNCTION :
+ case UNRECOGNIZED_INFO_TYPE :
+ case ST_NO_TASKS_REGISTERED :
+ return RtecScheduler::ANOMALY_WARNING;
+ break;
+
+ // Produce a lowest severity anomaly for any unknown status value
+ default:
+ return RtecScheduler::ANOMALY_NONE;
+ break;
+ }
+}
+
+
+// = Utility function for creating an entry for the
+// log of anomalies detected during scheduling.
+ACE_DynScheduler::Scheduling_Anomaly *
+ACE_DynScheduler::create_anomaly (ACE_DynScheduler::status_t status)
+{
+ ACE_DynScheduler::Scheduling_Anomaly * anomaly;
+ ACE_NEW_RETURN (anomaly, ACE_DynScheduler::Scheduling_Anomaly, 0);
+
+ anomaly->severity = anomaly_severity (status);
+ anomaly->description = status_message (status);
+
+ return anomaly;
+}
+
ACE_DynScheduler::ACE_DynScheduler ()
// Set the minimum and maximum priority to those for the current platform.
@@ -193,13 +263,13 @@ ACE_DynScheduler::init (const OS_Priority minimum_priority,
ACE_DynScheduler::status_t
ACE_DynScheduler::register_task (RT_Info *rt_info, handle_t &handle)
{
- ACE_DynScheduler::status_t ret;
+ ACE_DynScheduler::status_t ret = ST_UNKNOWN_TASK;
// check the pointer we were passed
if (! rt_info)
{
handle = 0;
- return ST_UNKNOWN_TASK;
+ return ret;
}
// try to store the new task's information . . .
@@ -454,7 +524,7 @@ ACE_DynScheduler::dispatch_configuration (const Preemption_Priority & p_priority
ACE_DynScheduler::status_t
ACE_DynScheduler::lookup_rt_info (handle_t handle,
- RT_Info*& rtinfo)
+ RT_Info*& rtinfo)
{
if (handle < 0 || (size_t) handle > rt_info_entries_.size ())
{
@@ -616,9 +686,13 @@ ACE_DynScheduler::reset ()
}
ACE_DynScheduler::status_t
-ACE_DynScheduler::schedule (void)
+ACE_DynScheduler::schedule (
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set)
{
+ RtecScheduler::Anomaly_Severity severity = RtecScheduler::ANOMALY_NONE;
+ RtecScheduler::Anomaly_Severity temp_severity = RtecScheduler::ANOMALY_NONE;
status_t temp_status = SUCCEEDED;
+ Scheduling_Anomaly *anomaly = 0;
ACE_Guard<LOCK> ace_mon (lock_);
@@ -634,137 +708,340 @@ ACE_DynScheduler::schedule (void)
tasks (rt_info_entries_.size ());
}
- // set up the task entry data structures, check for call cycles
+ // set up the task entry data structures
status_ = setup_task_entries ();
+ if (status_ != SUCCEEDED)
+ {
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (status_);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
- 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 ();
- }
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ return status_;
- if (status_ == SUCCEEDED)
- {
- // task entries are related, now threads can be found
- status_ = identify_threads ();
- }
+ default:
+ severity = anomaly->severity;
+ break;
+ }
+ }
- if ((status_ == SUCCEEDED) || (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- // invokes the internal thread scheduling method of the strategy
- temp_status = schedule_threads ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ // 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.
+ temp_status = check_dependency_cycles ();
+ if (temp_status != SUCCEEDED)
+ {
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (temp_status);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
- if ((status_ == SUCCEEDED) || (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- // propagate the dispatch information from the
- // threads throughout the call graph
- temp_status = propagate_dispatches ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = anomaly->severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = anomaly->severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
- if ((status_ == SUCCEEDED) || (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- // invokes the internal dispatch scheduling method of the strategy
- temp_status = schedule_dispatches ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ // task entries are related, now threads can be found
+ temp_status = identify_threads (anomaly_set);
+ if (temp_status != SUCCEEDED)
+ {
+ temp_severity = anomaly_severity (temp_status);
+ switch (temp_severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = temp_severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = temp_severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
+
+ // invoke the internal thread scheduling method of the strategy
+ temp_status = schedule_threads (anomaly_set);
+ if (temp_status != SUCCEEDED)
+ {
+ temp_severity = anomaly_severity (temp_status);
+ switch (temp_severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = temp_severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = temp_severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
+
+ // propagate the dispatch information from the
+ // threads throughout the call graph
+ temp_status = propagate_dispatches (anomaly_set);
+ if (temp_status != SUCCEEDED)
+ {
+ temp_severity = anomaly_severity (temp_status);
+ switch (temp_severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = temp_severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = temp_severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
+
+ // invoke the internal dispatch scheduling method of the strategy
+ temp_status = schedule_dispatches (anomaly_set);
+ if (temp_status != SUCCEEDED)
+ {
+ temp_severity = anomaly_severity (temp_status);
+ switch (temp_severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = temp_severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = temp_severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
// calculate utilization, total frame size, critical set
- if ((status_ == SUCCEEDED) || (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- temp_status = calculate_utilization_params ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ temp_status = calculate_utilization_params ();
+ if (temp_status != SUCCEEDED)
+ {
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (temp_status);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = anomaly->severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = anomaly->severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
// calculate utilization, total frame size, critical set
- if ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED) ||
- (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- temp_status = store_assigned_info ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ temp_status = store_assigned_info ();
+ if (temp_status != SUCCEEDED)
+ {
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (temp_status);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
- // generate the scheduling timeline over the total frame size
- if ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED) ||
- (status_ == ST_UNRESOLVED_REMOTE_DEPENDENCIES))
- {
- temp_status = create_timeline ();
- if (temp_status != SUCCEEDED)
- {
- status_ = temp_status;
- }
- }
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = anomaly->severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = anomaly->severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
- // store the timeline to a file if one was given
- if ((timeline_filename_ != 0) &&
- ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED)))
+ // generate, store the timeline to a file if file was given
+ if (timeline_filename_ != 0)
{
+ // generate the scheduling timeline over the total frame size
+ temp_status = create_timeline ();
+ if (temp_status != SUCCEEDED)
+ {
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (temp_status);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = anomaly->severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = anomaly->severity;
+ status_ = temp_status;
+ }
+ break;
+ }
+ }
+
+
temp_status = output_timeline (timeline_filename_, 0);
if (temp_status != SUCCEEDED)
{
- status_ = temp_status;
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (temp_status);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+
+ switch (anomaly->severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL :
+ status_ = temp_status;
+ return status_;
+
+ case RtecScheduler::ANOMALY_ERROR :
+ severity = anomaly->severity;
+ status_ = temp_status;
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING :
+ if (severity == RtecScheduler::ANOMALY_NONE)
+ {
+ severity = anomaly->severity;
+ status_ = temp_status;
+ }
+ break;
+ }
}
}
- // if a valid schedule was not generated, clean up from the attempt
+ // if a valid schedule was generated, mark it as up to date
switch (status_)
{
- // these are statuses that indicate a reasonable schedule was generated
+ // These are statuses that indicate a reasonable schedule was generated.
case SUCCEEDED:
- case ST_UTILIZATION_BOUND_EXCEEDED:
- case ST_UNRESOLVED_REMOTE_DEPENDENCIES:
+ case ST_TASK_ALREADY_REGISTERED :
+ case ST_UNRESOLVED_REMOTE_DEPENDENCIES :
+ case ST_UTILIZATION_BOUND_EXCEEDED :
+ case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS :
// 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;
}
@@ -773,10 +1050,13 @@ ACE_DynScheduler::schedule (void)
}
ACE_DynScheduler::status_t
-ACE_DynScheduler::propagate_dispatches ()
+ACE_DynScheduler::propagate_dispatches (
+ ACE_Unbounded_Set<ACE_DynScheduler::Scheduling_Anomaly *> &anomaly_set)
{
u_long i;
frame_size_ = 1;
+ status_t status = SUCCEEDED;
+ Scheduling_Anomaly * anomaly = 0;
// iterate through the ordered_task_entries_ array in order
// from highest DFS finishing time to lowest, so that every
@@ -784,9 +1064,73 @@ ACE_DynScheduler::propagate_dispatches ()
// 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;
+ switch (ordered_task_entries_ [i]->merge_dispatches (*dispatch_entries_))
+ {
+ case Task_Entry::INTERNAL_ERROR :
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (ST_BAD_INTERNAL_POINTER);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+
+ return ST_BAD_INTERNAL_POINTER;
+
+ case Task_Entry::TWO_WAY_DISJUNCTION :
+ if (status == SUCCEEDED)
+ {
+ status = TWO_WAY_DISJUNCTION;
+ }
+ anomaly = create_anomaly (TWO_WAY_DISJUNCTION);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+ break;
+
+ case Task_Entry::TWO_WAY_CONJUNCTION :
+ if (status == SUCCEEDED)
+ {
+ status = TWO_WAY_CONJUNCTION;
+ }
+ anomaly = create_anomaly (TWO_WAY_CONJUNCTION);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+ break;
+
+ case Task_Entry::UNRECOGNIZED_INFO_TYPE :
+ if (status == SUCCEEDED)
+ {
+ status = UNRECOGNIZED_INFO_TYPE;
+ }
+ anomaly = create_anomaly (UNRECOGNIZED_INFO_TYPE);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
+ break;
+
+ case Task_Entry::SUCCEEDED :
+ default:
+ break;
}
if (ordered_task_entries_ [i]->effective_period () > 0)
@@ -795,14 +1139,9 @@ ACE_DynScheduler::propagate_dispatches ()
minimum_frame_size (frame_size_,
ordered_task_entries_ [i]->effective_period ());
}
- else
- {
- return ST_UNKNOWN_TASK;
- }
-
}
- return SUCCEEDED;
+ return status;
}
// propagate the dispatch information from the
// threads throughout the call graph
@@ -888,7 +1227,7 @@ ACE_DynScheduler::setup_task_entries (void)
// bail out if there are no tasks registered
if (tasks () <= 0)
{
- return ST_UNKNOWN_TASK;
+ return ST_NO_TASKS_REGISTERED;
}
// clear the decks of any previous scheduling information
@@ -930,7 +1269,7 @@ ACE_DynScheduler::setup_task_entries (void)
// tie task entry to corresponding rt_info
if (! iter.next (info_entry))
{
- return ST_UNKNOWN_TASK;
+ return ST_BAD_INTERNAL_POINTER;
}
task_entries_ [i].rt_info (*info_entry);
@@ -1002,7 +1341,7 @@ ACE_DynScheduler::relate_task_entries_recurse (long &time, Task_Entry &entry)
if (! dependency_info)
{
- return ST_UNKNOWN_TASK;
+ return ST_BAD_INTERNAL_POINTER;
}
// obtain a pointer to the Task_Entry from the dependency RT_Info
@@ -1011,7 +1350,7 @@ ACE_DynScheduler::relate_task_entries_recurse (long &time, Task_Entry &entry)
if (! dependency_entry_ptr)
{
- return ST_UNKNOWN_TASK;
+ return ST_BAD_INTERNAL_POINTER;
}
// relate the entries according to the direction of the dependency
@@ -1041,10 +1380,12 @@ ACE_DynScheduler::relate_task_entries_recurse (long &time, Task_Entry &entry)
}
ACE_DynScheduler::status_t
-ACE_DynScheduler::identify_threads (void)
+ACE_DynScheduler::identify_threads (
+ ACE_Unbounded_Set<ACE_DynScheduler::Scheduling_Anomaly *> &anomaly_set)
{
u_int i, j;
ACE_DynScheduler::status_t result = SUCCEEDED;
+ Scheduling_Anomaly * anomaly = 0;
// walk array of task entries, picking out thread delineators
for (i = 0; i < tasks_; i++)
@@ -1092,24 +1433,53 @@ ACE_DynScheduler::identify_threads (void)
else if (task_entries_ [i].rt_info ()->info_type == RtecScheduler::REMOTE_DEPENDANT)
{
// Warn about unresolved remote dependencies, mark the task entry
- result = ST_UNRESOLVED_REMOTE_DEPENDENCIES;
+
+ result = (result == SUCCEEDED)
+ ? ST_UNRESOLVED_REMOTE_DEPENDENCIES
+ : result;
+
task_entries_ [i].has_unresolved_remote_dependencies (1);
ACE_DEBUG (
(LM_DEBUG,
"Warning: an operation identified by "
- "\"%s\" has unresolved remote dependencies\n.",
+ "\"%s\" has unresolved remote dependencies.\n",
(const char*) task_entries_ [i].rt_info ()->entry_point));
+
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (ST_UNRESOLVED_REMOTE_DEPENDENCIES);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
else
{
// Local 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);
+ ACE_DEBUG (
+ (LM_DEBUG,
+ "Error: operation \"%s\" does not specify a period or\n"
+ "visible threads, and is not called by any other operation.\n"
+ "Are there backwards dependencies.\n",
+ (const char*) task_entries_ [i].rt_info ()->entry_point));
+
+ result = ST_UNRESOLVED_LOCAL_DEPENDENCIES;
+
+ task_entries_ [i].has_unresolved_local_dependencies (1);
+
+ // Create an anomaly, add it to anomaly set
+ anomaly = create_anomaly (ST_UNRESOLVED_LOCAL_DEPENDENCIES);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
}
}
@@ -1201,8 +1571,10 @@ ACE_DynScheduler::check_dependency_cycles_recurse (Task_Entry &entry)
ACE_DynScheduler::status_t
-ACE_DynScheduler::schedule_threads (void)
+ACE_DynScheduler::schedule_threads (ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set)
{
+ Scheduling_Anomaly * anomaly = 0;
+
// make sure there are as many thread delineator
// entries in the set as the counter indicates
if (threads_ != thread_delineators_->size ())
@@ -1226,7 +1598,7 @@ ACE_DynScheduler::schedule_threads (void)
if (! iter.next (dispatch_entry))
{
- return ST_UNKNOWN_TASK;
+ return ST_BAD_INTERNAL_POINTER;
}
ordered_thread_dispatch_entries_ [i] = *dispatch_entry;
@@ -1238,7 +1610,8 @@ ACE_DynScheduler::schedule_threads (void)
if (status == SUCCEEDED)
{
// assign priorities to the thread dispatch entries
- status = assign_priorities (ordered_thread_dispatch_entries_, threads_);
+ status = assign_priorities (ordered_thread_dispatch_entries_,
+ threads_, anomaly_set);
}
return status;
@@ -1247,7 +1620,7 @@ ACE_DynScheduler::schedule_threads (void)
// entries that are threads, calls internal thread scheduling method
ACE_DynScheduler::status_t
-ACE_DynScheduler::schedule_dispatches (void)
+ACE_DynScheduler::schedule_dispatches (ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set)
{
dispatch_entry_count_ = dispatch_entries_->size ();
@@ -1257,8 +1630,6 @@ ACE_DynScheduler::schedule_dispatches (void)
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 ())
{
@@ -1266,7 +1637,7 @@ ACE_DynScheduler::schedule_dispatches (void)
if (! iter.next (dispatch_entry))
{
- return ST_UNKNOWN_TASK;
+ return ST_BAD_INTERNAL_POINTER;
}
ordered_dispatch_entries_ [i] = *dispatch_entry;
@@ -1276,7 +1647,8 @@ ACE_DynScheduler::schedule_dispatches (void)
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_);
+ return assign_subpriorities (ordered_dispatch_entries_,
+ dispatch_entry_count_, anomaly_set);
}
// dispatch scheduling method: sets up an array of dispatch entries,
// calls internal dispatch scheduling method.
@@ -1284,22 +1656,19 @@ ACE_DynScheduler::schedule_dispatches (void)
ACE_DynScheduler::status_t
ACE_DynScheduler::store_assigned_info (void)
{
-
for (u_int i = 0; i < dispatch_entry_count_; ++i)
- {
- if ((! ordered_dispatch_entries_) || (! (ordered_dispatch_entries_[i])) ||
- (! (ordered_dispatch_entries_[i]->task_entry ().rt_info ())))
- {
- ACE_ERROR_RETURN ((LM_ERROR,
- "ACE_DynScheduler::store_assigned_info () could not store "
- "priority information (error in internal representation)"),
- ST_UNKNOWN_TASK);
- }
+ {
+ if ((! ordered_dispatch_entries_) || (! (ordered_dispatch_entries_[i])) ||
+ (! (ordered_dispatch_entries_[i]->task_entry ().rt_info ())))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE_DynScheduler::store_assigned_info () could not store "
+ "priority information (error in internal representation)"),
+ ST_BAD_INTERNAL_POINTER);
+ }
// set OS priority and Scheduler preemption priority and static
// preemption subpriority in underlying RT_Info
- // TBD - assign values into a map of priorities and RT_Infos:
- // an RT_Info can be dispatched at multiple priorities
ordered_dispatch_entries_ [i]->task_entry ().rt_info ()->priority =
ordered_dispatch_entries_ [i]->OS_priority ();
ordered_dispatch_entries_ [i]->task_entry ().rt_info ()->preemption_priority =
@@ -1367,7 +1736,7 @@ ACE_DynScheduler::create_timeline ()
if (reschedule_queue.dequeue_head (rescheduled_entry) < 0)
{
- status = ST_UNKNOWN_TASK;
+ status = ST_BAD_INTERNAL_POINTER;
break;
}
@@ -1382,9 +1751,8 @@ ACE_DynScheduler::create_timeline ()
break;
}
-
- // schedule additional dispatcheds of the entry
- // over the total frame size into the timeline
+ // Schedule additional dispatches 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 ();
@@ -1424,10 +1792,9 @@ ACE_DynScheduler::create_timeline ()
while (reschedule_queue.is_empty () == 0)
{
-
if (reschedule_queue.dequeue_head (rescheduled_entry) < 0)
{
- status = ST_UNKNOWN_TASK;
+ status = ST_BAD_INTERNAL_POINTER;
break;
}
status = schedule_timeline_entry (*rescheduled_entry, reschedule_queue);
diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.h b/TAO/orbsvcs/orbsvcs/Sched/DynSched.h
index a4f7a67cd48..e61d08f3749 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/DynSched.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/DynSched.h
@@ -34,7 +34,7 @@
class TAO_ORBSVCS_Export ACE_DynScheduler
// = TITLE
- // dispatch scheduling interface.
+ // Dispatch scheduling interface.
//
// = DESCRIPTION
// This abstract base class provides the majority of the
@@ -59,6 +59,8 @@ public:
typedef RtecScheduler::Info_Type Info_Type;
typedef RtecScheduler::Dependency_Type Dependency_Type;
typedef RtecScheduler::Dispatching_Type Dispatching_Type;
+ typedef RtecScheduler::Scheduling_Anomaly Scheduling_Anomaly;
+ typedef RtecScheduler::Anomaly_Severity Anomaly_Severity;
typedef ACE_Map_Entry <ACE_CString, RT_Info *> Thread_Map_Entry;
typedef ACE_Map_Manager <ACE_CString, RT_Info *, ACE_Null_Mutex>
@@ -78,9 +80,13 @@ public:
, ST_UNKNOWN_TASK
, ST_UNKNOWN_PRIORITY
, ST_TASK_ALREADY_REGISTERED
+ , ST_NO_TASKS_REGISTERED
, ST_BAD_DEPENDENCIES_ON_TASK
, ST_BAD_INTERNAL_POINTER
, ST_VIRTUAL_MEMORY_EXHAUSTED
+ , TWO_WAY_DISJUNCTION
+ , TWO_WAY_CONJUNCTION
+ , UNRECOGNIZED_INFO_TYPE
// The following are only used by the runtime Scheduler.
, TASK_COUNT_MISMATCH // only used by schedule ()
@@ -95,6 +101,7 @@ public:
, ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS
, ST_CYCLE_IN_DEPENDENCIES
, ST_UNRESOLVED_REMOTE_DEPENDENCIES
+ , ST_UNRESOLVED_LOCAL_DEPENDENCIES
, ST_INVALID_PRIORITY_ORDERING
, UNABLE_TO_OPEN_SCHEDULE_FILE
, UNABLE_TO_WRITE_SCHEDULE_FILE
@@ -113,6 +120,15 @@ public:
// representation of a status_t value.
static const char * status_message (status_t status);
+ // = Utility function for creating an entry for determining
+ // the severity of an anomaly detected during scheduling.
+ static Anomaly_Severity anomaly_severity (status_t status);
+
+ // = Utility function for creating an entry for the
+ // log of anomalies detected during scheduling.
+ static Scheduling_Anomaly * create_anomaly (status_t status);
+
+
// = Initialize the scheduler.
void init (const OS_Priority minimum_priority,
const OS_Priority maximum_priority,
@@ -174,10 +190,11 @@ public:
// Obtains an RT_Info based on its "handle".
status_t lookup_config_info (Preemption_Priority priority,
- Config_Info* &config_info);
+ Config_Info* &config_info);
// Obtains a Config_Info based on its priority.
- status_t schedule (void);
+ status_t
+ schedule (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set);
// This sets up the data structures, invokes the internal scheduling method.
status_t output_timeline (const char *filename, const char *heading);
@@ -245,11 +262,13 @@ protected:
ACE_DynScheduler ();
- status_t schedule_threads (void);
+ status_t schedule_threads (
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set);
// thread scheduling method: sets up array of pointers to task
// entries that are threads, calls internal thread scheduling method
- status_t schedule_dispatches (void);
+ status_t schedule_dispatches (
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set);
// dispatch scheduling method: sets up an array of dispatch entries,
// calls internal dispatch scheduling method.
@@ -279,12 +298,16 @@ protected:
// 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;
+ virtual status_t assign_priorities (
+ Dispatch_Entry **dispatches,
+ u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set) = 0;
// = assign priorities to the sorted dispatches
- virtual status_t assign_subpriorities (Dispatch_Entry **dispatches,
- u_int count) = 0;
+ virtual status_t assign_subpriorities (
+ Dispatch_Entry **dispatches,
+ u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set) = 0;
// = assign dynamic and static sub-priorities to the sorted dispatches
virtual status_t
@@ -401,7 +424,8 @@ private:
status_t relate_task_entries_recurse (long &time, Task_Entry &entry);
// identify thread delimiters
- status_t identify_threads (void);
+ status_t
+ identify_threads (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set);
// checks for cycles in the dependency graph
status_t check_dependency_cycles (void);
@@ -421,7 +445,8 @@ private:
// update the scheduling parameters for the previous priority level
void update_priority_level_params ();
- status_t propagate_dispatches ();
+ status_t
+ propagate_dispatches (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set);
// propagate the dispatch information from the
// threads throughout the call graph
diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp
index 45fdf921a99..4594dc1a550 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp
+++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp
@@ -99,6 +99,7 @@ Task_Entry::Task_Entry ()
finished_ (-1),
is_thread_delineator_ (0),
has_unresolved_remote_dependencies_ (0),
+ has_unresolved_local_dependencies_ (0),
calls_ (),
callers_ ()
{
@@ -127,10 +128,10 @@ Task_Entry::~Task_Entry ()
// Merge dispatches according to info type and type of call,
// update relevant scheduling characteristics for this entry.
-int
+Task_Entry::Propagation_Status
Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries)
{
- int result = 0;
+ Task_Entry::Propagation_Status result = SUCCEEDED;
switch (info_type ())
{
case RtecScheduler::DISJUNCTION:
@@ -140,12 +141,14 @@ Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_ent
// 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);
- }
-
+ if (prohibit_dispatches (RtecScheduler::TWO_WAY_CALL) < 0)
+ {
+ result = TWO_WAY_DISJUNCTION;
+ }
+ if (disjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries) < 0)
+ {
+ result = INTERNAL_ERROR;
+ }
break;
case RtecScheduler::CONJUNCTION:
@@ -158,12 +161,14 @@ Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_ent
// (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);
- }
-
+ if (prohibit_dispatches (RtecScheduler::TWO_WAY_CALL) < 0)
+ {
+ result = TWO_WAY_CONJUNCTION;
+ }
+ if (conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries) < 0)
+ {
+ result = INTERNAL_ERROR;
+ }
break;
case RtecScheduler::OPERATION:
@@ -171,28 +176,27 @@ Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_ent
// 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);
- }
-
+ if (disjunctive_merge (RtecScheduler::TWO_WAY_CALL, dispatch_entries) < 0)
+ {
+ result = INTERNAL_ERROR;
+ }
+ if (conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries) < 0)
+ {
+ result = INTERNAL_ERROR;
+ }
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;
+ result = UNRECOGNIZED_INFO_TYPE;
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
@@ -260,6 +264,22 @@ Task_Entry::disjunctive_merge (
(const char*) this->rt_info ()->entry_point));
}
+ // Check for and warn about unresolved local
+ // dependencies in the ONE_WAY call graph.
+ if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL &&
+ (*link)->caller ().has_unresolved_local_dependencies () &&
+ ! this->has_unresolved_local_dependencies ())
+ {
+ // Propagate the unresolved local dependency
+ // flag, and issue a debug scheduler warning.
+ this->has_unresolved_local_dependencies (1);
+ ACE_DEBUG (
+ (LM_DEBUG,
+ "Warning: an operation identified by "
+ "\"%s\" has unresolved local dependencies.\n",
+ (const char*) this->rt_info ()->entry_point));
+ }
+
// Merge the caller's dispatches into the current set.
if (merge_frames (dispatch_entries, *this, dispatches_,
(*link)->caller ().dispatches_, effective_period_,
@@ -320,6 +340,22 @@ Task_Entry::conjunctive_merge (
(const char*) this->rt_info ()->entry_point));
}
+ // Check for and warn about unresolved local
+ // dependencies in the ONE_WAY call graph.
+ if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL &&
+ (*link)->caller ().has_unresolved_local_dependencies () &&
+ ! this->has_unresolved_local_dependencies ())
+ {
+ // Propagate the unresolved local dependency
+ // flag, and issue a debug scheduler warning.
+ this->has_unresolved_local_dependencies (1);
+ ACE_DEBUG (
+ (LM_DEBUG,
+ "Warning: an operation identified by "
+ "\"%s\" has unresolved local dependencies.\n",
+ (const char*) this->rt_info ()->entry_point));
+ }
+
frame_size = minimum_frame_size (frame_size, (*link)->caller ().effective_period_);
}
}
diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h
index 9c6141e14d6..8eb7f33d118 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h
@@ -109,6 +109,13 @@ public:
// Info for DFS traversal, topological sort of call graph.
enum DFS_Status {NOT_VISITED, VISITED, FINISHED};
+ // Status of merging dispatches.
+ enum Propagation_Status {SUCCEEDED,
+ TWO_WAY_DISJUNCTION,
+ TWO_WAY_CONJUNCTION,
+ INTERNAL_ERROR,
+ UNRECOGNIZED_INFO_TYPE};
+
// Constructor.
Task_Entry ();
@@ -118,7 +125,7 @@ public:
// Merges 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 (
+ Propagation_Status merge_dispatches (
ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries);
// Gets the pointer to the underlying RT_Info.
@@ -163,6 +170,12 @@ public:
// Gets the flag indicating whether node has unresolved remote dependencies.
int has_unresolved_remote_dependencies () const;
+ // Sets a flag indicating whether node has unresolved local dependencies.
+ void has_unresolved_local_dependencies (int i);
+
+ // Gets the flag indicating whether node has unresolved local dependencies.
+ int has_unresolved_local_dependencies () const;
+
// Gets the set of links to Task Entries which this entry calls.
ACE_Unbounded_Set <Task_Entry_Link *> & calls ();
@@ -259,6 +272,10 @@ private:
// dependencies in the entry's dependency call chain.
int has_unresolved_remote_dependencies_;
+ // Flag indicating whether or not there are unresolved local
+ // dependencies in the entry's dependency call chain.
+ int has_unresolved_local_dependencies_;
+
// Set of links to Task Entries which this entry calls.
ACE_Unbounded_Set <Task_Entry_Link *> calls_;
diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i
index f016b0ebeb4..5603dc6537b 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i
+++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i
@@ -120,6 +120,22 @@ Task_Entry::has_unresolved_remote_dependencies () const
}
+// Sets a flag indicating whether node has unresolved local dependencies.
+
+ACE_INLINE void
+Task_Entry::has_unresolved_local_dependencies (int i)
+{
+ has_unresolved_local_dependencies_ = i;
+}
+
+// Gets the flag indicating whether node has unresolved local dependencies.
+
+ACE_INLINE int
+Task_Entry::has_unresolved_local_dependencies () const
+{
+ return has_unresolved_local_dependencies_;
+}
+
// Gets the set of Task Entries on which this entry depends.
ACE_INLINE ACE_Unbounded_Set <Task_Entry_Link *> &
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h
index 257329bb4e7..e95db5677c8 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h
@@ -55,6 +55,7 @@ public:
typedef RtecScheduler::Config_Info Config_Info;
typedef RtecScheduler::Time Time;
typedef RtecScheduler::Dispatching_Type Dispatching_Type;
+ typedef RtecScheduler::Scheduling_Anomaly Scheduling_Anomaly;
// Map some types to simplify re-use.
@@ -73,11 +74,13 @@ public:
, ST_UNKNOWN_PRIORITY
, ST_TASK_ALREADY_REGISTERED
, ST_VIRTUAL_MEMORY_EXHAUSTED
+ , ST_BAD_INTERNAL_POINTER
// 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 ()
+ , 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.
@@ -166,7 +169,8 @@ public:
// = Computes the schedule.
- virtual status_t schedule (void) = 0;
+ virtual status_t
+ schedule (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set) = 0;
// This actually generates the files.
// = Access a thread priority.
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp
index 1d697e30d79..1daaeb423f6 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp
+++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp
@@ -217,7 +217,8 @@ Scheduler_Generic::init (const int minimum_priority,
Scheduler::status_t
-Scheduler_Generic::schedule (void)
+Scheduler_Generic::schedule (ACE_Unbounded_Set<Scheduling_Anomaly *>
+ &anomaly_set)
{
ACE_Guard<LOCK> ace_mon (lock_);
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h
index 68c33084cc0..181a4307093 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h
@@ -54,7 +54,8 @@ public:
// Obtains a Config_Info based on its priority.
// = Computes the schedule.
- virtual status_t schedule (void);
+ virtual status_t
+ schedule (ACE_Unbounded_Set<Scheduling_Anomaly *> &anomaly_set);
// = Access a thread priority.
virtual int priority (const handle_t handle,
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp
index 942586a3115..41f5c1330b3 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp
+++ b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp
@@ -67,11 +67,15 @@ ACE_Strategy_Scheduler::sort_dispatches (Dispatch_Entry **dispatches,
// by the strategy's comparison operators
ACE_DynScheduler::status_t
-ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches,
- u_int count)
+ACE_Strategy_Scheduler::assign_priorities (
+ Dispatch_Entry **dispatches,
+ u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set)
{
// start with happy status
- ACE_DynScheduler::status_t status = ACE_DynScheduler::SUCCEEDED;
+ ACE_DynScheduler::status_t status = SUCCEEDED;
+
+ RtecScheduler::Scheduling_Anomaly * anomaly = 0;
// start with the highest OS priority in the given range and work downward:
// if we run out of values to assign, return an error.
@@ -87,7 +91,7 @@ ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches,
// store the dispatch configuration for the highest priority level
Config_Info *config_ptr;
- ACE_NEW_RETURN(config_ptr, Config_Info, ST_VIRTUAL_MEMORY_EXHAUSTED);
+ ACE_NEW_RETURN (config_ptr, Config_Info, ST_VIRTUAL_MEMORY_EXHAUSTED);
config_ptr->preemption_priority = current_scheduler_priority;
config_ptr->thread_priority = current_OS_priority;
config_ptr->dispatching_type = strategy_.dispatch_type (*(dispatches[0]));
@@ -119,10 +123,26 @@ ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches,
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;
+ // If we have run out of priority levels to assign, indicate
+ // this in the return status, unless a more severe problem is
+ // already reflected there. Log an anomaly but keep right on
+ // assigning the minimum OS priority in the range to the remaining
+ // tasks.
+ status = (status == SUCCEEDED)
+ ? ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS
+ : status;
+
+ // Log the anomaly.
+ anomaly =
+ create_anomaly (ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
else
{
@@ -149,15 +169,28 @@ ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches,
break;
- default: // should never reach here: something *bad* has happened
+ default: // Should never reach here: something *bad* has happened.
- ACE_ERROR_RETURN ((
+ ACE_ERROR ((
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);
+ dispatches [i]->task_entry ().rt_info ()->entry_point.in ()));
+
+ status = ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING;
+
+ // Log the anomaly.
+ anomaly =
+ create_anomaly (ST_INVALID_PRIORITY_ORDERING);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
// set OS priority of the current dispatch entry
@@ -173,9 +206,14 @@ ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches,
// according to the strategy's priority comparison operator.
ACE_DynScheduler::status_t
-ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches,
- u_int count)
+ACE_Strategy_Scheduler::assign_subpriorities (
+ Dispatch_Entry **dispatches,
+ u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set)
{
+ ACE_DynScheduler::status_t status = ACE_DynScheduler::SUCCEEDED;
+ RtecScheduler::Scheduling_Anomaly * anomaly = 0;
+
// 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;
@@ -252,7 +290,7 @@ ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches,
case 0: // still at the same dynamic subpriority level
- {
+ {
switch (strategy_.static_subpriority_comp (*(dispatches[i-1]),
*(dispatches[i])))
{
@@ -272,27 +310,52 @@ ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches,
default: // should never reach here: something *bad* has happened
- ACE_ERROR_RETURN ((
+ ACE_ERROR ((
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);
+ dispatches [i]->task_entry ().rt_info ()->entry_point.in ()));
+
+ status = ST_INVALID_PRIORITY_ORDERING;
+
+ // Log the anomaly.
+ anomaly =
+ create_anomaly (ST_INVALID_PRIORITY_ORDERING);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
-
break;
- }
+ }
default: // should never reach here: something *bad* has happened
- ACE_ERROR_RETURN ((
+ ACE_ERROR ((
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]->task_entry ().rt_info ()->entry_point.in ()));
+
+ status = ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING;
+
+ // Log the anomaly.
+ anomaly =
+ create_anomaly (ST_INVALID_PRIORITY_ORDERING);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
dispatches [i]->dynamic_subpriority (dynamic_subpriority_level);
@@ -302,13 +365,26 @@ ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches,
default: // should never reach here: something *bad* has happened
- ACE_ERROR_RETURN ((
+ ACE_ERROR ((
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);
+ dispatches [i]->task_entry ().rt_info ()->entry_point.in ()));
+
+ status = ACE_DynScheduler::ST_INVALID_PRIORITY_ORDERING;
+
+ // Log the anomaly.
+ anomaly =
+ create_anomaly (ST_INVALID_PRIORITY_ORDERING);
+ if (anomaly)
+ {
+ anomaly_set.insert (anomaly);
+ }
+ else
+ {
+ return ST_VIRTUAL_MEMORY_EXHAUSTED;
+ }
}
}
@@ -328,7 +404,7 @@ ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches,
dispatches [i - j]->static_subpriority () - 1);
}
- return ACE_DynScheduler::SUCCEEDED;
+ return status;
}
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h
index 15abbb9760a..b5d0b87ab03 100644
--- a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h
+++ b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h
@@ -47,11 +47,15 @@ public:
virtual ~ACE_Strategy_Scheduler ();
// = virtual dtor
- status_t assign_priorities (Dispatch_Entry **dispatches, u_int count);
+ status_t assign_priorities (
+ Dispatch_Entry **dispatches, u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set);
// = 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);
+ status_t assign_subpriorities (
+ Dispatch_Entry **dispatches, u_int count,
+ ACE_Unbounded_Set<RtecScheduler::Scheduling_Anomaly *> &anomaly_set);
// = assigns dynamic and static sub-priorities to the sorted dispatch
// schedule, according to the strategy's subpriority comparisons.
diff --git a/TAO/orbsvcs/orbsvcs/Scheduler_Factory.cpp b/TAO/orbsvcs/orbsvcs/Scheduler_Factory.cpp
index 5553cde5589..c9d12bf2d0e 100644
--- a/TAO/orbsvcs/orbsvcs/Scheduler_Factory.cpp
+++ b/TAO/orbsvcs/orbsvcs/Scheduler_Factory.cpp
@@ -12,7 +12,7 @@
ACE_RCSID(orbsvcs, Scheduler_Factory, "$Id$")
-// initialize static class members
+// Initialize static class members.
RtecScheduler::Scheduler_ptr ACE_Scheduler_Factory::server_ = 0;
ACE_Scheduler_Factory::Factory_Status ACE_Scheduler_Factory::status_ =
ACE_Scheduler_Factory::UNINITIALIZED;
@@ -27,7 +27,7 @@ ACE_Scheduler_Factory::POD_RT_Info* TAO_SF_rt_info = 0;
// Helper struct, to encapsulate the singleton static server and
// ACE_TSS objects. We can't use ACE_Singleton directly, because
-// construction of ACE_Runbtime_Scheduler takes arguments.
+// construction of ACE_Runtime_Scheduler takes arguments.
struct ACE_Scheduler_Factory_Data
{
ACE_Runtime_Scheduler scheduler_;
@@ -176,22 +176,29 @@ ACE_Scheduler_Factory::server (void)
}
static char header[] =
-"// This file was automatically generated by Scheduler_Factory\n"
-"// before editing the file please consider generating it again\n"
+"// $Id $\n\n"
+"// This file was automatically generated by the Scheduler_Factory.\n"
+"// Before editing the file please consider generating it again.\n"
"\n"
"#include \"orbsvcs/Scheduler_Factory.h\"\n"
"\n";
static char footer[] =
"\n"
-"// This sets up Scheduler_Factory to use the runtime version\n"
+"// This sets up Scheduler_Factory to use the runtime version.\n"
"int scheduler_factory_setup = \n"
" ACE_Scheduler_Factory::use_runtime (configs_size, configs, infos_size, infos);\n"
"\n"
"// EOF\n";
+static char start_anomalies_found[] =
+"\n// The following scheduling anomalies were detected:\n";
+
+static char start_anomalies_none[] =
+"\n// There were no scheduling anomalies.\n";
+
static char start_infos[] =
-"static ACE_Scheduler_Factory::POD_RT_Info infos[] = {\n";
+"\n\nstatic ACE_Scheduler_Factory::POD_RT_Info infos[] = {\n";
static char end_infos[] =
"};\n\n"
@@ -201,7 +208,6 @@ static char end_infos_empty[] =
"};\n\n"
"static int infos_size = 0;\n\n";
-
static char start_configs[] =
"\nstatic ACE_Scheduler_Factory::POD_Config_Info configs[] = {\n";
@@ -216,6 +222,7 @@ static char end_configs_empty[] =
int ACE_Scheduler_Factory::dump_schedule
(const RtecScheduler::RT_Info_Set& infos,
const RtecScheduler::Config_Info_Set& configs,
+ const RtecScheduler::Scheduling_Anomaly_Set& anomalies,
const char* file_name,
const char* rt_info_format,
const char* config_info_format)
@@ -223,7 +230,7 @@ int ACE_Scheduler_Factory::dump_schedule
u_int i;
char entry_point [BUFSIZ];
- // default format for printing RT_Info output
+ // Default format for printing RT_Info output.
if (rt_info_format == 0)
{
rt_info_format = "{%20s, %10d, %10d, %10d, "
@@ -234,7 +241,7 @@ int ACE_Scheduler_Factory::dump_schedule
"(RtecScheduler::Info_Type) %d }";
}
- // default format for printing Config_Info output
+ // Default format for printing Config_Info output.
if (config_info_format == 0)
{
config_info_format = " { %10d, %10d, "
@@ -252,20 +259,51 @@ int ACE_Scheduler_Factory::dump_schedule
}
ACE_OS::fprintf(file, header);
- // print out operation QoS info
+ // Indicate anomalies encountered during scheduling.
+
+ ACE_OS::fprintf(file, (anomalies.length () > 0
+ ? start_anomalies_found
+ : start_anomalies_none));
+
+ for (i = 0; i < anomalies.length (); ++i)
+ {
+ const RtecScheduler::Scheduling_Anomaly& anomaly = anomalies[i];
+ switch (anomaly.severity)
+ {
+ case RtecScheduler::ANOMALY_FATAL:
+ ACE_OS::fprintf(file, "FATAL: ");
+ break;
+
+ case RtecScheduler::ANOMALY_ERROR:
+ ACE_OS::fprintf(file, "ERROR: ");
+ break;
+
+ case RtecScheduler::ANOMALY_WARNING:
+ ACE_OS::fprintf(file, "// WARNING: ");
+ break;
+
+ default:
+ ACE_OS::fprintf(file, "// UNKNOWN: ");
+ break;
+ }
+
+ ACE_OS::fprintf (file, "%s\n", anomaly.description);
+ }
+
+ // Print out operation QoS info.
ACE_OS::fprintf(file, start_infos);
for (i = 0; i < infos.length (); ++i)
{
if (i != 0)
{
- // Finish previous line
+ // Finish previous line.
ACE_OS::fprintf(file, ",\n");
}
const RtecScheduler::RT_Info& info = infos[i];
// Put quotes around the entry point name, exactly as it is stored.
- ACE_OS::sprintf (entry_point, "\"%s\"", (const char*) info.entry_point);
+ ACE_OS::sprintf (entry_point, "\"%s\"", (const char*) info.entry_point);
// @@ TODO Eventually the TimeT structure will be a 64-bit
// unsigned int, we will have to change this dump method then.
@@ -286,7 +324,7 @@ int ACE_Scheduler_Factory::dump_schedule
info.preemption_priority,
info.info_type);
}
- // finish last line.
+ // Finish last line.
ACE_OS::fprintf(file, "\n");
if (infos.length () > 0)
@@ -298,13 +336,13 @@ int ACE_Scheduler_Factory::dump_schedule
ACE_OS::fprintf(file, end_infos_empty);
}
- // print out queue configuration info
+ // Print out queue configuration info.
ACE_OS::fprintf(file, start_configs);
for (i = 0; i < configs.length (); ++i)
{
if (i != 0)
{
- // Finish previous line
+ // Finish previous line.
ACE_OS::fprintf(file, ",\n");
}
const RtecScheduler::Config_Info& config = configs[i];
@@ -314,7 +352,7 @@ int ACE_Scheduler_Factory::dump_schedule
config.thread_priority,
config.dispatching_type);
}
- // finish last line.
+ // Finish last line.
ACE_OS::fprintf(file, "\n");
if (configs.length () > 0)
@@ -378,7 +416,7 @@ ACE_Scheduler_Factory::set_preemption_priority
ace_scheduler_factory_data->preemption_priority_->
#if defined (HPUX) && !defined (__GNUG__)
- // aCC can't handle the typedef
+ // aCC can't handle the typedef.
operator RtecScheduler_Preemption_Priority & () = preemption_priority;
#else
operator RtecScheduler::Preemption_Priority & () = preemption_priority;
diff --git a/TAO/orbsvcs/orbsvcs/Scheduler_Factory.h b/TAO/orbsvcs/orbsvcs/Scheduler_Factory.h
index 95707b4370c..688f4360dd0 100644
--- a/TAO/orbsvcs/orbsvcs/Scheduler_Factory.h
+++ b/TAO/orbsvcs/orbsvcs/Scheduler_Factory.h
@@ -73,6 +73,19 @@ public:
RtecScheduler::Dispatching_Type dispatching_type;
};
+ struct POD_Scheduling_Anomaly
+ // = TITLE
+ // Plain Old Data for scheduling anomaly information.
+ //
+ // = DESCRIPTION
+ // This class provide us with a plain old data version of
+ // scheduling anomalies, which is used to generate error
+ // and warning lines in the runtime scheduling header output.
+ {
+ const char* description;
+ RtecScheduler::Anomaly_Severity severity;
+ };
+
static int use_config (CosNaming::NamingContext_ptr naming);
// Setup the variables needed for a config run, using the
// NamingContext to locate a Scheduler.
@@ -101,6 +114,7 @@ public:
static int dump_schedule (const RtecScheduler::RT_Info_Set& infos,
const RtecScheduler::Config_Info_Set& configs,
+ const RtecScheduler::Scheduling_Anomaly_Set& anomalies,
const char* file_name = 0,
const char* rt_info_format = 0,
const char* config_info_format = 0);
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.cpp b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.cpp
index ff3e11e5422..bd4877561d0 100644
--- a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.cpp
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.cpp
@@ -177,7 +177,7 @@ main (int argc, char *argv[])
100000, // worst case execution time
100000, // typical execution time (unused)
100000, // cached execution time
- 0, // period (100 ns)
+ 10000000, // period (100 ns)
RtecScheduler::LOW_CRITICALITY, // criticality
RtecScheduler::HIGH_IMPORTANCE, // importance
0, // quantum (unused)
@@ -185,7 +185,7 @@ main (int argc, char *argv[])
0, // OS priority
0, // Preemption subpriority
0, // Preemption priority
- RtecScheduler::REMOTE_DEPENDANT // info type
+ RtecScheduler::OPERATION // info type
},
// 20 Hz high criticality consumer
{ "high_20_C", // entry point
@@ -394,6 +394,7 @@ main (int argc, char *argv[])
RtecScheduler::RT_Info_Set_var infos;
RtecScheduler::Config_Info_Set_var configs;
+ RtecScheduler::Scheduling_Anomaly_Set_var anomalies;
#if defined (__SUNPRO_CC)
// Sun C++ 4.2 warns with the code below:
@@ -408,25 +409,27 @@ main (int argc, char *argv[])
RtecScheduler::RT_Info_Set_out infos_out (infos);
RtecScheduler::Config_Info_Set_out configs_out (configs);
+ RtecScheduler::Scheduling_Anomaly_Set_out anomalies_out (anomalies);
ACE_Scheduler_Factory::server ()->compute_scheduling
(ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
ACE_SCOPE_THREAD),
ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
ACE_SCOPE_THREAD),
- infos_out, configs_out, TAO_TRY_ENV);
+ infos_out, configs_out, anomalies_out, TAO_TRY_ENV);
#else /* ! __SUNPRO_CC */
ACE_Scheduler_Factory::server ()->compute_scheduling
(ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
ACE_SCOPE_THREAD),
ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
ACE_SCOPE_THREAD),
- infos.out (), configs.out (), TAO_TRY_ENV);
+ infos.out (), configs.out (), anomalies.out (), TAO_TRY_ENV);
#endif /* ! __SUNPRO_CC */
TAO_CHECK_ENV;
ACE_Scheduler_Factory::dump_schedule (infos.in (),
configs.in (),
+ anomalies.in (),
"Sched_Conf_Runtime.h",
format_string);
}
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.dsw b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.dsw
index bfa6054e898..829c4735f1e 100644
--- a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.dsw
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf.dsw
@@ -15,6 +15,18 @@ Package=<4>
###############################################################################
+Project: "Sched_Conf_Anomalies"=.\Sched_Conf_Anomalies.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "Sched_Conf_Runtime"=.\Sched_Conf_Runtime.dsp - Package Owner=<4>
Package=<5>
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.cpp b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.cpp
new file mode 100644
index 00000000000..891892f6cec
--- /dev/null
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.cpp
@@ -0,0 +1,385 @@
+// $Id$
+
+// This program performa a simple scheduler configuration run,
+// and dumps the results of one scheduling into a C++ header file.
+
+#include "ace/Sched_Params.h"
+#include "ace/Get_Opt.h"
+#include "tao/corba.h"
+
+#include "orbsvcs/CosNamingC.h"
+#include "orbsvcs/Scheduler_Factory.h"
+#include "orbsvcs/Naming/Naming_Utils.h"
+
+ACE_RCSID(Sched_Conf, Sched_Conf_Anomalies, "$Id$")
+
+const char* service_name = "ScheduleService";
+
+const char* format_string = "{%-12s, %d, %d, %d, %d, %8d, "
+ "(RtecScheduler::Criticality) %d, "
+ "(RtecScheduler::Importance) %d, "
+ "%d, %d, %3d, %d, %d, "
+ "(RtecScheduler::Info_Type) %d}\n";
+
+int
+parse_args (int argc, char *argv [])
+{
+ ACE_Get_Opt get_opt (argc, argv, "n:");
+ int opt;
+
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'n':
+ service_name = get_opt.optarg;
+ break;
+ case '?':
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "Usage: %s "
+ "-n service_name "
+ "\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (parse_args (argc, argv) != 0)
+ {
+ return 1;
+ }
+
+ // create initial data for supplier and consumer operations
+ const int operation_count = 8;
+ ACE_Scheduler_Factory::POD_RT_Info config_infos[operation_count] = {
+ // good supplier (no unresolved dependencies)
+ { "good_supplier", // entry point
+ 0, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 500000, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 1, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // good consumer (no unresolved dependencies)
+ { "good_consumer", // entry point
+ 1, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // supplier with unresolved remote dependencies
+ { "unresolved_remote_supplier", // entry point
+ 2, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::REMOTE_DEPENDANT // info type
+ },
+ // consumer with unresolved remote dependencies
+ { "unresolved_remote_consumer", // entry point
+ 3, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // supplier with unresolved local dependencies
+ { "unresolved_local_supplier", // entry point
+ 4, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // consumer with unresolved local dependencies
+ { "unresolved_local_consumer", // entry point
+ 5, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // consumer with unresolved local and remote dependencies
+ { "both_unresolved_consumer_1", // entry point
+ 6, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ },
+ // another consumer with unresolved
+ // local and remote dependencies
+ { "both_unresolved_consumer_2", // entry point
+ 7, // handle
+ 5000, // worst case execution time
+ 5000, // typical execution time (unused)
+ 5000, // cached execution time
+ 0, // period (100 ns)
+ RtecScheduler::HIGH_CRITICALITY, // criticality
+ RtecScheduler::LOW_IMPORTANCE, // importance
+ 0, // quantum (unused)
+ 0, // threads
+ 0, // OS priority
+ 0, // Preemption subpriority
+ 0, // Preemption priority
+ RtecScheduler::OPERATION // info type
+ }
+ };
+
+
+ TAO_TRY
+ {
+ // Initialize ORB.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "internet", TAO_TRY_ENV);
+ TAO_CHECK_ENV;
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+ if (CORBA::is_nil(poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in(), TAO_TRY_ENV);
+ TAO_CHECK_ENV;
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager (TAO_TRY_ENV);
+ TAO_CHECK_ENV;
+
+ // Initialize the naming services
+ TAO_Naming_Client my_name_client;
+ if (my_name_client.init (orb.in ()) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize "
+ "the TAO_Naming_Client. \n"),
+ -1);
+
+ if (ACE_Scheduler_Factory::use_config (my_name_client.get_context (),
+ service_name) < 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to bind to the scheduling service.\n"),
+ 1);
+ }
+ // create and initialize RT_Infos in the scheduler,
+ // make second half of array depend on first half.
+ for (int i = 0; i < operation_count; ++i)
+ {
+ // create the RT_Info
+ config_infos[i].handle =
+ ACE_Scheduler_Factory::server ()->create (config_infos[i].entry_point,
+ TAO_TRY_ENV);
+
+ // initialize the RT_Info
+ ACE_Scheduler_Factory::server ()->
+ set (config_infos[i].handle,
+ (RtecScheduler::Criticality) config_infos[i].criticality,
+ config_infos[i].worst_case_execution_time,
+ config_infos[i].typical_execution_time,
+ config_infos[i].cached_execution_time,
+ config_infos[i].period,
+ (RtecScheduler::Importance) config_infos[i].importance,
+ config_infos[i].quantum,
+ config_infos[i].threads,
+ (RtecScheduler::Info_Type) config_infos[i].info_type,
+ TAO_TRY_ENV);
+ }
+
+
+ // register dependency of good consumer on good supplier
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[1].handle,
+ config_infos[0].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+
+ // register dependency of consumer that will have unresolved remote
+ // dependencies on supplier with unresolved remote dependencies
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[3].handle,
+ config_infos[2].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+
+
+ // register dependency of consumer that will have unresolved local
+ // dependencies on supplier with unresolved local dependencies
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[5].handle,
+ config_infos[4].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+
+
+ // register dependencies on each supplier of first consumer that will
+ // have both unresolved local and unresolved remote dependencies.
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[6].handle,
+ config_infos[0].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[6].handle,
+ config_infos[2].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[6].handle,
+ config_infos[4].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+
+
+ // Register dependencies on each of the other consumers by second
+ // consumer that will have both unresolved local and unresolved remote
+ // dependencies.
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[7].handle,
+ config_infos[1].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[7].handle,
+ config_infos[3].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[7].handle,
+ config_infos[5].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+ ACE_Scheduler_Factory::server ()->
+ add_dependency (config_infos[7].handle,
+ config_infos[6].handle,
+ 1, // number of calls
+ RtecScheduler::ONE_WAY_CALL, // type of dependency
+ TAO_TRY_ENV);
+
+
+ RtecScheduler::RT_Info_Set_var infos;
+ RtecScheduler::Config_Info_Set_var configs;
+ RtecScheduler::Scheduling_Anomaly_Set_var anomalies;
+
+#if defined (__SUNPRO_CC)
+ // Sun C++ 4.2 warns with the code below:
+ // Warning (Anachronism): Temporary used for non-const
+ // reference, now obsolete.
+ // Note: Type "CC -migration" for more on anachronisms.
+ // Warning (Anachronism): The copy constructor for argument
+ // infos of type RtecScheduler::RT_Info_Set_out should take
+ // const RtecScheduler::RT_Info_Set_out&.
+ // But, this code is not CORBA conformant, because users should
+ // not define instances of _out types.
+
+ RtecScheduler::RT_Info_Set_out infos_out (infos);
+ RtecScheduler::Config_Info_Set_out configs_out (configs);
+ RtecScheduler::Scheduling_Anomaly_Set_out anomalies_out (anomalies);
+ ACE_Scheduler_Factory::server ()->compute_scheduling
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD),
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD),
+ infos_out, configs_out, anomalies_out, TAO_TRY_ENV);
+#else /* ! __SUNPRO_CC */
+ ACE_Scheduler_Factory::server ()->compute_scheduling
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD),
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD),
+ infos.out (), configs.out (), anomalies.out (), TAO_TRY_ENV);
+#endif /* ! __SUNPRO_CC */
+
+ TAO_CHECK_ENV;
+
+ ACE_Scheduler_Factory::dump_schedule (infos.in (),
+ configs.in (),
+ anomalies.in (),
+ "Sched_Conf_Anomalies_Runtime.h",
+ format_string);
+ }
+ TAO_CATCH (CORBA::SystemException, sys_ex)
+ {
+ TAO_TRY_ENV.print_exception ("SYS_EX");
+ }
+ TAO_ENDTRY;
+
+ return 0;
+}
+
+
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.dsp b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.dsp
new file mode 100644
index 00000000000..f7e9d6bad1d
--- /dev/null
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="Sched_Conf_Anomalies" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Sched_Conf_Anomalies - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Sched_Conf_Anomalies.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Sched_Conf_Anomalies.mak" CFG="Sched_Conf_Anomalies - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Sched_Conf_Anomalies - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Sched_Conf_Anomalies - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Sched_Conf_Anomalies - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "Sched_Conf_Anomalies - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Sched_Conf_Anomalies___Win32_Debug"
+# PROP BASE Intermediate_Dir "Sched_Conf_Anomalies___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\\" /I "..\..\..\\" /I "..\..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D TAO_ORBSVCS_HAS_DLL=1 /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 orbsvcsd.lib TAOd.lib aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\orbsvcs" /libpath:"..\..\..\tao" /libpath:"..\..\..\..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "Sched_Conf_Anomalies - Win32 Release"
+# Name "Sched_Conf_Anomalies - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Sched_Conf_Anomalies.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies_Runtime.h b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies_Runtime.h
new file mode 100644
index 00000000000..806c0754f76
--- /dev/null
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Anomalies_Runtime.h
@@ -0,0 +1,47 @@
+// $Id $
+
+// This file was automatically generated by the Scheduler_Factory.
+// Before editing the file please consider generating it again.
+
+#include "orbsvcs/Scheduler_Factory.h"
+
+
+// The following scheduling anomalies were detected:
+// WARNING: ST_UNRESOLVED_REMOTE_DEPENDENCIES
+ERROR: ST_UNRESOLVED_LOCAL_DEPENDENCIES
+
+
+static ACE_Scheduler_Factory::POD_RT_Info infos[] = {
+{"good_supplier", 1, 5000, 5000, 5000, 500000, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 1, 15, 0, 0, (RtecScheduler::Info_Type) 0}
+,
+{"good_consumer", 2, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 1, 0, (RtecScheduler::Info_Type) 0}
+,
+{"unresolved_remote_supplier", 3, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 3}
+,
+{"unresolved_remote_consumer", 4, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+,
+{"unresolved_local_supplier", 5, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+,
+{"unresolved_local_consumer", 6, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+,
+{"both_unresolved_consumer_1", 7, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+,
+{"both_unresolved_consumer_2", 8, 5000, 5000, 5000, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+
+};
+
+static int infos_size = sizeof(infos)/sizeof(infos[0]);
+
+
+static ACE_Scheduler_Factory::POD_Config_Info configs[] = {
+ { 0, 15, (RtecScheduler::Dispatching_Type) 2 }
+};
+
+static int configs_size = sizeof(configs)/sizeof(configs[0]);
+
+
+// This sets up Scheduler_Factory to use the runtime version.
+int scheduler_factory_setup =
+ ACE_Scheduler_Factory::use_runtime (configs_size, configs, infos_size, infos);
+
+// EOF
diff --git a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Runtime.h b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Runtime.h
index 6f0721b2376..6bdeaec9e4d 100644
--- a/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Runtime.h
+++ b/TAO/orbsvcs/tests/Sched_Conf/Sched_Conf_Runtime.h
@@ -1,42 +1,46 @@
-// $Id$
+// $Id $
-// This file was automatically generated by Scheduler_Factory
-// before editing the file please consider generating it again
+// This file was automatically generated by the Scheduler_Factory.
+// Before editing the file please consider generating it again.
#include "orbsvcs/Scheduler_Factory.h"
+
+// There were no scheduling anomalies.
+
+
static ACE_Scheduler_Factory::POD_RT_Info infos[] = {
{"high_20_S" , 1, 5000, 5000, 5000, 500000, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 1, 15, 11, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_20_S" , 2, 5000, 5000, 5000, 500000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 8, 1, (RtecScheduler::Info_Type) 0}
+{"low_20_S" , 2, 5000, 5000, 5000, 500000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 11, 1, (RtecScheduler::Info_Type) 0}
,
{"high_10_S" , 3, 10000, 10000, 10000, 1000000, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 1, 15, 8, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_10_S" , 4, 10000, 10000, 10000, 1000000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 5, 1, (RtecScheduler::Info_Type) 0}
+{"low_10_S" , 4, 10000, 10000, 10000, 1000000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 8, 1, (RtecScheduler::Info_Type) 0}
,
{"high_05_S" , 5, 20000, 20000, 20000, 2000000, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 1, 15, 5, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_05_S" , 6, 20000, 20000, 20000, 2000000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 2, 1, (RtecScheduler::Info_Type) 0}
+{"low_05_S" , 6, 20000, 20000, 20000, 2000000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 1, 2, 5, 1, (RtecScheduler::Info_Type) 0}
,
{"high_01_S" , 7, 100000, 100000, 100000, 10000000, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 2, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_01_S" , 8, 100000, 100000, 100000, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 3}
+{"low_01_S" , 8, 100000, 100000, 100000, 10000000, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 2, 1, (RtecScheduler::Info_Type) 0}
,
{"high_20_C" , 9, 0, 0, 0, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 9, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_20_C" , 10, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 6, 1, (RtecScheduler::Info_Type) 0}
+{"low_20_C" , 10, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 9, 1, (RtecScheduler::Info_Type) 0}
,
{"high_10_C" , 11, 0, 0, 0, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 6, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_10_C" , 12, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 3, 1, (RtecScheduler::Info_Type) 0}
+{"low_10_C" , 12, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 6, 1, (RtecScheduler::Info_Type) 0}
,
{"high_05_C" , 13, 0, 0, 0, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 3, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_05_C" , 14, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 0, 1, (RtecScheduler::Info_Type) 0}
+{"low_05_C" , 14, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 3, 1, (RtecScheduler::Info_Type) 0}
,
{"high_01_C" , 15, 0, 0, 0, 0, (RtecScheduler::Criticality) 3, (RtecScheduler::Importance) 1, 0, 0, 15, 0, 0, (RtecScheduler::Info_Type) 0}
,
-{"low_01_C" , 16, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 0, 0, 0, (RtecScheduler::Info_Type) 0}
+{"low_01_C" , 16, 0, 0, 0, 0, (RtecScheduler::Criticality) 1, (RtecScheduler::Importance) 3, 0, 0, 2, 0, 1, (RtecScheduler::Info_Type) 0}
};
@@ -51,8 +55,8 @@ static ACE_Scheduler_Factory::POD_Config_Info configs[] = {
static int configs_size = sizeof(configs)/sizeof(configs[0]);
-// This sets up Scheduler_Factory to use the runtime version
-int scheduler_factory_setup =
+// This sets up Scheduler_Factory to use the runtime version.
+int scheduler_factory_setup =
ACE_Scheduler_Factory::use_runtime (configs_size, configs, infos_size, infos);
// EOF