- 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
This commit is contained in:
parent
736aa25456
commit
a378239d60
|
@ -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
|
||||
|
|
|
@ -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() < \
|
||||
|
|
|
@ -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() < \
|
||||
|
|
|
@ -160,27 +160,6 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException)
|
|||
return tmp < 0 ? numeric_limits<int>::max() : static_cast<int>(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<policy_sorts_type>(tmp);
|
||||
else
|
||||
return policy_sorts_processes;
|
||||
}
|
||||
|
||||
void
|
||||
PythonPolicy::wait_unlock() const throw(UserInterruptException)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Process*>($1)) != NULL)
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(proc),
|
||||
SWIGTYPE_p_sgpem__Process, 0 | 0 );
|
||||
else if((thread = dynamic_cast<Thread*>($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*;
|
||||
|
||||
|
|
|
@ -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<DynamicThread*>::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<DynamicThread*>::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<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
|
||||
it != _dynamic_threads.end(); it++)
|
||||
{
|
||||
int acq = (*it)->get_last_release();
|
||||
if(result < acq)
|
||||
result = acq;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ namespace sgpem
|
|||
|
||||
void serialize(SerializeVisitor& translator) 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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Request*> get_requests();
|
||||
|
||||
void serialize(SerializeVisitor& translator) const;
|
||||
|
@ -68,6 +76,10 @@ namespace sgpem
|
|||
state _state;
|
||||
std::vector<DynamicRequest*> _dynamic_requests;
|
||||
DynamicProcess* _parent;
|
||||
|
||||
int _ran_for;
|
||||
int _last_acquisition;
|
||||
int _last_release;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,12 +25,6 @@ using namespace sgpem;
|
|||
Policy::~Policy()
|
||||
{}
|
||||
|
||||
int
|
||||
Policy::get_id() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
|
||||
PolicyParameters&
|
||||
Policy::get_parameters()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
namespace sgpem
|
||||
{
|
||||
class ReadyQueue;
|
||||
class Schedulable;
|
||||
class Thread;
|
||||
|
||||
class SG_DLLEXPORT ReadyQueue
|
||||
{
|
||||
|
@ -39,12 +39,12 @@ namespace sgpem
|
|||
|
||||
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);
|
||||
Thread& get_item_at(position index) throw (std::out_of_range);
|
||||
void append(Thread& schedulable);
|
||||
|
||||
private:
|
||||
typedef std::vector<Schedulable*> Schedulables;
|
||||
Schedulables _scheds;
|
||||
typedef std::vector<Thread*> Threads;
|
||||
Threads _scheds;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue