Skip to content
Snippets Groups Projects
Commit 13a4bf11 authored by Maël Madon's avatar Maël Madon
Browse files

Merge branch 'issue12' into 'master'

Better memory management and float rounding issues

See merge request !10
parents d998c533 2c6a79cd
No related branches found
No related tags found
1 merge request!10Better memory management and float rounding issues
Pipeline #5410 passed
Showing with 220 additions and 167 deletions
......@@ -32,6 +32,16 @@ Session::Session(
jobs = list<const Job *>();
}
Session::~Session()
{
for (const Job *job : jobs){
delete job;
}
jobs.clear();
preceding_sessions.clear();
following_sessions.clear();
}
Workload::~Workload()
{
deallocate();
......@@ -174,6 +184,7 @@ Job *Workload::job_from_json_object(const Value &object)
return j;
}
bool JobComparator::operator()(const Job *j1, const Job *j2) const
{
PPK_ASSERT_ERROR(j1->id.find('!') != string::npos,
......@@ -187,7 +198,11 @@ bool JobComparator::operator()(const Job *j1, const Job *j2) const
if (id1.length() == id2.length()) /* same length: lexicographic order */
return id1 < id2;
return id1.length() < id2.length();
}
bool JobComparator::operator()(Job j1, Job j2) const
{
return JobComparator::operator()(&j1, &j2);
}
bool SessionComparator::operator()(const Session *s1, const Session *s2) const
......@@ -423,7 +438,7 @@ Job *Parser::job_from_json_object(string user_name, const Value &object)
return j;
}
string Parser::json_description_string_from_job(Job *job)
string Parser::json_description_string_from_job(const Job *job)
{
PPK_ASSERT_ERROR(job->id != "", "A job must have the field 'id'.");
PPK_ASSERT_ERROR(
......
......@@ -13,7 +13,7 @@
#include <utility>
struct JobAlloc;
struct Session;
class Session;
#define DATE_NEVER -1.0
#define DATE_UNKNOWN -2.0
......@@ -53,6 +53,7 @@ struct JobAlloc
struct JobComparator
{
bool operator()(const Job *j1, const Job *j2) const;
bool operator()(Job j1, Job j2) const;
};
struct Profile
......@@ -62,8 +63,12 @@ struct Profile
std::string description;
};
struct Session
class Session
{
public:
Session(unsigned int id, double first_submit_time, unsigned int nb_jobs);
~Session();
unsigned int id;
double
original_first_submit_time; /* the submit time of the first job in this
......@@ -76,7 +81,6 @@ struct Session
std::map<Session *, double> preceding_sessions; /* pair (Session, t_time) */
std::set<Session *> following_sessions;
Session(unsigned int id, double first_submit_time, unsigned int nb_jobs);
};
struct SessionComparator
......@@ -126,7 +130,7 @@ struct Parser
static Job *job_from_json_object(
const std::string user_name, const rapidjson::Value &object);
// with format 'user-name!jobID'
static std::string json_description_string_from_job(Job *job);
static std::string json_description_string_from_job(const Job *job);
static Session *session_from_json_object(const std::string user_name,
const rapidjson::Value &object, std::list<unsigned int> *prec_sessions,
std::list<double> *tt_after_prec_sessions);
......
......@@ -2,4 +2,6 @@
#define NB_CORE_PER_MACHINE 16
#define INITIAL_MACHINE_STATE AWAKE
#define PSTATE_AWAKE 0
#define PSTATE_ASLEEP 1
\ No newline at end of file
#define PSTATE_ASLEEP 1
#define EPSILON 0.00001 /* For float rounding issues */
\ No newline at end of file
......@@ -37,6 +37,9 @@ BinPacking::BinPacking(Workload *workload, SchedulingDecision *decision,
BinPacking::~BinPacking()
{
for (auto host : listofHosts)
delete host;
listofHosts.clear();
}
std::string BinPacking::hosts_to_string(std::list<SortableHost *> listofHosts)
......
......@@ -65,6 +65,9 @@ BinPackingEnergy::BinPackingEnergy(Workload *workload,
BinPackingEnergy::~BinPackingEnergy()
{
for (auto host : listofHosts)
delete host;
listofHosts.clear();
}
std::string BinPackingEnergy::machine_state_to_string(
......
......@@ -8,6 +8,7 @@
#include "../pempek_assert.hpp"
#include "rapidjson/rapidjson.h"
#include <loguru.hpp>
#include <memory>
using namespace rapidjson;
Broker::Broker(rapidjson::Document *user_description_file)
......@@ -15,6 +16,16 @@ Broker::Broker(rapidjson::Document *user_description_file)
/* Parse description file and call constructor for each user */
if (!user_description_file->ObjectEmpty())
{
if (user_description_file->HasMember("core_limit_per_user"))
{
PPK_ASSERT_ERROR(
(*user_description_file)["core_limit_per_user"].IsInt(),
"Invalid user_description file: field "
"'core_limit_per_user' should be an int.");
core_limit_per_user
= (*user_description_file)["core_limit_per_user"].GetInt();
// otherwise, initialized at std::numeric_limits<int>::max()
}
if (user_description_file->HasMember("dm_window"))
{
const Value &dm_param = (*user_description_file)["dm_window"];
......@@ -143,8 +154,7 @@ Broker::~Broker()
{
delete it.second;
}
for (auto itr = dynamic_jobs.begin(); itr != dynamic_jobs.end(); itr++)
delete itr->second;
dynamic_jobs.clear();
users_to_wake.clear();
}
......@@ -155,10 +165,10 @@ double Broker::next_submission(double date) const
}
void Broker::jobs_to_submit(
double date, list<Job *> &jobs, list<Profile *> &profiles)
double date, list<Job> &jobs, list<const Profile *> &profiles)
{
jobs = list<Job *>();
profiles = list<Profile *>();
jobs = list<Job>();
profiles = list<const Profile *>();
User *user = user_queue.front();
double planned_date_submission = user->next_submission();
......@@ -171,15 +181,25 @@ void Broker::jobs_to_submit(
while (planned_date_submission == user->next_submission())
{
user_queue.pop_front();
list<Job *> user_jobs;
list<Profile *> user_profiles;
unsigned int nb_core_requested = 0;
list<shared_ptr<Job>> user_jobs;
list<const Profile *> user_profiles;
user->jobs_to_submit(date, user_jobs, user_profiles);
for (Job *job : user_jobs)
for (shared_ptr<Job> job : user_jobs)
{
jobs.push_back(job);
dynamic_jobs[job->id] = job;
job->status = WAITING;
nb_core_requested = nb_core_requested + job->nb_requested_resources;
if (nb_core_requested > core_limit_per_user)
{
job->status = KILLED;
}
else
{
jobs.push_back(*job);
dynamic_jobs[job->id] = job;
job->status = WAITING;
}
}
profiles.splice(profiles.end(), user_profiles);
......@@ -231,7 +251,7 @@ void Broker::update_status_if_dyn_job(
{
string user_name = job_id.substr(0, job_id.find('!'));
User *user = users[user_name];
Job *current_job = it->second;
shared_ptr<Job> current_job = it->second;
switch (status)
{
......@@ -250,7 +270,7 @@ void Broker::update_status_if_dyn_job(
/* Add potentially interested user to the map of users to wake up */
if (users_to_wake.find(user) == users_to_wake.end())
users_to_wake.emplace(user, list<Job *>());
users_to_wake.emplace(user, list<shared_ptr<Job>>());
/* ..and keep track of its recently ended jobs */
users_to_wake[user].push_back(current_job);
......@@ -265,7 +285,7 @@ void Broker::update_status_if_dyn_job(
/* Add potentially interested user to the map of users to wake up */
if (users_to_wake.find(user) == users_to_wake.end())
users_to_wake.emplace(user, list<Job *>());
users_to_wake.emplace(user, list<shared_ptr<Job>>());
/* ..and keep track of its recently ended jobs */
users_to_wake[user].push_back(current_job);
......
......@@ -34,7 +34,7 @@ public:
* @param[out] profiles The list of profiles used by the jobs, if new.
*/
void jobs_to_submit(
double date, list<Job *> &jobs, list<Profile *> &profiles);
double date, list<Job> &jobs, list<const Profile *> &profiles);
/**
* @brief Ackowledge the latest execution-related activity and forward the
......@@ -48,10 +48,11 @@ public:
private:
map<string, User *> users;
unsigned int core_limit_per_user = std::numeric_limits<int>::max();
list<User *> user_queue;
map<string, Job *> dynamic_jobs = map<string, Job *>();
map<User *, list<Job *>> users_to_wake
= map<User *, list<Job *>>();
map<string, shared_ptr<Job>> dynamic_jobs = map<string, shared_ptr<Job>>();
map<User *, list<shared_ptr<Job>>> users_to_wake
= map<User *, list<shared_ptr<Job>>>();
private:
/* Deterministic generation of seeds for users that use randomness */
......
......@@ -41,16 +41,6 @@ void DynScheduler::on_simulation_start(
/* Check for optional parameters */
if (!_variant_options->ObjectEmpty())
{
if (_variant_options->HasMember("core_limit_per_user"))
{
PPK_ASSERT_ERROR(
(*_variant_options)["core_limit_per_user"].IsInt(),
"Invalid user_description file: field "
"'core_limit_per_user' should be an int.");
core_limit_per_user
= (*_variant_options)["core_limit_per_user"].GetInt();
// otherwise, initialized at std::numeric_limits<int>::max()
}
if (_variant_options->HasMember("log_user_stats")
&& (*_variant_options)["log_user_stats"].GetBool())
{
......@@ -148,53 +138,46 @@ void DynScheduler::end_broker(double date)
void DynScheduler::submit_broker_jobs(double date)
{
std::list<Job *> jobs;
std::list<Profile *> profiles;
std::list<Job> jobs;
std::list<const Profile *> profiles;
broker->jobs_to_submit(date, jobs, profiles);
if (!profiles.empty())
if (!profiles.empty()) {
dyn_register_profiles(profiles, date);
/* Profiles won't be used anymore, free memory */
for (const Profile *profile : profiles){
delete profile;
}
}
dyn_submit(jobs, date);
}
void DynScheduler::dyn_submit(std::list<Job *> jobs, double date)
void DynScheduler::dyn_submit(std::list<Job> jobs, double date)
{
std::map<std::string, int> core_per_user;
for (Job *current_job : jobs)
for (Job current_job : jobs)
{
std::string fullID = current_job->id;
std::string fullID = current_job.id;
PPK_ASSERT_ERROR(fullID.find('!') != std::string::npos,
"Dynamicaly submitted jobs should have the format "
"Dynamically submitted jobs should have the format "
"'user_name!jobID'.");
std::string user_name = fullID.substr(0, fullID.find('!'));
fullID.erase(0, fullID.find('!') + 1);
std::string jobID = fullID;
std::string job_description
= Parser::json_description_string_from_job(&current_job);
std::string empty_profile_description
= std::string(); // has already been sent
// REFAC: move to broker
core_per_user[user_name]
= core_per_user[user_name] + current_job->nb_requested_resources;
/* Register the job to batsim */
_decision->add_submit_job(user_name, jobID, current_job.profile,
job_description, empty_profile_description, date, true);
if (core_per_user[user_name] > core_limit_per_user)
{
current_job->status = KILLED;
}
else
{
std::string job_description
= Parser::json_description_string_from_job(current_job);
std::string empty_profile_description
= std::string(); // has already been sent
/* Register the job to batsim */
_decision->add_submit_job(user_name, jobID, current_job->profile,
job_description, empty_profile_description, date, true);
}
}
}
void DynScheduler::dyn_register_profiles(
std::list<Profile *> profiles, double date)
std::list<const Profile *> profiles, double date)
{
for (auto profile : profiles)
{
......
......@@ -53,12 +53,12 @@ protected:
/**
* Dynamically registers to batsim the job `jobs` to submit.
*/
void dyn_submit(std::list<Job *> jobs, double date);
void dyn_submit(std::list<Job> jobs, double date);
/**
* Registers to batsim the profiles that will be used by the broker.
*/
void dyn_register_profiles(std::list<Profile *> profiles, double date);
void dyn_register_profiles(std::list<const Profile *> profiles, double date);
protected:
bool broker_enabled = false;
......@@ -67,6 +67,5 @@ protected:
bool next_submission_has_changed = false;
private:
int core_limit_per_user = std::numeric_limits<int>::max();
std::string log_folder = "";
};
\ No newline at end of file
......@@ -21,7 +21,7 @@ int *User::get_dm_stat()
return stat;
}
void User::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
void User::wake_on_feedback(double date, std::list<shared_ptr<Job>> &ended_jobs)
{
return;
}
......
......@@ -4,9 +4,12 @@
#include "rapidjson/document.h"
#include <list>
#include <string>
#include <memory>
#include "scheds/HARD_DEFINED_VAR.hpp"
using namespace std;
class User
{
public:
......@@ -30,17 +33,17 @@ public:
* @param[out] profiles The list of profiles used by the jobs, if new.
*/
virtual void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles)
= 0;
/* For demand response users only: */
virtual int *get_dm_stat();
/* For users reacting to feedback: */
virtual void wake_on_feedback(double date, std::list<Job *> &ended_jobs);
virtual void wake_on_feedback(double date, list<shared_ptr<Job>> &ended_jobs);
public:
std::string user_name;
string user_name;
protected:
double date_of_next_submission;
......
......@@ -5,8 +5,6 @@
#include <limits>
#include <string>
#define EPS 0.00001
/* FeedbackUser */
void FeedbackUser::init_FeedbackUser(
std::string name, const rapidjson::Value &param)
......@@ -82,13 +80,13 @@ void FeedbackUser::update_date_next_sub()
}
void FeedbackUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
jobs = std::list<Job *>();
profiles = std::list<Profile *>();
jobs = std::list<shared_ptr<Job>>();
profiles = std::list<const Profile *>();
/* Add the free sessions starting now to the list of active sessions */
while (!free_sessions.empty() && free_sessions.top()->start_time < date + EPS)
while (!free_sessions.empty() && free_sessions.top()->start_time < date + EPSILON)
{
active_sessions.push_back(free_sessions.top());
free_sessions.pop();
......@@ -110,9 +108,9 @@ void FeedbackUser::jobs_to_submit(
double offset = active_sess->start_time;
while (!job_list->empty()
&& job_list->front()->submission_time + offset < date + EPS)
&& job_list->front()->submission_time + offset < date + EPSILON)
{
Job *job = new Job(*job_list->front()); // Cast const Job * -> Job *
shared_ptr<Job> job = shared_ptr<Job>(new Job(*job_list->front())); // Cast const Job * -> shared_ptr<Job>
Profile *job_profile = new Profile();
/* Handle the job according to the user behavior. */
......@@ -150,10 +148,10 @@ void FeedbackUser::jobs_to_submit(
update_date_next_sub();
}
void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
void FeedbackUser::wake_on_feedback(double date, std::list<shared_ptr<Job>> &ended_jobs)
{
/* Propagate the info and close finished sessions */
for (Job *j : ended_jobs)
for (shared_ptr<Job>j : ended_jobs)
{
j->session->unfinished_jobs--;
PPK_ASSERT_ERROR(ongoing_job_counter > 0,
......@@ -208,7 +206,7 @@ void FBUserThinkTimeOnly::close_session(double date, Session *finished_session)
delete finished_session;
}
bool FBUserThinkTimeOnly::handle_job(double date, Job *job, Profile *profile)
bool FBUserThinkTimeOnly::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
Parser::profile_from_duration(
profile, job->profile, user_name, platform_computing_speed);
......
......@@ -17,8 +17,8 @@ public:
virtual ~FeedbackUser();
double next_submission();
virtual void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
virtual void wake_on_feedback(double date, std::list<Job *> &ended_jobs);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
virtual void wake_on_feedback(double date, std::list<shared_ptr<Job>> &ended_jobs);
protected:
/**
......@@ -44,7 +44,7 @@ protected:
* depending on the user behavior and returns if it should still be executed
* now.
*/
virtual bool handle_job(double date, Job *job, Profile *profile) = 0;
virtual bool handle_job(double date, shared_ptr<Job>job, Profile *profile) = 0;
protected:
std::string input_json;
......@@ -80,5 +80,5 @@ public:
protected:
void close_session(double date, Session *finished_session);
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job> job, Profile *profile);
};
\ No newline at end of file
......@@ -39,12 +39,12 @@ DichoIntersubmitTimeUser::~DichoIntersubmitTimeUser()
}
void DichoIntersubmitTimeUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
jobs = std::list<Job *>();
jobs = std::list<shared_ptr<Job>>();
/* The last job is still running */
if (last_job_submitted != nullptr
if (last_job_submitted
&& (last_job_submitted->status == WAITING
|| last_job_submitted->status == RUNNING))
{
......@@ -55,7 +55,7 @@ void DichoIntersubmitTimeUser::jobs_to_submit(
else
{
/* First job submitted by this user */
if (last_job_submitted == nullptr)
if (!last_job_submitted)
{
delay_between_sumbit = delay_sup; // initial delay
profiles = job_profiles_used();
......@@ -65,10 +65,10 @@ void DichoIntersubmitTimeUser::jobs_to_submit(
{
delay_sup = std::ceil(date - last_job_submitted->submission_time);
delay_between_sumbit = (delay_sup + delay_inf) / 2;
profiles = std::list<Profile *>(); // already submitted before
profiles = std::list<const Profile *>(); // already submitted before
}
Job *job = new Job();
shared_ptr<Job>job = shared_ptr<Job>(new Job());
job->id = user_name + "!" + std::to_string(job_id++);
job->profile = "100_sec";
job->submission_time = date;
......@@ -88,9 +88,9 @@ void DichoIntersubmitTimeUser::jobs_to_submit(
date_of_next_submission = DATE_NEVER;
}
std::list<Profile *> DichoIntersubmitTimeUser::job_profiles_used()
std::list<const Profile *> DichoIntersubmitTimeUser::job_profiles_used()
{
std::list<Profile *> profiles;
std::list<const Profile *> profiles;
Profile *profile0 = new Profile();
profile0->workload_name = user_name;
......@@ -142,22 +142,36 @@ RoutineGreedyUser::~RoutineGreedyUser()
{
}
bool RoutineGreedyUser::all_jobs_finished_successfully() const
bool RoutineGreedyUser::previous_jobs_succedded()
{
for (const Job *job : last_jobs_submitted)
bool res = true;
for (auto iter = last_jobs_submitted.begin();
iter != last_jobs_submitted.end();)
{
if (job->status == WAITING || job->status == RUNNING
|| job->status == KILLED)
return false;
shared_ptr<Job> job = *iter;
switch (job->status) {
case WAITING:
case RUNNING:
res = false;
iter++;
break;
case KILLED:
res = false;
iter = last_jobs_submitted.erase(iter);
break;
case FINISHED:
iter = last_jobs_submitted.erase(iter);
}
}
return true;
return res;
}
void RoutineGreedyUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
jobs = std::list<Job *>();
profiles = std::list<Profile *>();
jobs = std::list<shared_ptr<Job>>();
profiles = std::list<const Profile *>();
/* First call: just submit the initial amount of jobs */
if (first_submit)
......@@ -167,7 +181,7 @@ void RoutineGreedyUser::jobs_to_submit(
}
/* All job finished: submit twice as many jobs */
else if (all_jobs_finished_successfully())
else if (previous_jobs_succedded())
nb_jobs_to_submit
= (nb_jobs_to_submit == 0) ? 1 : nb_jobs_to_submit * 2;
......@@ -175,10 +189,9 @@ void RoutineGreedyUser::jobs_to_submit(
else
nb_jobs_to_submit /= 2;
last_jobs_submitted.clear();
for (int i = 0; i < nb_jobs_to_submit; i++)
{
Job *job = new Job();
shared_ptr<Job> job = shared_ptr<Job>(new Job());
job->id = user_name + "!" + std::to_string(job_id++);
job->profile = "100_sec";
job->submission_time = date;
......@@ -198,9 +211,9 @@ void RoutineGreedyUser::jobs_to_submit(
date_of_next_submission = DATE_NEVER;
}
std::list<Profile *> RoutineGreedyUser::job_profiles_used()
std::list<const Profile *> RoutineGreedyUser::job_profiles_used()
{
std::list<Profile *> profiles;
std::list<const Profile *> profiles;
Profile *profile0 = new Profile();
profile0->workload_name = user_name;
......@@ -246,9 +259,9 @@ ThinkTimeUser::~ThinkTimeUser()
}
void ThinkTimeUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
jobs = std::list<Job *>();
jobs = std::list<shared_ptr<Job>>();
/* Stop condition reached */
if (date > end_submit)
......@@ -258,9 +271,15 @@ void ThinkTimeUser::jobs_to_submit(
else
{
/* First job submitted by this user */
if (last_job_submitted == nullptr)
if (!last_job_submitted)
profiles = job_profiles_used();
Job *job = new Job();
else{
PPK_ASSERT_ERROR(last_job_submitted->status == FINISHED
|| last_job_submitted->status == KILLED,
"ThinkTimeUser %s called to submit, but her last job did not finish", user_name.c_str());
}
shared_ptr<Job> job = shared_ptr<Job>(new Job());
job->id = user_name + "!" + std::to_string(job_id++);
job->profile = "100_sec";
job->submission_time = date;
......@@ -271,13 +290,13 @@ void ThinkTimeUser::jobs_to_submit(
jobs.push_back(job);
/* Date of next submission unknown for now... */
date_of_next_submission = -2.0;
date_of_next_submission = DATE_UNKNOWN;
}
}
std::list<Profile *> ThinkTimeUser::job_profiles_used()
std::list<const Profile *> ThinkTimeUser::job_profiles_used()
{
std::list<Profile *> profiles;
std::list<const Profile *> profiles;
Profile *profile0 = new Profile();
profile0->workload_name = user_name;
......@@ -291,7 +310,7 @@ std::list<Profile *> ThinkTimeUser::job_profiles_used()
return profiles;
}
void ThinkTimeUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
void ThinkTimeUser::wake_on_feedback(double date, std::list<shared_ptr<Job>> &ended_jobs)
{
/* The user has been awakened: her last job terminated */
PPK_ASSERT_ERROR(last_job_submitted->status == KILLED
......
......@@ -9,23 +9,23 @@
class DichoIntersubmitTimeUser : public User
{
public:
DichoIntersubmitTimeUser(std::string name, double date_first_submit,
DichoIntersubmitTimeUser(string name, double date_first_submit,
double date_end_submit, double initial_delay);
DichoIntersubmitTimeUser(std::string name, const rapidjson::Value &param);
DichoIntersubmitTimeUser(string name, const rapidjson::Value &param);
~DichoIntersubmitTimeUser();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
protected:
std::list<Profile *> job_profiles_used();
list<const Profile *> job_profiles_used();
private:
double delay_inf = 0;
double delay_sup;
double delay_between_sumbit;
int job_id = 0;
const Job *last_job_submitted = nullptr;
shared_ptr<Job> last_job_submitted;
};
/**
......@@ -37,17 +37,17 @@ private:
class RoutineGreedyUser : public User
{
public:
RoutineGreedyUser(std::string name, double date_first_submit,
RoutineGreedyUser(string name, double date_first_submit,
double date_end_submit, double delay_between_sumbit,
int initial_nb_job);
RoutineGreedyUser(std::string name, const rapidjson::Value &param);
RoutineGreedyUser(string name, const rapidjson::Value &param);
~RoutineGreedyUser();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
protected:
std::list<Profile *> job_profiles_used();
list<const Profile *> job_profiles_used();
private:
double delay_between_sumbit;
......@@ -55,8 +55,10 @@ private:
bool first_submit = true;
int job_id = 0;
std::list<const Job *> last_jobs_submitted;
bool all_jobs_finished_successfully() const;
list<shared_ptr<Job>> last_jobs_submitted;
/* Return true if all the jobs previously submitted by the user finished
* successfully. Also delete the finished jobs. */
bool previous_jobs_succedded();
};
/**
......@@ -69,20 +71,20 @@ private:
class ThinkTimeUser : public User
{
public:
ThinkTimeUser(std::string name, double date_first_submit,
ThinkTimeUser(string name, double date_first_submit,
double date_end_submit, double think_time);
ThinkTimeUser(std::string name, const rapidjson::Value &param);
ThinkTimeUser(string name, const rapidjson::Value &param);
~ThinkTimeUser();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
void wake_on_feedback(double date, std::list<Job *> &ended_jobs);
double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
void wake_on_feedback(double date, list<shared_ptr<Job>> &ended_jobs);
protected:
std::list<Profile *> job_profiles_used();
list<const Profile *> job_profiles_used();
private:
double think_time;
int job_id = 0;
Job *last_job_submitted = nullptr;
shared_ptr<Job> last_job_submitted;
};
\ No newline at end of file
......@@ -35,25 +35,25 @@ ReplayUser::~ReplayUser()
}
void ReplayUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
jobs = std::list<Job *>();
profiles = std::list<Profile *>();
jobs = std::list<shared_ptr<Job>>();
profiles = std::list<const Profile *>();
PPK_ASSERT_ERROR(!original_trace->is_empty(),
"User %s has been called to sumbit but her job queue is empty",
user_name.c_str());
PPK_ASSERT_ERROR(original_trace->first_job()->submission_time <= date,
"First job in user %s's queue has greater sumbmission time than "
"current date",
user_name.c_str());
PPK_ASSERT_ERROR(original_trace->first_job()->submission_time < date + EPSILON,
"First job in user %s's queue has greater sumbmission time (%f) than "
"current date (%f)",
user_name.c_str(), original_trace->first_job()->submission_time, date);
/* Submit all jobs that have same submit time */
while (!original_trace->is_empty()
&& original_trace->first_job()->submission_time <= date)
&& original_trace->first_job()->submission_time < date + EPSILON)
{
/* Cast const Job * into Job * */
Job *job = new Job(*original_trace->first_job());
shared_ptr<Job> job = shared_ptr<Job>(new Job(*original_trace->first_job()));
Profile *job_profile = new Profile();
/* Handle the job according to the user behavior. */
......@@ -100,12 +100,12 @@ ReplayUserRigid::~ReplayUserRigid()
}
void ReplayUserRigid::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
bool ReplayUserRigid::handle_job(double date, Job *job, Profile *profile)
bool ReplayUserRigid::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
/* Just generate the corresponding profile */
Parser::profile_from_duration(profile, job->profile, user_name, platform_computing_speed);
......@@ -121,7 +121,7 @@ bool ReplayUserRigid::handle_job(double date, Job *job, Profile *profile)
}
/* ReplayUserReconfig */
bool ReplayUserReconfig::handle_job(double date, Job *job, Profile *profile)
bool ReplayUserReconfig::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
int orig_nb_core = job->nb_requested_resources;
......@@ -204,7 +204,7 @@ ReplayUserReconfig::~ReplayUserReconfig()
}
void ReplayUserReconfig::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
......@@ -253,7 +253,7 @@ DMUserReconfig::~DMUserReconfig()
}
void DMUserReconfig::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
......@@ -271,7 +271,7 @@ DMUserDegrad::~DMUserDegrad()
}
void DMUserDegrad::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
......@@ -289,7 +289,7 @@ DMUserRenonce::~DMUserRenonce()
}
void DMUserRenonce::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
......@@ -307,12 +307,12 @@ DMUserDelay::~DMUserDelay()
}
void DMUserDelay::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
{
ReplayUser::jobs_to_submit(date, jobs, profiles);
}
bool DMUserReconfig::handle_job(double date, Job *job, Profile *profile)
bool DMUserReconfig::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
if (dm_window->date_in_dm_window(date))
{
......@@ -356,7 +356,7 @@ bool DMUserReconfig::handle_job(double date, Job *job, Profile *profile)
return true;
}
bool DMUserDegrad::handle_job(double date, Job *job, Profile *profile)
bool DMUserDegrad::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
if (dm_window->date_in_dm_window(date))
{
......@@ -390,7 +390,7 @@ bool DMUserDegrad::handle_job(double date, Job *job, Profile *profile)
return true;
}
bool DMUserRenonce::handle_job(double date, Job *job, Profile *profile)
bool DMUserRenonce::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
if (dm_window->date_in_dm_window(date))
{
......@@ -411,7 +411,7 @@ bool DMUserRenonce::handle_job(double date, Job *job, Profile *profile)
return true;
}
bool DMUserDelay::handle_job(double date, Job *job, Profile *profile)
bool DMUserDelay::handle_job(double date, shared_ptr<Job>job, Profile *profile)
{
if (dm_window->date_in_dm_window(date))
{
......@@ -425,7 +425,8 @@ bool DMUserDelay::handle_job(double date, Job *job, Profile *profile)
/* Put job back in the queue and sort */
SortableJobOrder::UpdateInformation update_info(0);
original_trace->insert_job(job);
Job *j = new Job(); *j = *job;
original_trace->insert_job(j);
original_trace->sort_queue(&update_info);
/* Return "Do not execute now" */
......
......@@ -24,7 +24,7 @@ public:
virtual ~ReplayUser();
double next_submission();
virtual void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
/**
......@@ -38,7 +38,7 @@ protected:
* A job is read in the original trace. Handle it depending on the user
* behavior and returns if it should still be executed now.
*/
virtual bool handle_job(double date, Job *job, Profile *profile) = 0;
virtual bool handle_job(double date, shared_ptr<Job>job, Profile *profile) = 0;
virtual int *get_dm_stat();
protected:
......@@ -63,10 +63,10 @@ public:
~ReplayUserRigid();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
};
/**
......@@ -84,13 +84,13 @@ public:
~ReplayUserReconfig();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
/** Draw a random variable according to the proportions given by
* big_medium_little and reconfigure the number of cores requested
* accordingly. */
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
private:
double big, medium, little;
......@@ -127,10 +127,10 @@ public:
~DMUserReconfig();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
double alpha = 1.0; // for the speedup model
};
......@@ -146,10 +146,10 @@ public:
~DMUserDegrad();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
};
/**
......@@ -164,10 +164,10 @@ public:
~DMUserRenonce();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
};
/**
......@@ -182,8 +182,8 @@ public:
~DMUserDelay();
double next_submission();
void jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
protected:
bool handle_job(double date, Job *job, Profile *profile);
bool handle_job(double date, shared_ptr<Job>job, Profile *profile);
};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment