- 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:
tchernobog 2006-07-04 10:46:15 +00:00
parent 736aa25456
commit a378239d60
17 changed files with 119 additions and 194 deletions

View File

@ -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

View File

@ -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() < \

View File

@ -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() < \

View File

@ -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)

View File

@ -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

View File

@ -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*;

View File

@ -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;
}

View File

@ -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<DynamicThread*>& get_dynamic_threads();

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -25,12 +25,6 @@ using namespace sgpem;
Policy::~Policy()
{}
int
Policy::get_id() const
{
return _id;
}
PolicyParameters&
Policy::get_parameters()

View File

@ -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

View File

@ -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);
}

View File

@ -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<Schedulable*> 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<Thread*> Threads;
Threads _scheds;
};
}

View File

@ -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) {