summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp
new file mode 100644
index 00000000000..79234617c6f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp
@@ -0,0 +1,264 @@
+//=============================================================================
+/**
+ * @file Scheduler.cpp
+ *
+ * $Id$
+ *
+ * @author David Levine
+ */
+//=============================================================================
+
+
+#include "ace/Sched_Params.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Sched/Scheduler.h"
+#include "ace/OS_NS_stdio.h"
+
+#include "ace/Lock_Adapter_T.h"
+
+ACE_RCSID(Sched, Scheduler, "$Id$")
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class Scheduler static members
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+const ACE_Scheduler::mode_t ACE_Scheduler::CURRENT_MODE = 0xFFFFFFFF;
+
+ACE_Scheduler *ACE_Scheduler::instance_ = 0;
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class ACE_Scheduler static functions
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void
+ACE_Scheduler::output (FILE *file, const status_t status)
+{
+ switch (status)
+ {
+ case NOT_SCHEDULED :
+ ACE_OS::fprintf (file, "NOT_SCHEDULED");
+ break;
+ case SUCCEEDED :
+ ACE_OS::fprintf (file, "SUCCEEDED");
+ break;
+ case ST_TASK_ALREADY_REGISTERED :
+ ACE_OS::fprintf (file, "TASK_ALREADY_REGISTERED");
+ break;
+ case ST_VIRTUAL_MEMORY_EXHAUSTED :
+ ACE_OS::fprintf (file, "VIRTUAL_MEMORY_EXHAUSTED");
+ break;
+ case ST_UNKNOWN_TASK :
+ ACE_OS::fprintf (file, "UNKNOWN_TASK");
+ break;
+ case INVALID_MODE :
+ ACE_OS::fprintf (file, "INVALID_MODE");
+ break;
+ case MODE_COUNT_MISMATCH :
+ ACE_OS::fprintf (file, "MODE_COUNT_MISMATCH");
+ break;
+ case TASK_COUNT_MISMATCH :
+ ACE_OS::fprintf (file, "TASK_COUNT_MISMATCH");
+ break;
+ case INVALID_PRIORITY :
+ ACE_OS::fprintf (file, "INVALID_PRIORITY");
+ break;
+
+ // The following are only used during scheduling (in the case of
+ // off-line scheduling, they are only used prior to runtime).
+ // To save a little code space (280 bytes on g++ 2.7.2/Solaris 2.5.1),
+ // we could conditionally compile them so that they're not in the
+ // runtime version.
+ case ST_UTILIZATION_BOUND_EXCEEDED :
+ ACE_OS::fprintf (file, "UTILIZATION_BOUND_EXCEEDED");
+ break;
+ case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS :
+ ACE_OS::fprintf (file, "INSUFFICIENT_THREAD_PRIORITY_LEVELS");
+ break;
+ case ST_CYCLE_IN_DEPENDENCIES :
+ ACE_OS::fprintf (file, "CYCLE_IN_DEPENDENCIES");
+ break;
+ case UNABLE_TO_OPEN_SCHEDULE_FILE :
+ ACE_OS::fprintf (file, "UNABLE_TO_OPEN_SCHEDULE_FILE");
+ break;
+ case UNABLE_TO_WRITE_SCHEDULE_FILE :
+ ACE_OS::fprintf (file, "UNABLE_TO_WRITE_SCHEDULE_FILE");
+ break;
+ // End of config-only status values.
+
+ default:
+ ACE_OS::fprintf (file, "UNKNOWN STATUS: %d", status);
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// class ACE_Scheduler member functions
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+ACE_Scheduler::ACE_Scheduler () :
+ minimum_priority_queue_ (0), // Could initialize this to -1, but it's
+ // unsigned and we don't really need to
+ // distinguish between no queues and one
+ // queue.
+ modes_ (0),
+ tasks_ (0),
+ threads_ (0),
+ mode_ (0),
+ status_ (NOT_SCHEDULED),
+ output_level_ (0)
+{
+}
+
+
+ACE_Scheduler::~ACE_Scheduler ()
+{
+}
+
+
+// ************************************************************
+
+ACE_Scheduler::status_t
+ACE_Scheduler::get_rt_info (Object_Name name,
+ RT_Info* &rtinfo)
+{
+ handle_t handle;
+
+ // This makes a copy. We can optimize this with our own string
+ // class.
+ ACE_CString lookup (name);
+ // Search the map for the <name>. If found, return the RT_Info.
+ RT_Info **info_array = 0;
+ if (info_collection_.find (lookup, info_array) >= 0)
+ {
+ rtinfo = info_array[0];
+ // If we find it, return.
+ return SUCCEEDED;
+ }
+ else
+ // Otherwise, make one, bind it, and register it.
+ {
+ rtinfo = new RT_Info;
+ rtinfo->entry_point = name;
+ // Create and array (size one) of RT_Info*
+ info_array = new RT_Info*[1];
+ info_array[0] = rtinfo;
+ // Bind the rtinfo to the name.
+ if (info_collection_.bind (lookup, info_array) != 0)
+ {
+ delete rtinfo;
+ delete info_array;
+ rtinfo = 0;
+ return FAILED; // Error!
+ }
+ else
+ {
+ // Register the array.
+ status_t result = this->register_task (info_array, 1, handle);
+ if (result == SUCCEEDED)
+ {
+ rtinfo->handle = handle;
+ return ST_UNKNOWN_TASK; // Didn't find it, but made one!
+ }
+ else
+ {
+ rtinfo->handle = 0;
+ return FAILED;
+ }
+ }
+ }
+}
+
+int ACE_Scheduler::number_of_dependencies(RT_Info* rt_info)
+{
+ return rt_info->dependencies.length();
+}
+
+int ACE_Scheduler::number_of_dependencies(RT_Info& rt_info)
+{
+ return rt_info.dependencies.length();
+}
+
+int ACE_Scheduler::add_dependency(RT_Info* rt_info,
+ const Dependency_Info& d)
+{
+ // ACE_DEBUG ((LM_DEBUG, "Sched (%t) adding dependency to: %s\n",
+ // (const char*)rt_info->entry_point));
+ RtecScheduler::Dependency_Set& set = rt_info->dependencies;
+ int l = set.length();
+ set.length(l + 1);
+ set[l] = d;
+ return 0;
+}
+
+void ACE_Scheduler::export_to_file (RT_Info* info, FILE* file)
+{
+ ACE_Scheduler::export_to_file (*info, file);
+}
+
+void ACE_Scheduler::export_to_file (RT_Info& info, FILE* file)
+{
+ // The divide-by-1 is for ACE_U_LongLong support.
+ (void) ACE_OS::fprintf (file,
+ ACE_TEXT("%s\n%d\n")
+ ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT("\n")
+ ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT("\n")
+ ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT("\n")
+ ACE_TEXT("%d\n%d\n")
+ ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT("\n")
+ ACE_TEXT("%u\n# begin dependencies\n%d\n"),
+ (const char*)info.entry_point,
+ info.handle,
+ ORBSVCS_Time::to_hrtime (info.worst_case_execution_time) / 1,
+ ORBSVCS_Time::to_hrtime (info.typical_execution_time) / 1,
+ ORBSVCS_Time::to_hrtime (info.cached_execution_time) / 1,
+ info.period,
+ info.importance,
+ ORBSVCS_Time::to_hrtime (info.quantum) / 1,
+ info.threads,
+ number_of_dependencies(info));
+
+ for (int i = 0; i < number_of_dependencies(info); ++i)
+ {
+ RT_Info tmp;
+ // TODO: info.dependencies [i].rt_info >>= &tmp;
+ (void) ACE_OS::fprintf (file, "%s, %d\n",
+ (const char*)tmp.entry_point,
+ info.dependencies[i].number_of_calls);
+
+ }
+
+ (void) ACE_OS::fprintf (file, "# end dependencies\n%d\n%d\n\n",
+ info.priority,
+ info.preemption_subpriority);
+
+
+}
+
+int
+ACE_Scheduler::dispatch_configuration (const Preemption_Priority & p_priority,
+ OS_Thread_Priority & priority,
+ Dispatching_Type & d_type)
+{
+ // look up the stored configuration info for the given priority level
+ Config_Info *config_info;
+ if (lookup_config_info (p_priority, config_info) != SUCCEEDED)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Config info for priority %lu could not be found\n",
+ p_priority),
+ -1);
+ }
+
+ priority = config_info->thread_priority;
+ d_type = config_info->dispatching_type;
+
+ return 0;
+}
+ // provide the thread priority and queue type for the given priority level