From a378239d60ff554100cfa29b7dda3d8229959ebe Mon Sep 17 00:00:00 2001 From: tchernobog Date: Tue, 4 Jul 2006 10:46:15 +0000 Subject: [PATCH] - Only schedule Threads. Ditch support for Policies deciding if they want to schedule Threads or Processes altogether - Move setter methods for last_acquisition/last_release from DynamicSchedulable to DynamicThread - Rewrite aforesaid methods, along with the respective getter methods, into Dynamic(Thread|Process) git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@708 3ecf2c5c-341e-0410-92b4-d18e462d057c --- plugins/pyloader/src/ScriptAdapter.py | 26 --------- plugins/pyloader/src/builtin-policies/fcfs.py | 3 -- plugins/pyloader/src/builtin-policies/sjf.py | 3 -- plugins/pyloader/src/python_policy.cc | 21 -------- plugins/pyloader/src/python_policy.hh | 2 - plugins/pyloader/src/sgpem.i | 25 +-------- src/backend/dynamic_process.cc | 41 ++++++++++++++ src/backend/dynamic_process.hh | 8 ++- src/backend/dynamic_schedulable.cc | 54 +------------------ src/backend/dynamic_schedulable.hh | 15 ++---- src/backend/dynamic_thread.cc | 41 +++++++++++++- src/backend/dynamic_thread.hh | 14 ++++- src/backend/policy.cc | 6 --- src/backend/policy.hh | 25 --------- src/backend/ready_queue.cc | 8 +-- src/backend/ready_queue.hh | 18 +++---- src/backend/scheduler.cc | 3 -- 17 files changed, 119 insertions(+), 194 deletions(-) diff --git a/plugins/pyloader/src/ScriptAdapter.py b/plugins/pyloader/src/ScriptAdapter.py index 1eb5583..758e910 100644 --- a/plugins/pyloader/src/ScriptAdapter.py +++ b/plugins/pyloader/src/ScriptAdapter.py @@ -82,32 +82,6 @@ class ScriptAdapter : self._ret_val = self._policy.is_preemptive() self._g_mutex.unlock() - ## @brief Asynchronously call Policy.get_time_slice() - # - # @param self The caller object - def async_get_time_slice(self): - self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self) - - def _wrap_get_time_slice(self): - thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,)) - - def _wrap_get_time_slice_callback(self): - self._ret_val = self._policy.get_time_slice() - self._g_mutex.unlock() - - ## @brief Asynchronously call Policy.wants() - # - # @param self The caller object - def async_wants(self): - self._g_mutex.lock(ScriptAdapter._wrap_wants, self) - - def _wrap_wants(self): - thread.start_new_thread(ScriptAdapter._wrap_wants_callback, (self,)) - - def _wrap_wants_callback(self): - self._ret_val = self._policy.wants() - self._g_mutex.unlock() - ## @brief Return the global shared variable with the methods' last return value def get_return_value(self): return self._ret_val diff --git a/plugins/pyloader/src/builtin-policies/fcfs.py b/plugins/pyloader/src/builtin-policies/fcfs.py index 805c62b..cbf62c1 100644 --- a/plugins/pyloader/src/builtin-policies/fcfs.py +++ b/plugins/pyloader/src/builtin-policies/fcfs.py @@ -36,9 +36,6 @@ class fcfs(Policy) : def get_time_slice(self): return -2 - def wants(self): - return policy_sorts_processes - def sort_queue(self, queue): cmpf = lambda a, b: \ a.get_arrival_time() < \ diff --git a/plugins/pyloader/src/builtin-policies/sjf.py b/plugins/pyloader/src/builtin-policies/sjf.py index 12707b3..4227d47 100644 --- a/plugins/pyloader/src/builtin-policies/sjf.py +++ b/plugins/pyloader/src/builtin-policies/sjf.py @@ -36,9 +36,6 @@ class sjf(Policy) : def get_time_slice(self): return -1 - def wants(self): - return policy_sorts_processes - def sort_queue(self, queue): cmpf = lambda a, b: \ a.get_remaining_time() < \ diff --git a/plugins/pyloader/src/python_policy.cc b/plugins/pyloader/src/python_policy.cc index bfea145..97a6b9a 100644 --- a/plugins/pyloader/src/python_policy.cc +++ b/plugins/pyloader/src/python_policy.cc @@ -160,27 +160,6 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException) return tmp < 0 ? numeric_limits::max() : static_cast(tmp); } -policy_sorts_type -PythonPolicy::wants() const throw(UserInterruptException) -{ - PyObject* retval = PyObject_CallMethod(_adapter, "async_wants", NULL); - Py_DECREF(retval); - - wait_unlock(); - - // Parse return value stored in global Python object - retval = PyObject_CallMethod(_adapter, "get_return_value", NULL); - assert(retval); - long tmp = PyInt_AsLong(retval); - Py_DECREF(retval); - - //FIXME add the MalformedPolicyException class and throw it the else - // branch instead - if(tmp == policy_sorts_threads || tmp == policy_sorts_processes) - return static_cast(tmp); - else - return policy_sorts_processes; -} void PythonPolicy::wait_unlock() const throw(UserInterruptException) diff --git a/plugins/pyloader/src/python_policy.hh b/plugins/pyloader/src/python_policy.hh index 689fb2d..e0f53f0 100644 --- a/plugins/pyloader/src/python_policy.hh +++ b/plugins/pyloader/src/python_policy.hh @@ -76,8 +76,6 @@ namespace sgpem */ int get_time_slice() const throw(UserInterruptException); - policy_sorts_type wants() const throw(UserInterruptException); - void activate() { //FIXME write code for me diff --git a/plugins/pyloader/src/sgpem.i b/plugins/pyloader/src/sgpem.i index 1338d15..1ac60d9 100644 --- a/plugins/pyloader/src/sgpem.i +++ b/plugins/pyloader/src/sgpem.i @@ -47,9 +47,6 @@ namespace std { namespace sgpem { - /** Don't get worried, order is not important! */ - enum policy_sorts_type { policy_sorts_threads, policy_sorts_processes }; - class Policy { public: virtual ~Policy() = 0; @@ -154,7 +151,7 @@ namespace sgpem { }; virtual unsigned int get_arrival_time() const = 0; - virtual unsigned int get_remaining_time() const = 0; + virtual unsigned int get_elapsed_time() const = 0; virtual int get_base_priority() const = 0; virtual int get_current_priority() const = 0; virtual unsigned int get_total_cpu_time() const = 0; @@ -198,25 +195,7 @@ namespace sgpem { size_t size() const; - // Dynamic cast to Process or to Thread so - // that Python code sees the extra-methods - %typename(out) sgpem::Schedulable*; - { - // OMG, Ponies!! - Process* proc; - Thread* thread; - if((proc = dynamic_cast($1)) != NULL) - $result = SWIG_NewPointerObj(SWIG_as_voidptr(proc), - SWIGTYPE_p_sgpem__Process, 0 | 0 ); - else if((thread = dynamic_cast($1)) != NULL) - $result = SWIG_NewPointerObj(SWIG_as_voidptr(thread), - SWIGTYPE_p_sgpem__Thread, 0 | 0 ); - else // Fall back to Schedulable* if no dynamic_cast went well: - $result = SWIG_NewPointerObj(SWIG_as_voidptr(thread), - $1_descriptor, 0 | 0 ); - } - - sgpem::Schedulable* get_item_at(position index); + sgpem::Thread* get_item_at(position index); %typename(out) sgpem::Schedulable*; diff --git a/src/backend/dynamic_process.cc b/src/backend/dynamic_process.cc index da6f2e8..1640e26 100644 --- a/src/backend/dynamic_process.cc +++ b/src/backend/dynamic_process.cc @@ -155,3 +155,44 @@ DynamicProcess::get_dynamic_threads() { return _dynamic_threads; } + +unsigned int +DynamicProcess::get_elapsed_time() const +{ + unsigned int result = 0; + for(std::vector::const_iterator it = _dynamic_threads.begin(); + it != _dynamic_threads.end(); it++) + { + result += (*it)->get_elapsed_time(); + } + return result; +} + +int +DynamicProcess::get_last_acquisition() const +{ + int result = -1; + for(std::vector::const_iterator it = _dynamic_threads.begin(); + it != _dynamic_threads.end(); it++) + { + int acq = (*it)->get_last_acquisition(); + if(result < acq) + result = acq; + } + return result; +} + +int +DynamicProcess::get_last_release() const +{ + int result = -1; + for(std::vector::const_iterator it = _dynamic_threads.begin(); + it != _dynamic_threads.end(); it++) + { + int acq = (*it)->get_last_release(); + if(result < acq) + result = acq; + } + return result; +} + diff --git a/src/backend/dynamic_process.hh b/src/backend/dynamic_process.hh index 69070a0..c7616aa 100644 --- a/src/backend/dynamic_process.hh +++ b/src/backend/dynamic_process.hh @@ -53,8 +53,12 @@ namespace sgpem void serialize(SerializeVisitor& translator) const; - virtual StaticProcess& get_core(); - virtual const StaticProcess& get_core() const; + int get_last_acquisition() const; + int get_last_release() const; + unsigned int get_elapsed_time() const; + + virtual StaticProcess& get_core(); + virtual const StaticProcess& get_core() const; // Does also the job of "add_thread" and "remove_thread" std::vector& get_dynamic_threads(); diff --git a/src/backend/dynamic_schedulable.cc b/src/backend/dynamic_schedulable.cc index 4e6551a..9b7cea1 100644 --- a/src/backend/dynamic_schedulable.cc +++ b/src/backend/dynamic_schedulable.cc @@ -28,8 +28,7 @@ using namespace sgpem; using namespace std; DynamicSchedulable::DynamicSchedulable() - : _ran_for(0), _last_acquisition(-1), - _last_release(-1), _priority_push(0) + : _priority_push(0) {} bool @@ -63,60 +62,9 @@ DynamicSchedulable::get_total_cpu_time() const return get_core().get_total_cpu_time(); } -int -DynamicSchedulable::get_priority_push() const -{ - return _priority_push; -} - -int -DynamicSchedulable::set_priority_push(int new_value) -{ - int temp = _priority_push; - _priority_push = new_value; - return temp; -} int DynamicSchedulable::get_current_priority() const { return get_base_priority() + get_priority_push(); } - -unsigned int -DynamicSchedulable::get_elapsed_time() const -{ - return _ran_for; -} - -void -DynamicSchedulable::decrease_remaining_time() -{ - _ran_for++; -} - -int -DynamicSchedulable::get_last_acquisition() const -{ - return _last_acquisition; -} - -void -DynamicSchedulable::set_last_acquisition(int instant) -{ - _last_acquisition = instant; -} - -int -DynamicSchedulable::get_last_release() const -{ - return _last_release; -} - -void -DynamicSchedulable::set_last_release(int instant) -{ - _last_release = instant; -} - - diff --git a/src/backend/dynamic_schedulable.hh b/src/backend/dynamic_schedulable.hh index 03c6c1b..12f6986 100644 --- a/src/backend/dynamic_schedulable.hh +++ b/src/backend/dynamic_schedulable.hh @@ -68,17 +68,11 @@ namespace sgpem virtual int get_current_priority() const; - virtual unsigned int get_elapsed_time() const; + virtual unsigned int get_elapsed_time() const = 0; - virtual void decrease_remaining_time(); + virtual int get_last_acquisition() const = 0; - virtual int get_last_acquisition() const; - - virtual void set_last_acquisition(int instant); - - virtual int get_last_release() const; - - virtual void set_last_release(int instant); + virtual int get_last_release() const = 0; /** \brief Returns a pointer to the schedulable object * @@ -89,9 +83,6 @@ namespace sgpem virtual const StaticSchedulable& get_core() const = 0; private: - int _ran_for; - int _last_acquisition; - int _last_release; int _priority_push; }; } diff --git a/src/backend/dynamic_thread.cc b/src/backend/dynamic_thread.cc index 8de5736..6ed594d 100644 --- a/src/backend/dynamic_thread.cc +++ b/src/backend/dynamic_thread.cc @@ -33,7 +33,8 @@ using namespace std; DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) - : DynamicSchedulable(), _core(core), _state(state_future), _parent(parent) + : DynamicSchedulable(), _core(core), _state(state_future), _parent(parent), + _ran_for(0), _last_acquisition(-1), _last_release(-1) { parent->get_threads().push_back(this); } @@ -109,3 +110,41 @@ DynamicThread::get_dynamic_requests() { return _dynamic_requests; } + + +unsigned int +DynamicThread::get_elapsed_time() const +{ + return _ran_for; +} + +void +DynamicThread::decrease_remaining_time() +{ + _ran_for++; +} + +int +DynamicThread::get_last_acquisition() const +{ + return _last_acquisition; +} + +void +DynamicThread::set_last_acquisition(int instant) +{ + _last_acquisition = instant; +} + +int +DynamicThread::get_last_release() const +{ + return _last_release; +} + +void +DynamicThread::set_last_release(int instant) +{ + _last_release = instant; +} + diff --git a/src/backend/dynamic_thread.hh b/src/backend/dynamic_thread.hh index 7a1d221..5aef98c 100644 --- a/src/backend/dynamic_thread.hh +++ b/src/backend/dynamic_thread.hh @@ -50,9 +50,17 @@ namespace sgpem DynamicProcess& get_process(); state get_state() const; - state set_state(state new_state); + int get_last_acquisition() const; + void set_last_acquisition(int instant); + + int get_last_release() const; + void set_last_release(int instant); + + unsigned int get_elapsed_time() const; + void decrease_remaining_time(); + std::vector get_requests(); void serialize(SerializeVisitor& translator) const; @@ -68,6 +76,10 @@ namespace sgpem state _state; std::vector _dynamic_requests; DynamicProcess* _parent; + + int _ran_for; + int _last_acquisition; + int _last_release; }; } diff --git a/src/backend/policy.cc b/src/backend/policy.cc index 3315676..6980191 100644 --- a/src/backend/policy.cc +++ b/src/backend/policy.cc @@ -25,12 +25,6 @@ using namespace sgpem; Policy::~Policy() {} -int -Policy::get_id() const -{ - return _id; -} - PolicyParameters& Policy::get_parameters() diff --git a/src/backend/policy.hh b/src/backend/policy.hh index 9fb0c0f..61e3bc8 100644 --- a/src/backend/policy.hh +++ b/src/backend/policy.hh @@ -32,13 +32,6 @@ namespace sgpem { - - enum policy_sorts_type - { - policy_sorts_threads, - policy_sorts_processes - }; - class Policy; /** \brief @@ -50,7 +43,6 @@ namespace sgpem class SG_DLLEXPORT Policy { public: - virtual ~Policy(); /** @@ -70,12 +62,6 @@ namespace sgpem */ virtual void sort_queue() const throw(UserInterruptException) = 0; - /** - Gets the unique identifier (id) of this Policy. - \return The Policy id. - */ - int get_id() const; - /** Gets a string description of the policy. @@ -105,16 +91,6 @@ namespace sgpem */ virtual int get_time_slice() const throw(UserInterruptException) = 0; - /** - Tell what kind of entities are scheduled by this policy. - - Because it's a pure virtual method, must be re-implemented - in concrete derived classes. - \return A SortsType value identifying the desired type for the objects - composing the queue passed to the sort_queue method. - */ - virtual policy_sorts_type wants() const throw(UserInterruptException) = 0; - virtual void activate() = 0; virtual void deactivate() = 0; @@ -130,7 +106,6 @@ namespace sgpem protected: PolicyParameters _parameters; - int _id; }; }//~ namespace sgpem diff --git a/src/backend/ready_queue.cc b/src/backend/ready_queue.cc index bbae6ab..fd91f89 100644 --- a/src/backend/ready_queue.cc +++ b/src/backend/ready_queue.cc @@ -36,7 +36,7 @@ ReadyQueue::swap(position a, position b) // Once we've done the check once, we // can assume it's safe to use "[]"; // this for performance reasons. - Schedulable* temp = _scheds.at(a); + Thread* temp = _scheds.at(a); _scheds[a] = _scheds.at(b); _scheds[b] = temp; } @@ -49,7 +49,7 @@ ReadyQueue::size() const } -sgpem::Schedulable& +sgpem::Thread& ReadyQueue::get_item_at(position index) throw (std::out_of_range) { @@ -59,7 +59,7 @@ ReadyQueue::get_item_at(position index) void -ReadyQueue::append(Schedulable& schedulable) +ReadyQueue::append(Thread& thread) { - _scheds.push_back(&schedulable); + _scheds.push_back(&thread); } diff --git a/src/backend/ready_queue.hh b/src/backend/ready_queue.hh index 50ad424..69fc3b4 100644 --- a/src/backend/ready_queue.hh +++ b/src/backend/ready_queue.hh @@ -29,7 +29,7 @@ namespace sgpem { class ReadyQueue; - class Schedulable; + class Thread; class SG_DLLEXPORT ReadyQueue { @@ -37,14 +37,14 @@ namespace sgpem typedef unsigned int position; typedef unsigned int size_t; - void swap(position a, position b) throw (std::out_of_range); - size_t size() const; - Schedulable& get_item_at(position index) throw (std::out_of_range); - void append(Schedulable& schedulable); - - private: - typedef std::vector Schedulables; - Schedulables _scheds; + void swap(position a, position b) throw (std::out_of_range); + size_t size() const; + Thread& get_item_at(position index) throw (std::out_of_range); + void append(Thread& schedulable); + + private: + typedef std::vector Threads; + Threads _scheds; }; } diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index ef3839d..07125c8 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -182,10 +182,7 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup // should maybe be done here as the first thing, instead than // directly when selecting them if(running_thread != NULL) - { running_thread->decrease_remaining_time(); - running_thread->get_process().decrease_remaining_time(); - } // 4a. Requests for the running thread exhausted if(running_thread != NULL) {