diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-21 04:05:34 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-21 04:05:34 +0000 |
commit | 536b5a992f2a1fa9d1619a9a6f07ee692aa24895 (patch) | |
tree | 3ecf1016bdd0dd9067939219a37bc3c9f8b29b5f | |
parent | 98589c17f95464c0d6f8d424ec6d256952d5fde4 (diff) | |
download | ATCD-536b5a992f2a1fa9d1619a9a6f07ee692aa24895.tar.gz |
added Scheduler_Generic
-rw-r--r-- | TAO/local/bin/Scheduling_Service/Scheduler_Generic.cpp | 528 | ||||
-rw-r--r-- | TAO/local/bin/Scheduling_Service/Scheduler_Generic.h | 135 | ||||
-rw-r--r-- | TAO/local/bin/Scheduling_Service/Scheduler_Generic.i | 21 |
3 files changed, 684 insertions, 0 deletions
diff --git a/TAO/local/bin/Scheduling_Service/Scheduler_Generic.cpp b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.cpp new file mode 100644 index 00000000000..67f87d30cba --- /dev/null +++ b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.cpp @@ -0,0 +1,528 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.cpp +// +// = CREATION DATE +// 19 November 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#include "ace/Sched_Params.h" + +#include "Scheduler_Generic.h" + +#if ! defined (__ACE_INLINE__) +#include "Scheduler_Generic.i" +#endif /* __ACE_INLINE__ */ + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// static functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// Structure for storing the RT_Info information for each task, per mode. +struct Mode_Entry +{ + RtecScheduler::RT_Info *rt_info_; + u_long start_time_; // microseconds + u_long stop_time_; // microseconds + + Mode_Entry() : + rt_info_ (0), + start_time_ (0), + stop_time_ (0) + { + } + + Mode_Entry(RtecScheduler::RT_Info *const rt_info, + const u_long start_time = 0, + const u_long stop_time = 0) : + rt_info_ (rt_info), + start_time_ (start_time), + stop_time_ (stop_time) + { + } + + ~Mode_Entry () {} + + Mode_Entry &operator= (const Mode_Entry &entry) + { + if (this != &entry) + { + rt_info_ = entry.rt_info_; + start_time_ = entry.start_time_; + stop_time_ = entry.stop_time_; + } + + return *this; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// class Scheduler_Generic member functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +Scheduler_Generic::Scheduler_Generic () : + Scheduler (), + handles_ (0), + // Set the minimum priority to that for the current platform. This + // shouldn't be necessary, but UPSingleProcessorOrb::initialize_reactors + // creates threads before the Event Channel calls Scheduler::init (). + minimum_priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD)), + increasing_priority_ (-1), + task_entries_ () +{ +} + + +Scheduler_Generic::~Scheduler_Generic () +{ + reset (); +} + + +void +Scheduler_Generic::reset () +{ +} + +Scheduler::status_t +Scheduler_Generic::lookup_rt_info (handle_t handle, + RT_Info*& rtinfo) +{ + if (handle < 0 || (size_t) handle > task_entries_.size ()) + { + return ST_UNKNOWN_TASK; + } + RT_Info*** entry; + ACE_Unbounded_Set_Iterator <RT_Info **> i (task_entries_); + while (i.next (entry) != 0) + { + i.advance (); + RT_Info** array = *entry; + if (array[0]->handle == handle) + { + rtinfo = array[0]; + return SUCCEEDED; + } + } + + return ST_UNKNOWN_TASK; +} + + +Scheduler::status_t +Scheduler_Generic::register_task (RT_Info *rt_info [], + const u_int number_of_modes, + handle_t &handle) +{ + status_t ret; + + // try to store the new task's information . . . + switch (task_entries_.insert (rt_info)) + { + case 0 : // successfully inserted + { + rt_info [0]->handle = (handle = ++handles_); + + // assigned the same handle to the RT_Info for each of its modes + for (u_int i = 1; i < number_of_modes; ++i) + { + if (rt_info [i] != 0) + rt_info [i]->handle = handle; + } + + if (number_of_modes > modes ()) + { + modes (number_of_modes); + } + + ret = SUCCEEDED; + + if (output_level () >= 5) + { + ACE_OS::printf ("registered task \"%s\" with RT_Info starting " + "at %X\n", + (const char*)rt_info[0]->entry_point, + (void *) rt_info[0]); + } + } + break; + + case 1 : // the entry had already been inserted + handle = 0; + ret = ST_TASK_ALREADY_REGISTERED; + break; + + default : + // case -1 : insert failed, probably because virtual memory exhaused + handle = 0; + ret = ST_VIRTUAL_MEMORY_EXHAUSTED; + break; + } + + return ret; +} + + +void +Scheduler_Generic::init (const int minimum_priority, + const int maximum_priority, + const char *runtime_filename, + const char *rt_info_filename, + const char *timeline_filename) +{ + minimum_priority_ = minimum_priority; + maximum_priority_ = maximum_priority; + runtime_filename_ = runtime_filename; + rt_info_filename_ = rt_info_filename; + timeline_filename_ = timeline_filename; +} + + +Scheduler::status_t +Scheduler_Generic::schedule (void) +{ + ACE_Guard<LOCK> ace_mon (lock_); + + // here goes . . . + + increasing_priority_ = maximum_priority_ >= minimum_priority_; + + status_t status = NOT_SCHEDULED; + + // store number of tasks, based on registrations + tasks (task_entries_.size ()); + + if (output_level () > 0) + { + print_schedule (); + } + + if (runtime_filename_ != 0 && + (status == SUCCEEDED || status == ST_UTILIZATION_BOUND_EXCEEDED)) + { + status = store_schedule (runtime_filename_); + } + + if ((status == SUCCEEDED || status == ST_UTILIZATION_BOUND_EXCEEDED) && rt_info_filename_) + { + status = store_rt_info (rt_info_filename_); + } + + // If there was a failure, (try to) remove the output files. + if (! (status == SUCCEEDED || status == ST_UTILIZATION_BOUND_EXCEEDED)) + { + if (runtime_filename_ && unlink ((char *) runtime_filename_) + && errno != ENOENT) + { + ACE_OS::perror ("Scheduler_Generic::schedule (); " + "unable to remove schedule file"); + } + if (rt_info_filename_ && unlink ((char *) rt_info_filename_) && + errno != ENOENT) + { + ACE_OS::perror ("Scheduler_Generic::schedule (); " + "unable to remove rt_info file"); + } + } + + return status; +} + + +int +Scheduler_Generic::priority (const handle_t handle, + OS_Thread_Priority &priority, + Sub_Priority &subpriority, + Preemption_Priority &preemption_prio, + const mode_t requested_mode) const +{ + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (requested_mode); + + priority = minimum_priority_; + subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; + preemption_prio = ACE_Scheduler_MAX_PREEMPTION_PRIORITY; + + if (output_level () >= 3) + { + ACE_OS::printf ("preemption_prio %d: min %d, pri %d, min_pri %d\n", + preemption_prio, minimum_priority_queue (), + priority, minimum_priority_); + } + + return 0; +} + + +void +Scheduler_Generic::print_schedule () +{ +} + + +Scheduler::status_t +Scheduler_Generic::store_schedule (const char *filename) +{ + u_int i; + RT_Info ***entry; + FILE *const file = ACE_OS::fopen (filename, "w"); + + if (file) + { + ACE_OS::fprintf (file, "\ +// Automatically generated \"%s\"\n\ +\n\ +#include \"Scheduler_Runtime.h\"\n\ +\n\ +static const unsigned int MODES = %u;\n\ +static const unsigned int TASKS = %u;\n\ +static const unsigned int THREADS = %u;\n\ +static const unsigned int MINIMUM_PRIORITY_QUEUE = %u;\n\ +\n\ +int\n\ +Scheduler_Runtime_registered_tasks_ [TASKS] = { 0 };\n\ +\n\ +const char *\n\ +Scheduler_Runtime_task_names_ [TASKS] =\n\ + {\n\ +", filename, + modes (), + tasks (), + threads (), + minimum_priority_queue ()); + + ACE_Unbounded_Set_Iterator <RT_Info **> + task_entries_i (task_entries_); + i = 0; + while (task_entries_i.next (entry) != 0) + { + task_entries_i.advance (); + ACE_OS::fprintf (file, " \"%s\"%s\n", + (const char*) (*entry) [0]->entry_point, + ++i == tasks () ? "" : ","); + } + + ACE_OS::fprintf (file, "\ + };\n\ +\n\ +int\n\ +Scheduler_Runtime_priorities_ [MODES][TASKS][3] =\n\ + {\n\ +"); + + for (i = 0; i < modes (); ++i) + { + ACE_OS::fprintf (file, " { /* mode %u */\n", i); + + ACE_Unbounded_Set_Iterator <RT_Info **> + task_entries_i (task_entries_); + u_int j = 0; + while (task_entries_i.next (entry) != 0) + { + task_entries_i.advance (); + + RtecScheduler::OS_Priority priority; + RtecScheduler::Sub_Priority subpriority; + RtecScheduler::Preemption_Priority preemption_prio; + this->priority (0, priority, subpriority, preemption_prio, j); + + ACE_OS::fprintf (file, " \"%s\"%s\n", + (const char*) (*entry) [0]->entry_point, + j + 1 == tasks () ? "" : ","); + + ACE_OS::fprintf (file, " { %d, %d, %u }%s\n", + priority, + subpriority, + preemption_prio, + ++j == tasks () ? "" : ","); + } + ACE_OS::fprintf (file, " }%s /* end mode %u */\n", + i == modes () - 1 ? "" : ",", i); + } + + ACE_OS::fprintf (file, "\ + };\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::modes ()\n\ +{\n\ + return MODES;\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::tasks ()\n\ +{\n\ + return TASKS;\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::threads ()\n\ +{\n\ + return THREADS;\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::minimum_priority_queue ()\n\ +{\n\ + return MINIMUM_PRIORITY_QUEUE;\n\ +}\n\ +\n\ +const char *\n\ +Scheduler_Runtime::task_name (const unsigned int handle)\n\ +{\n\ + return Scheduler_Runtime_task_names_ [handle - 1];\n\ +}\n\ +\n\ +int\n\ +Scheduler_Runtime::priority (const unsigned int mode,\n\ + const unsigned int handle)\n\ +{\n\ + return Scheduler_Runtime_priorities_ [mode][handle - 1][0];\n\ +}\n\ +\n\ +int\n\ +Scheduler_Runtime::subpriority (const unsigned int mode,\n\ + const unsigned int handle)\n\ +{\n\ + return Scheduler_Runtime_priorities_ [mode][handle - 1][1];\n\ +}\n\ +\n\ +int\n\ +Scheduler_Runtime::preemption_prio (const unsigned int mode,\n\ + const unsigned int handle)\n\ +{\n\ + return Scheduler_Runtime_priorities_ [mode][handle - 1][2];\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::config ()\n\ +{\n\ + return 0;\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::find (const char *operation_name)\n\ +{\n\ + for (unsigned int i = 0; i < TASKS; ++i)\n\ + if (! ACE_OS::strcmp (operation_name,\n\ + Scheduler_Runtime_task_names_ [i]))\n\ + return i + 1;\n\ +\n\ + return 0;\n\ +}\n\ +\n\ +unsigned int\n\ +Scheduler_Runtime::register_task (const unsigned int task)\n\ +{\n\ + if (Scheduler_Runtime_registered_tasks_ [task - 1] == 1)\n\ + {\n\ + return 0;\n\ + }\n\ + else\n\ + {\n\ + Scheduler_Runtime_registered_tasks_ [task - 1] = 1;\n\ + return task;\n\ + }\n\ +}\n\ +\n\ +"); + + if (ACE_OS::fprintf (file, "// EOF\n") > 0 && + ACE_OS::fclose (file) == 0) + { + return SUCCEEDED; + } + else + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } + } + else + { + return UNABLE_TO_OPEN_SCHEDULE_FILE; + } +} + + +Scheduler::status_t +Scheduler_Generic::store_rt_info (const char *filename) +{ + FILE *file = ACE_OS::fopen (filename, "w"); + if (file) + { + const time_t now = ACE_OS::time (0); + + (void) ACE_OS::fprintf (file, + "# RT_Info provided for \"%s\" %s" + "# Version 1.1\n" + "# Format for each entry:\n" + "# entry name\n" + "# handle\n" + "# worst case execution time\n" + "# typical execution time\n" + "# cached execution time\n" + "# period\n" + "# importance\n" + "# quantum\n" + "# begin dependencies\n" + "# number of dependencies\n" + "# entry name, number of calls " + "(one of these lines per dependency, if any)\n" + "# end dependencies\n" + "# priority\n" + "# order within priority\n\n" + "%u modes\n%u operations\n\n", + filename, ACE_OS::ctime (&now), + modes (), tasks ()); + + RT_Info ***entry; + ACE_Unbounded_Set_Iterator <RT_Info **> + task_entries_i (task_entries_); + while (task_entries_i.next (entry) != 0) + { + task_entries_i.advance (); + export ((*entry) [0], file); + } + } + else + { + return UNABLE_TO_OPEN_SCHEDULE_FILE; + } + + if (ACE_OS::fprintf (file, "\n# end of file\n", 1) > 0 && + ACE_OS::fclose (file) == 0) + { + return SUCCEEDED; + } + else + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<RtecScheduler::RT_Info **>; +template class ACE_Unbounded_Set<RtecScheduler::RT_Info **>; +template class ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info **>; +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + + +// EOF diff --git a/TAO/local/bin/Scheduling_Service/Scheduler_Generic.h b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.h new file mode 100644 index 00000000000..37c09f6b12d --- /dev/null +++ b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.h @@ -0,0 +1,135 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.h +// +// = CREATION DATE +// 19 November 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#if ! defined (SCHEDULER_INTERNAL_H) +#define SCHEDULER_INTERNAL_H + +#include "Scheduler.h" + +class Scheduler_Generic : public ACE_Scheduler + // = TITLE + // Implementation of an off-line scheduler. + // + // = DESCRIPTION + // Schedules tasks, assigning the same priority to all of them. +{ +public: + Scheduler_Generic (); + virtual ~Scheduler_Generic (); + + // = Initialize the scheduler. + virtual void init (const int minimum_priority, + const int maximum_priority, + const char *runtime_filename = 0, + const char *rt_info_filename = 0, + const char *timeline_filename = 0); + + // = Registers a task. + virtual status_t register_task (RT_Info *[], + const u_int number_of_modes, + handle_t &handle); + + virtual status_t lookup_rt_info (handle_t handle, + RT_Info* &rtinfo); + // Obtains an RT_Info based on its "handle". + + // = Computes the schedule. + virtual status_t schedule (void); + + // = Access a thread priority. + virtual int priority (const handle_t handle, + OS_Thread_Priority &priority, + Sub_Priority &subpriority, + Preemption_Priority &preemption_prio, + const mode_t = CURRENT_MODE) const; + // Defines "priority" as the priority that was assigned to the Task that + // was assigned "handle", for the specified mode. Defines "subpriority" + // as the relative ordering (due to dependencies) within the priority. + // Returns 0 on success, or 1 if an invalid mode or handle are supplied. + +private: + u_int handles_; + // The number of task handles dispensed so far. + + int minimum_priority_; + // The minimum priority value that the application specified (in + // its call to init ()). + + int maximum_priority_; + // The maximum priority value that the application specified (in + // its call to init ()). + + const char *runtime_filename_; + // Destination file of Scheduler output from the configuration run. + + const char *rt_info_filename_; + // Destination file of all rt_info data from the configuration run. + + const char *timeline_filename_; + // The destination of the timeline. + + int increasing_priority_; + // Set to 1 if priority values increase with increasing priority, + // such as on Solaris and Win32, or 0 if they decrease, such as on + // VxWorks. + + ACE_Unbounded_Set <RT_Info **> task_entries_; + // Collection of known tasks. + +#if defined (ACE_HAS_THREADS) + typedef ACE_Recursive_Thread_Mutex LOCK; +#else + typedef ACE_Null_Mutex LOCK; +#endif /* ACE_HAS_THREADS */ + + LOCK lock_; + // This protects access to the scheduler during configuration runs. + + + /////////////////////////////////////// + // member functions for internal use // + /////////////////////////////////////// + + void reset (); + // Prepare for another schedule computation, but do not + // disturb the "output" (priorities that have already been assigned). + + void print_schedule (); + // Display the schedule, task-by-task. + + status_t store_schedule (const char *filename); + // Store the schedule in the named file. + + status_t store_rt_info (const char *filename); + // Export all RT_Info to the named file. + + ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic (const Scheduler_Generic &)) + ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic &operator= ( + const Scheduler_Generic &)) +}; + + +#if defined (__ACE_INLINE__) +#include "Scheduler_Generic.i" +#endif /* __ACE_INLINE__ */ + +#endif /* SCHEDULER_INTERNAL_H */ + + +// EOF diff --git a/TAO/local/bin/Scheduling_Service/Scheduler_Generic.i b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.i new file mode 100644 index 00000000000..71e3695dc35 --- /dev/null +++ b/TAO/local/bin/Scheduling_Service/Scheduler_Generic.i @@ -0,0 +1,21 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.i +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + + +// EOF + |