diff --git a/src/backend/default_resource_policy_manager.cc b/src/backend/default_resource_policy_manager.cc index d3b56e6..8be6689 100644 --- a/src/backend/default_resource_policy_manager.cc +++ b/src/backend/default_resource_policy_manager.cc @@ -31,8 +31,6 @@ DefaultResourcePolicyManager DefaultResourcePolicyManager::_default_instance; DefaultResourcePolicyManager::DefaultResourcePolicyManager() { - ResourcePolicy * lifo = new ResourcePolicyLiFo(); - _policies.push_back(lifo); ResourcePoliciesGatekeeper::get_instance().register_manager(this); // Includes default policies. _policies.push_back(new ResourcePolicyLiFo()); diff --git a/src/backend/resource_policy_lifo.cc b/src/backend/resource_policy_lifo.cc index d0efd0f..c7bfe82 100644 --- a/src/backend/resource_policy_lifo.cc +++ b/src/backend/resource_policy_lifo.cc @@ -54,10 +54,30 @@ ResourcePolicyLiFo::enforce(Environment& environment, Environment::SubRequestQue typedef SubRequestQueue::iterator It; for (It i = old_queue.begin(); i != old_queue.end(); i++) { - // just rebuilds the queue by now. - queue.push_back(*i); + // allocated ones remain allocated + if((**i).get_state() == Request::state_allocated) + queue.push_back(*i); } + + + bool inserted = false; + typedef SubRequestQueue::iterator It; + for (It i = old_queue.begin(); i != old_queue.end(); i++) + { + // allocated ones remain allocated + if((**i).get_state() != Request::state_allocated) + { + // non-allocated ones go after the newly arrived + if(!inserted) + { + queue.push_back(&sr); + inserted = true; + } + if (*i != &sr) + queue.push_back(*i); + } + } printf("\nResourcePolicy 'LiFo' has terminated."); } diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index 22aef36..3cf9473 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -69,6 +69,8 @@ static void raise_new_requests(DynamicThread& running_thread, ConcreteEnvironmen static void look_for_mutant_request_states(ConcreteEnvironment& environment, unsigned int& alive_threads); static void determine_subr_allocable_status(const DynamicRequest& req, DynamicSubRequest& subr, const Resource& res, SubRequestQueue& queue); +static void determine_subr_allocable_status(const Resource& res, SubRequestQueue& queue); + // --------------------------------------------------------- @@ -185,14 +187,21 @@ raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environme /// TODO: right here, right now we should call the resource policy to /// update the queue. Updates the state of the subrequest depending /// on the position in the queue, as explained before. - //resource_policy.enforce(environment, queue, cur_subr); + resource_policy.enforce(environment, queue, cur_subr); // Get the number of places for the corresponding resource Resource& resource = *environment.get_resources().find(rkey)->second; + + // WARNING: adding a new request may require updating the status of ALL other + // requests in the queue + determine_subr_allocable_status(resource, queue); + + // after that, check if it is globally allocable. // See if the subrequest is allocable or unallocable, and set its state. // It's important that the subrequest has already been added to the queue. - determine_subr_allocable_status(cur_req, cur_subr, resource, queue); +// determine_subr_allocable_status(cur_req, cur_subr, resource, queue); + } //~ for(over subrequests) } //~ if(request is future and is time to allocate it) @@ -214,9 +223,10 @@ raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environme case Request::state_allocable: for(Iseq it_dsrs = const_iseq(subreqs); it_dsrs; ++it_dsrs) { + DynamicSubRequest& subreq = **it_dsrs; assert(subreq.get_state() == Request::state_allocable); - +/* // Move this request up the queue, to the back of the allocated // subrequests. This is mainly for display. :-) // The rest of the queue sorting business is up to the resource policy. @@ -229,7 +239,7 @@ raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environme SubRequestQueue::iterator this_subreq = find(alloc_it, queue.end(), &subreq); assert(this_subreq != queue.end()); swap(*alloc_it, *this_subreq); - +*/ subreq.set_state(Request::state_allocated); } break; @@ -258,8 +268,11 @@ determine_subr_allocable_status(const DynamicRequest& req, DynamicSubRequest& su unsigned int total_places = res.get_places(); unsigned int free_places = total_places; unsigned int needed_places = 0; + + unsigned int position_in_queue = 0; + bool too_far_in_the_queue = false; for(Iseq queue_it = const_iseq(queue); - queue_it && free_places >= needed_places; queue_it++) + queue_it && free_places >= needed_places; queue_it++, position_in_queue++) { SubRequest& sr = **queue_it; if(sr.get_state() == Request::state_allocated) @@ -270,16 +283,20 @@ determine_subr_allocable_status(const DynamicRequest& req, DynamicSubRequest& su // Okay, this won't win a beauty contest... if(&sr.get_request() == &req) needed_places++; + // Well, and what about this, then? + if(&sr == &subr && position_in_queue + 1 > total_places) + too_far_in_the_queue = true; + } //~ for(over subrequest queue) // If the number of places this thread need for a resource are // less or equal the places left free, it's allocable. - if(needed_places <= free_places) + if(needed_places <= free_places && !too_far_in_the_queue) subr.set_state(Request::state_allocable); else { subr.set_state(Request::state_unallocable); - +/* // Okay, this is difficult to understand, so read carefully: // when we make a subrequest unallocable, it means that the // whole request is unallocable. However, it may happen that @@ -296,10 +313,32 @@ determine_subr_allocable_status(const DynamicRequest& req, DynamicSubRequest& su if(&x.get_request() == &req && x.get_state() == Request::state_allocable) x.set_state(Request::state_unallocable); } +*/ } + } +// The following loop updates the states of the subrequests depending +// on their position in the queue +void +determine_subr_allocable_status(const Resource& res, SubRequestQueue& queue) +{ + unsigned int total_places = res.get_places(); + unsigned int position_in_queue = 0; + for(Iseq queue_it = const_iseq(queue); + queue_it; queue_it++, position_in_queue++) + { + DynamicSubRequest& sr = (DynamicSubRequest&) **queue_it; + if (sr.get_state() == Request::state_allocated) + continue; + if(position_in_queue + 1 > total_places) + sr.set_state(Request::state_unallocable); + else + sr.set_state(Request::state_allocable); + } //~ for(over subrequest queue) +} + // This function checks if there are some allocable or unallocable // requests that should change their state according to the previous // step of the simulation. It also put previously blocked threads @@ -333,7 +372,8 @@ look_for_mutant_request_states(ConcreteEnvironment& environment, // Update the state of the subrequest, either from allocable to // unallocable or vice-versa - determine_subr_allocable_status(req, subr, *res_it->second, queue); +// determine_subr_allocable_status(req, subr, *res_it->second, queue); + determine_subr_allocable_status(*res_it->second, queue); // TODO: The following is a moderately expensive operation // to do here. See if we can move it somewhere else. diff --git a/src/gui_builder.cc b/src/gui_builder.cc index 4ee9b8a..141f34c 100644 --- a/src/gui_builder.cc +++ b/src/gui_builder.cc @@ -532,6 +532,7 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) _refXml->get_widget("SimulationScrolledWindow", simulation_window); SimulationWidget& simulation_widget = *manage(new SimulationWidget(Simulation::get_instance())); simulation_window->add(simulation_widget); + simulation_widget.set_show_threads(true); simulation_widget.show(); // Why this works, and SimulationWidget doesn't ?? diff --git a/src/holt_container_window.cc b/src/holt_container_window.cc index 340a52a..95e0e56 100644 --- a/src/holt_container_window.cc +++ b/src/holt_container_window.cc @@ -11,6 +11,7 @@ using namespace sgpem; add(_holt_widget); _holt_widget.set_scaling_mode(CairoWidget::scaling_min); _holt_widget.show(); + _holt_widget.set_show_threads(true); //set_keep_above(); }