sgpemv2/src/backend/concrete_process_statistics.cc
elvez 6d54f886f1 - Fixed portability issues. I'm curious to know where that programmer learnt about 'roundf' and 'uint', anyway...
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1153 3ecf2c5c-341e-0410-92b4-d18e462d057c
2006-09-14 17:42:15 +00:00

208 lines
5.7 KiB
C++

// src/backend/concrete_process_statistics.cc - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "concrete_process_statistics.hh"
#include "concrete_thread_statistics.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/thread.hh>
#include <iostream>
using namespace std;
using namespace sgpem;
/**
The constructor executes all calculations examinating or only the Thred object,
or the whole History
\param core The process whose statistics we are going to calculate
\param instant The instant statistics will refer to
\param _threads_stats The statistics of the threads belonging to "core"
*/
ConcreteProcessStatistics::ConcreteProcessStatistics(const Process* core, const int& instant):
_core(core)
{
//retrieve threads statistics necessary to calculate "core"'s statistics
vector<const Thread*> threads = core->get_threads();
for (unsigned int i_t = 0; i_t < threads.size(); i_t++)
_threads_stats.push_back(ConcreteThreadStatistics(threads[i_t], instant));
//inizialize variables
_total_inactivity = 0;
_execution_time = 0;
_response_time = -1;
_turn_around = 0;
_resource_usage_time = 0;
_resource_waitings_time = 0;
_average_response_time = 0;
int min_reponse = -1; //useful for _response_time
int arrived_threads = 0; //useful for _average_response_time
bool someone_began = false; //useful for _response_time
//iterate through threads statistics
vector<ConcreteThreadStatistics>::const_iterator i;
for(i = _threads_stats.begin(); i != _threads_stats.end(); i++)
{
Thread* t = const_cast<Thread*>((*i).get_core());
if (t->get_process() == *core)
{ //found a thread belonging to "core"
_execution_time += (*i).get_execution_time();
_resource_usage_time += (*i).get_resource_usage_time();
if ((*i).get_response_time() != -1)
{
_average_response_time += (*i).get_response_time();
arrived_threads++;
}
if ((*i).get_response_time() != -1 && someone_began == false)
{
someone_began = true;
min_reponse = (*i).get_response_time();
}
if(someone_began && (*i).get_response_time() != -1 && (*i).get_response_time() + (*i).get_real_arrival_time() < min_reponse)
min_reponse = (*i).get_response_time() + (*i).get_real_arrival_time();
if ((*i).get_real_arrival_time() + (*i).get_execution_time() + (*i).get_total_inactivity() > _turn_around)
_turn_around = (*i).get_real_arrival_time() + (*i).get_execution_time() + (*i).get_total_inactivity();
}
}
//******* AAARRRGGHH!!!
//We have to iterate the whole History ONLY to retreive _resource_waitings_time !!
//
const History& hist = Simulation::get_instance().get_history();
for (int time=0; time < instant; time++)
{
const Environment& env = hist.get_environment_at(time);
const vector<Process*> procs = env.get_processes();
for (unsigned int i_p=0; i_p < procs.size(); i_p++)
if (*procs[i_p] == *core && procs[i_p]->get_state() == Schedulable::state_blocked)
_resource_waitings_time++;
}
//set other variables
if(core->get_total_cpu_time() != 0)
_execution_progress = (_execution_time*100) / core->get_total_cpu_time();
else
_execution_progress = 0;
_total_inactivity = _turn_around - _execution_time;
if (_turn_around == 0)
_efficiency = -1;
else
_efficiency = (_execution_time*100)/_turn_around;
_response_time = min_reponse;
if (arrived_threads != 0)
_average_response_time = (float)((int)((_average_response_time/arrived_threads)*100))/100;
}
ConcreteProcessStatistics::~ConcreteProcessStatistics()
{
}
int
ConcreteProcessStatistics::get_execution_time() const
{
return _execution_time;
}
int
ConcreteProcessStatistics::get_execution_progress() const
{
return _execution_progress;
}
int
ConcreteProcessStatistics::get_total_inactivity() const
{
return _total_inactivity;
}
int
ConcreteProcessStatistics::get_response_time() const
{
return _response_time;
}
int
ConcreteProcessStatistics::get_turn_around() const
{
return _turn_around;
}
int
ConcreteProcessStatistics::get_efficiency() const
{
return _efficiency;
}
int
ConcreteProcessStatistics::get_resource_usage_time() const
{
return _resource_usage_time;
}
int
ConcreteProcessStatistics::get_resource_waitings_time() const
{
return _resource_waitings_time;
}
float
ConcreteProcessStatistics::get_average_response_time() const
{
return _average_response_time;
}
const Process*
ConcreteProcessStatistics::get_core() const
{
return _core;
}
/**
\warning Don't delete these pointers!!
\warning These pointers are not valid anymore after the destruction of "this"
*/
vector<const ThreadStatistics*>
ConcreteProcessStatistics::get_threads_statistics() const
{
vector<const ThreadStatistics*> rit;
for (unsigned int i=0; i < _threads_stats.size(); i++)
rit.push_back(&_threads_stats[i]);
return rit;
}