- Implement a couple of helper methods into Dynamic(Sub)Request to
make life easier to Scheduler - Go on implementing a bit more of Scheduler::step_forward() - Remove "places" from SubRequest git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@778 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
53073295d5
commit
14b5b66b3c
|
@ -362,14 +362,13 @@ ConcreteHistory::add_request(Thread& owner,
|
|||
DynamicSubRequest&
|
||||
ConcreteHistory::add_subrequest(Request& request,
|
||||
resource_key_t resource_key,
|
||||
time_t duration,
|
||||
size_t places)
|
||||
time_t duration)
|
||||
{
|
||||
reset(false);
|
||||
|
||||
DynamicRequest& dyn_request = dynamic_cast<DynamicRequest&>(request);
|
||||
|
||||
StaticSubRequest* core = new StaticSubRequest(resource_key, duration, places);
|
||||
StaticSubRequest* core = new StaticSubRequest(resource_key, duration);
|
||||
DynamicSubRequest* subreq = new DynamicSubRequest(core, &dyn_request);
|
||||
|
||||
dyn_request.get_subrequests().push_back(subreq);
|
||||
|
|
|
@ -81,8 +81,7 @@ namespace sgpem
|
|||
|
||||
virtual DynamicSubRequest& add_subrequest(Request& request,
|
||||
resource_key_t resource_key,
|
||||
time_t duration,
|
||||
size_t places = 1);
|
||||
time_t duration);
|
||||
|
||||
virtual void reset(bool notify = true);
|
||||
|
||||
|
|
|
@ -35,8 +35,7 @@ using namespace std;
|
|||
|
||||
DynamicRequest::DynamicRequest(StaticRequest *core,
|
||||
DynamicThread* owner) :
|
||||
_static_request(core), _dynamic_thread(owner),
|
||||
_state(state_ready)
|
||||
_static_request(core), _dynamic_thread(owner)
|
||||
{
|
||||
assert(core != NULL);
|
||||
assert(owner != NULL);
|
||||
|
@ -47,8 +46,7 @@ DynamicRequest::DynamicRequest(StaticRequest *core,
|
|||
}
|
||||
|
||||
DynamicRequest::DynamicRequest(const DynamicRequest& other, DynamicThread* owner) :
|
||||
_static_request(other._static_request), _dynamic_thread(owner),
|
||||
_state(other._state)
|
||||
_static_request(other._static_request), _dynamic_thread(owner)
|
||||
{
|
||||
typedef vector<DynamicSubRequest*> SubReqVec;
|
||||
|
||||
|
@ -96,6 +94,7 @@ DynamicRequest::get_dynamic_subrequests()
|
|||
return _dynamic_subrequests;
|
||||
}
|
||||
|
||||
|
||||
DynamicThread&
|
||||
DynamicRequest::get_thread()
|
||||
{
|
||||
|
@ -111,16 +110,42 @@ DynamicRequest::get_instant() const
|
|||
Request::state
|
||||
DynamicRequest::get_state() const
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
typedef std::vector<DynamicSubRequest*> SubReqs;
|
||||
|
||||
state result = state_future;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Only for debug:
|
||||
bool at_least_once = false;
|
||||
#endif // ~NDEBUG
|
||||
|
||||
Request::state
|
||||
DynamicRequest::set_state(state new_state)
|
||||
{
|
||||
state temp = _state;
|
||||
_state = new_state;
|
||||
return temp;
|
||||
const SubReqs& sreqs = _dynamic_subrequests;
|
||||
for(SubReqs::const_iterator it = sreqs.begin(); it != sreqs.end(); it++)
|
||||
{
|
||||
SubRequest& cur = **it;
|
||||
|
||||
switch(cur.get_state())
|
||||
{
|
||||
case state_allocated:
|
||||
return state_allocated;
|
||||
case state_unallocable:
|
||||
return state_unallocable;
|
||||
default:
|
||||
|
||||
#ifndef NDEBUG
|
||||
// We want to be sure that all subrequests
|
||||
// have the same state since state_allocable,
|
||||
// state_terminated and state_future are mutually
|
||||
// exclusive
|
||||
if(at_least_once)
|
||||
assert(result == cur.get_state());
|
||||
at_least_once = true;
|
||||
#endif //~ NDEBUG
|
||||
|
||||
result = cur.get_state();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@ namespace sgpem
|
|||
unsigned int get_instant() const;
|
||||
|
||||
state get_state() const;
|
||||
state set_state(state new_state);
|
||||
|
||||
void serialize(SerializeVisitor& translator) const;
|
||||
|
||||
|
@ -72,7 +71,6 @@ namespace sgpem
|
|||
|
||||
memory::smart_ptr<StaticRequest> _static_request;
|
||||
DynamicThread* _dynamic_thread;
|
||||
state _state;
|
||||
std::vector<DynamicSubRequest*> _dynamic_subrequests;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "dynamic_sub_request.hh"
|
||||
#include "dynamic_request.hh"
|
||||
#include "request.hh"
|
||||
#include "serialize_visitor.hh"
|
||||
|
||||
#include "smartp.tcc"
|
||||
|
@ -32,7 +33,7 @@ using namespace sgpem;
|
|||
DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core,
|
||||
DynamicRequest* owner) :
|
||||
_static_subrequest(core), _owner(owner),
|
||||
_queue_position(-1)
|
||||
_queue_position(-1), _ran_for(0), _state(Request::state_future)
|
||||
{
|
||||
assert(core != NULL);
|
||||
assert(owner != NULL);
|
||||
|
@ -45,7 +46,8 @@ DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core,
|
|||
DynamicSubRequest::DynamicSubRequest(const DynamicSubRequest& other,
|
||||
DynamicRequest* owner) :
|
||||
_static_subrequest(other._static_subrequest), _owner(owner),
|
||||
_queue_position(other._queue_position)
|
||||
_queue_position(other._queue_position), _ran_for(other._ran_for),
|
||||
_state(other._state)
|
||||
{
|
||||
assert(owner != NULL);
|
||||
|
||||
|
@ -74,11 +76,6 @@ DynamicSubRequest::get_resource_key() const
|
|||
return _static_subrequest->get_resource_key();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DynamicSubRequest::get_places() const
|
||||
{
|
||||
return _static_subrequest->get_places();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DynamicSubRequest::get_length() const
|
||||
|
@ -106,6 +103,41 @@ DynamicSubRequest::get_request()
|
|||
}
|
||||
|
||||
|
||||
DynamicSubRequest::state
|
||||
DynamicSubRequest::get_state() const
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
|
||||
DynamicSubRequest::state
|
||||
DynamicSubRequest::set_state(state new_state)
|
||||
{
|
||||
state temp;
|
||||
_state = new_state;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
DynamicSubRequest::get_remaining_time() const
|
||||
{
|
||||
return _static_subrequest->get_length() - _ran_for;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
DynamicSubRequest::decrease_remaining_time()
|
||||
{
|
||||
assert(_state == Request::state_allocated);
|
||||
unsigned int temp = get_remaining_time();
|
||||
if(temp > 0)
|
||||
_ran_for++;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DynamicSubRequest::serialize(SerializeVisitor& translator) const
|
||||
{
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#define DYNAMIC_SUB_REQUEST_HH 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "request.hh"
|
||||
#include "sub_request.hh"
|
||||
#include "dynamic_request.hh"
|
||||
#include "dynamic_resource.hh"
|
||||
|
@ -38,7 +40,7 @@ namespace sgpem
|
|||
|
||||
class SG_DLLLOCAL DynamicSubRequest : public SubRequest
|
||||
{
|
||||
public:
|
||||
public:
|
||||
DynamicSubRequest(StaticSubRequest* core,
|
||||
DynamicRequest* owner);
|
||||
DynamicSubRequest(const DynamicSubRequest& other, DynamicRequest* owner);
|
||||
|
@ -49,8 +51,6 @@ namespace sgpem
|
|||
|
||||
resource_key_t get_resource_key() const;
|
||||
|
||||
unsigned int get_places() const;
|
||||
|
||||
unsigned int get_length() const;
|
||||
|
||||
int get_queue_position() const;
|
||||
|
@ -58,6 +58,12 @@ namespace sgpem
|
|||
|
||||
virtual DynamicRequest& get_request();
|
||||
|
||||
state get_state() const;
|
||||
state set_state(state new_state);
|
||||
|
||||
unsigned int get_remaining_time() const;
|
||||
unsigned int decrease_remaining_time();
|
||||
|
||||
void serialize(SerializeVisitor& translator) const;
|
||||
|
||||
StaticSubRequest& get_core();
|
||||
|
@ -70,6 +76,8 @@ namespace sgpem
|
|||
memory::smart_ptr<StaticSubRequest> _static_subrequest;
|
||||
DynamicRequest* _owner;
|
||||
int _queue_position;
|
||||
unsigned int _ran_for;
|
||||
state _state;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -97,8 +97,7 @@ namespace sgpem
|
|||
|
||||
virtual SubRequest& add_subrequest(Request& request,
|
||||
resource_key_t resource_key,
|
||||
time_t duration,
|
||||
size_t places = 1) = 0;
|
||||
time_t duration) = 0;
|
||||
|
||||
|
||||
virtual void attach(HistoryObserver& observer);
|
||||
|
|
|
@ -35,10 +35,11 @@ namespace sgpem
|
|||
public:
|
||||
enum state
|
||||
{
|
||||
state_ready = 1 << 0,
|
||||
state_allocated = 1 << 1,
|
||||
state_future = 1 << 2,
|
||||
state_exhausted = 1 << 3
|
||||
state_unallocable = 1 << 0,
|
||||
state_allocated = 1 << 1,
|
||||
state_future = 1 << 2,
|
||||
state_exhausted = 1 << 3,
|
||||
state_allocable = 1 << 4
|
||||
};
|
||||
|
||||
virtual ~Request();
|
||||
|
@ -47,6 +48,7 @@ namespace sgpem
|
|||
|
||||
virtual std::vector<SubRequest*> get_subrequests() = 0;
|
||||
virtual unsigned int get_instant() const = 0;
|
||||
|
||||
virtual state get_state() const = 0;
|
||||
|
||||
virtual void serialize(SerializeVisitor& translator) const = 0;
|
||||
|
|
|
@ -162,8 +162,10 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
|
|||
// increasing the time elapsed of the running thread + process
|
||||
// should be done here as the first thing, instead than
|
||||
// directly after selecting them
|
||||
running_thread->decrease_remaining_time();
|
||||
if(current.get_total_cpu_time() - current.get_elapsed_time() > 0)
|
||||
running_thread->decrease_remaining_time();
|
||||
|
||||
assert(running_thread == NULL); // ... and one to bind them all.
|
||||
running_thread = ¤t; // Even if we change its state to terminated
|
||||
// 2. mark threads that used all their allotted time as terminated
|
||||
if(current.get_total_cpu_time() - current.get_elapsed_time() == 0)
|
||||
|
@ -179,41 +181,59 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
|
|||
}
|
||||
|
||||
// 4a. Look for exhausted requests for the running thread
|
||||
if(running_thread != NULL) {
|
||||
Requests& reqs = running_thread->get_dynamic_requests();
|
||||
bool running_terminated = running_thread->get_state() == Schedulable::state_terminated;
|
||||
if(running_thread != NULL)
|
||||
{
|
||||
Requests& reqs = running_thread->get_dynamic_requests();
|
||||
bool running_terminated = running_thread->get_state() == Schedulable::state_terminated;
|
||||
|
||||
for(Requests::iterator it = reqs.begin(); it != reqs.end(); it++)
|
||||
{
|
||||
DynamicRequest& rq = **it;
|
||||
if(rq.get_state() == Request::state_allocated)
|
||||
/* decrease remaining time for request */;
|
||||
|
||||
// ASK MARCO : can we implement request::decrease_remaining_time() as
|
||||
// a function that calls decrease_remaining_time() on all its subrequests,
|
||||
// that in turn never go with a remaining time < 0?
|
||||
|
||||
// If the running thread terminated uncoditionally put them in exhausted state
|
||||
if(running_terminated /* || rq.get_remaining_time() == 0 */ )
|
||||
rq.set_state(Request::state_exhausted);
|
||||
}
|
||||
|
||||
|
||||
// FIXME we lack a way to tell and/or remember for how
|
||||
// much a subrequest has been being fulfilled
|
||||
// THIS MEANS this part is NOT complete
|
||||
// We should check if a request has been fulfilled
|
||||
|
||||
// FIXME If a request was being fulfilled to the running thread,
|
||||
// we should decrease the request remaining time here.
|
||||
|
||||
// This is why we kept a ref to the old running thread,
|
||||
// even if it was terminated
|
||||
|
||||
|
||||
} //~ if running_thread != NULL
|
||||
|
||||
for(Requests::iterator r_it = reqs.begin(); r_it != reqs.end(); r_it++)
|
||||
{
|
||||
DynamicRequest& rq = **r_it;
|
||||
|
||||
// If the running thread terminated uncoditionally put them in exhausted state
|
||||
if(running_terminated)
|
||||
{
|
||||
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
||||
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
||||
(*s_it)->set_state(Request::state_exhausted);
|
||||
continue; // go to next request
|
||||
}
|
||||
|
||||
if(rq.get_state() == Request::state_allocated)
|
||||
{
|
||||
/* decrease remaining time for each allocated subrequest */
|
||||
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
||||
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
||||
{
|
||||
DynamicSubRequest& subr = **s_it;
|
||||
if(subr.get_state() == Request::state_allocated)
|
||||
subr.decrease_remaining_time();
|
||||
if(subr.get_remaining_time() == 0)
|
||||
{
|
||||
subr.set_state(Request::state_exhausted);
|
||||
|
||||
// FIXME : if exhausted, it should be taken away from the queue of the
|
||||
// requested resource
|
||||
}
|
||||
}
|
||||
}
|
||||
} //~ for(over requests)
|
||||
|
||||
// FIXME we lack a way to tell and/or remember for how
|
||||
// much a subrequest has been being fulfilled
|
||||
// THIS MEANS this part is NOT complete
|
||||
// We should check if a request has been fulfilled
|
||||
|
||||
// FIXME If a request was being fulfilled to the running thread,
|
||||
// we should decrease the request remaining time here.
|
||||
|
||||
// This is why we kept a ref to the old running thread,
|
||||
// even if it was terminated
|
||||
|
||||
|
||||
} //~ if running_thread != NULL
|
||||
|
||||
|
||||
// ---------- FIXME ----------------
|
||||
// What to do now if the simulation ended?
|
||||
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
using namespace sgpem;
|
||||
|
||||
StaticSubRequest::StaticSubRequest(resource_key_t resource_key,
|
||||
unsigned int length,
|
||||
unsigned int places) :
|
||||
unsigned int length) :
|
||||
_resource_key(resource_key),
|
||||
_length(length), _places(places)
|
||||
_length(length)
|
||||
{
|
||||
//A static request doesn't keep track of its static subrequests
|
||||
//at least for now.
|
||||
|
@ -54,12 +53,6 @@ StaticSubRequest::get_resource_key() const
|
|||
return _resource_key;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
StaticSubRequest::get_places() const
|
||||
{
|
||||
return _places;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
StaticSubRequest::get_length() const
|
||||
{
|
||||
|
|
|
@ -37,15 +37,12 @@ namespace sgpem
|
|||
typedef SubRequest::resource_key_t resource_key_t;
|
||||
|
||||
StaticSubRequest(resource_key_t resource_key,
|
||||
unsigned int length,
|
||||
unsigned int places = 1);
|
||||
unsigned int length);
|
||||
|
||||
~StaticSubRequest();
|
||||
|
||||
resource_key_t get_resource_key() const;
|
||||
|
||||
unsigned int get_places() const;
|
||||
|
||||
unsigned int get_length() const;
|
||||
|
||||
private:
|
||||
|
@ -54,7 +51,6 @@ namespace sgpem
|
|||
|
||||
resource_key_t _resource_key;
|
||||
unsigned int _length;
|
||||
unsigned int _places;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,17 +23,19 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "request.hh"
|
||||
|
||||
namespace sgpem
|
||||
{
|
||||
class SubRequest;
|
||||
class SerializeVisitor;
|
||||
class Request;
|
||||
class Resource;
|
||||
|
||||
class SG_DLLEXPORT SubRequest
|
||||
{
|
||||
public:
|
||||
typedef int resource_key_t;
|
||||
typedef Request::state state;
|
||||
|
||||
virtual ~SubRequest();
|
||||
|
||||
|
@ -41,12 +43,14 @@ namespace sgpem
|
|||
|
||||
virtual resource_key_t get_resource_key() const = 0;
|
||||
|
||||
virtual unsigned int get_places() const = 0;
|
||||
|
||||
virtual unsigned int get_length() const = 0;
|
||||
virtual unsigned int get_length() const = 0;
|
||||
|
||||
virtual int get_queue_position() const = 0;
|
||||
|
||||
virtual state get_state() const = 0;
|
||||
|
||||
virtual unsigned int get_remaining_time() const = 0;
|
||||
|
||||
virtual Request& get_request() = 0;
|
||||
|
||||
virtual void serialize(SerializeVisitor& translator) const = 0;
|
||||
|
|
|
@ -1086,11 +1086,10 @@ TextSimulation::on_add_subrequest(const Tokens& arguments)
|
|||
|
||||
CommandParameter<int> resource_key(_("resource key"), 0, INT_MAX, true, 0);
|
||||
CommandParameter<int> duration(_("duration"), 0, INT_MAX, true, 0);
|
||||
CommandParameter<int> places(_("places"), 0, INT_MAX, false, 1);
|
||||
|
||||
History& h = Simulation::get_instance().get_history();
|
||||
|
||||
h.add_subrequest(*r, resource_key.value, duration.value, places.value);
|
||||
h.add_subrequest(*r, resource_key.value, duration.value);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue