mirror of https://github.com/BOINC/boinc.git
- scheduler: fix memory leak (free BEST_APP_VERSION objects)
svn path=/trunk/boinc/; revision=21597
This commit is contained in:
parent
fa66519441
commit
ca239d913a
|
@ -3830,3 +3830,10 @@ David 20 May 2010
|
||||||
sched/
|
sched/
|
||||||
sched_customize.cpp
|
sched_customize.cpp
|
||||||
sched_version.cpp
|
sched_version.cpp
|
||||||
|
|
||||||
|
David 20 May 2010
|
||||||
|
- scheduler: fix memory leak (free BEST_APP_VERSION objects)
|
||||||
|
|
||||||
|
sched/
|
||||||
|
sched_types.h
|
||||||
|
sched_version.cpp
|
||||||
|
|
|
@ -105,146 +105,6 @@ struct HOST_USAGE {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// summary of a client's request for work, and our response to it
|
|
||||||
// Note: this is zeroed out in SCHEDULER_REPLY constructor
|
|
||||||
//
|
|
||||||
struct WORK_REQ {
|
|
||||||
bool anonymous_platform;
|
|
||||||
|
|
||||||
// Flags used by old-style scheduling,
|
|
||||||
// while making multiple passes through the work array
|
|
||||||
bool infeasible_only;
|
|
||||||
bool reliable_only;
|
|
||||||
bool user_apps_only;
|
|
||||||
bool beta_only;
|
|
||||||
|
|
||||||
// user preferences
|
|
||||||
bool no_cuda;
|
|
||||||
bool no_ati;
|
|
||||||
bool no_cpu;
|
|
||||||
bool allow_non_preferred_apps;
|
|
||||||
bool allow_beta_work;
|
|
||||||
std::vector<APP_INFO> preferred_apps;
|
|
||||||
|
|
||||||
bool has_reliable_version;
|
|
||||||
// whether the host has a reliable app version
|
|
||||||
|
|
||||||
int effective_ncpus;
|
|
||||||
int effective_ngpus;
|
|
||||||
|
|
||||||
// 6.7+ clients send separate requests for different resource types:
|
|
||||||
//
|
|
||||||
double cpu_req_secs; // instance-seconds requested
|
|
||||||
double cpu_req_instances; // number of idle instances, use if possible
|
|
||||||
double cuda_req_secs;
|
|
||||||
double cuda_req_instances;
|
|
||||||
double ati_req_secs;
|
|
||||||
double ati_req_instances;
|
|
||||||
inline bool need_cpu() {
|
|
||||||
return (cpu_req_secs>0) || (cpu_req_instances>0);
|
|
||||||
}
|
|
||||||
inline bool need_cuda() {
|
|
||||||
return (cuda_req_secs>0) || (cuda_req_instances>0);
|
|
||||||
}
|
|
||||||
inline bool need_ati() {
|
|
||||||
return (ati_req_secs>0) || (ati_req_instances>0);
|
|
||||||
}
|
|
||||||
inline void clear_cpu_req() {
|
|
||||||
cpu_req_secs = 0;
|
|
||||||
cpu_req_instances = 0;
|
|
||||||
}
|
|
||||||
inline void clear_gpu_req() {
|
|
||||||
cuda_req_secs = 0;
|
|
||||||
cuda_req_instances = 0;
|
|
||||||
ati_req_secs = 0;
|
|
||||||
ati_req_instances = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// older clients send send a single number, the requested duration of jobs
|
|
||||||
//
|
|
||||||
double seconds_to_fill;
|
|
||||||
|
|
||||||
// true if new-type request
|
|
||||||
//
|
|
||||||
bool rsc_spec_request;
|
|
||||||
|
|
||||||
double disk_available;
|
|
||||||
double ram, usable_ram;
|
|
||||||
double running_frac;
|
|
||||||
int njobs_sent;
|
|
||||||
|
|
||||||
// The following keep track of the "easiest" job that was rejected
|
|
||||||
// by EDF simulation.
|
|
||||||
// Any jobs harder than this can be rejected without doing the simulation.
|
|
||||||
//
|
|
||||||
double edf_reject_min_cpu;
|
|
||||||
int edf_reject_max_delay_bound;
|
|
||||||
bool have_edf_reject;
|
|
||||||
void edf_reject(double cpu, int delay_bound) {
|
|
||||||
if (have_edf_reject) {
|
|
||||||
if (cpu < edf_reject_min_cpu) edf_reject_min_cpu = cpu;
|
|
||||||
if (delay_bound> edf_reject_max_delay_bound) edf_reject_max_delay_bound = delay_bound;
|
|
||||||
} else {
|
|
||||||
edf_reject_min_cpu = cpu;
|
|
||||||
edf_reject_max_delay_bound = delay_bound;
|
|
||||||
have_edf_reject = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool edf_reject_test(double cpu, int delay_bound) {
|
|
||||||
if (!have_edf_reject) return false;
|
|
||||||
if (cpu < edf_reject_min_cpu) return false;
|
|
||||||
if (delay_bound > edf_reject_max_delay_bound) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RESOURCE disk;
|
|
||||||
RESOURCE mem;
|
|
||||||
RESOURCE speed;
|
|
||||||
RESOURCE bandwidth;
|
|
||||||
|
|
||||||
std::vector<USER_MESSAGE> no_work_messages;
|
|
||||||
std::vector<BEST_APP_VERSION*> best_app_versions;
|
|
||||||
std::vector<DB_HOST_APP_VERSION> host_app_versions;
|
|
||||||
std::vector<DB_HOST_APP_VERSION> host_app_versions_orig;
|
|
||||||
|
|
||||||
// various reasons for not sending jobs (used to explain why)
|
|
||||||
//
|
|
||||||
bool no_allowed_apps_available;
|
|
||||||
bool excessive_work_buf;
|
|
||||||
bool hr_reject_temp;
|
|
||||||
bool hr_reject_perm;
|
|
||||||
bool outdated_client;
|
|
||||||
bool no_cuda_prefs;
|
|
||||||
bool no_ati_prefs;
|
|
||||||
bool no_cpu_prefs;
|
|
||||||
bool max_jobs_on_host_exceeded;
|
|
||||||
bool max_jobs_on_host_cpu_exceeded;
|
|
||||||
bool max_jobs_on_host_gpu_exceeded;
|
|
||||||
bool no_jobs_available; // project has no work right now
|
|
||||||
|
|
||||||
//int max_jobs_per_day;
|
|
||||||
// host.max_results_day * (NCPUS + NGPUS*gpu_multiplier)
|
|
||||||
int max_jobs_per_rpc;
|
|
||||||
int njobs_on_host;
|
|
||||||
// How many jobs from this project are in progress on the host.
|
|
||||||
// Initially this is the number of "other_results"
|
|
||||||
// reported in the request message.
|
|
||||||
// If the resend_lost_results option is used,
|
|
||||||
// it's set to the number of outstanding results taken from the DB
|
|
||||||
// (those that were lost are resent).
|
|
||||||
// As new results are sent, it's incremented.
|
|
||||||
int njobs_on_host_cpu;
|
|
||||||
// same, but just CPU jobs.
|
|
||||||
int njobs_on_host_gpu;
|
|
||||||
// same, but just GPU jobs.
|
|
||||||
int max_jobs_on_host;
|
|
||||||
int max_jobs_on_host_cpu;
|
|
||||||
int max_jobs_on_host_gpu;
|
|
||||||
void update_for_result(double seconds_filled);
|
|
||||||
void add_no_work_message(const char*);
|
|
||||||
void get_job_limits();
|
|
||||||
};
|
|
||||||
|
|
||||||
// a description of a sticky file on host.
|
// a description of a sticky file on host.
|
||||||
//
|
//
|
||||||
struct FILE_INFO {
|
struct FILE_INFO {
|
||||||
|
@ -441,6 +301,153 @@ struct DISK_LIMITS {
|
||||||
double min_free;
|
double min_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// summary of a client's request for work, and our response to it
|
||||||
|
// Note: this is zeroed out in SCHEDULER_REPLY constructor
|
||||||
|
//
|
||||||
|
struct WORK_REQ {
|
||||||
|
bool anonymous_platform;
|
||||||
|
|
||||||
|
// Flags used by old-style scheduling,
|
||||||
|
// while making multiple passes through the work array
|
||||||
|
bool infeasible_only;
|
||||||
|
bool reliable_only;
|
||||||
|
bool user_apps_only;
|
||||||
|
bool beta_only;
|
||||||
|
|
||||||
|
// user preferences
|
||||||
|
bool no_cuda;
|
||||||
|
bool no_ati;
|
||||||
|
bool no_cpu;
|
||||||
|
bool allow_non_preferred_apps;
|
||||||
|
bool allow_beta_work;
|
||||||
|
std::vector<APP_INFO> preferred_apps;
|
||||||
|
|
||||||
|
bool has_reliable_version;
|
||||||
|
// whether the host has a reliable app version
|
||||||
|
|
||||||
|
int effective_ncpus;
|
||||||
|
int effective_ngpus;
|
||||||
|
|
||||||
|
// 6.7+ clients send separate requests for different resource types:
|
||||||
|
//
|
||||||
|
double cpu_req_secs; // instance-seconds requested
|
||||||
|
double cpu_req_instances; // number of idle instances, use if possible
|
||||||
|
double cuda_req_secs;
|
||||||
|
double cuda_req_instances;
|
||||||
|
double ati_req_secs;
|
||||||
|
double ati_req_instances;
|
||||||
|
inline bool need_cpu() {
|
||||||
|
return (cpu_req_secs>0) || (cpu_req_instances>0);
|
||||||
|
}
|
||||||
|
inline bool need_cuda() {
|
||||||
|
return (cuda_req_secs>0) || (cuda_req_instances>0);
|
||||||
|
}
|
||||||
|
inline bool need_ati() {
|
||||||
|
return (ati_req_secs>0) || (ati_req_instances>0);
|
||||||
|
}
|
||||||
|
inline void clear_cpu_req() {
|
||||||
|
cpu_req_secs = 0;
|
||||||
|
cpu_req_instances = 0;
|
||||||
|
}
|
||||||
|
inline void clear_gpu_req() {
|
||||||
|
cuda_req_secs = 0;
|
||||||
|
cuda_req_instances = 0;
|
||||||
|
ati_req_secs = 0;
|
||||||
|
ati_req_instances = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// older clients send send a single number, the requested duration of jobs
|
||||||
|
//
|
||||||
|
double seconds_to_fill;
|
||||||
|
|
||||||
|
// true if new-type request
|
||||||
|
//
|
||||||
|
bool rsc_spec_request;
|
||||||
|
|
||||||
|
double disk_available;
|
||||||
|
double ram, usable_ram;
|
||||||
|
double running_frac;
|
||||||
|
int njobs_sent;
|
||||||
|
|
||||||
|
// The following keep track of the "easiest" job that was rejected
|
||||||
|
// by EDF simulation.
|
||||||
|
// Any jobs harder than this can be rejected without doing the simulation.
|
||||||
|
//
|
||||||
|
double edf_reject_min_cpu;
|
||||||
|
int edf_reject_max_delay_bound;
|
||||||
|
bool have_edf_reject;
|
||||||
|
void edf_reject(double cpu, int delay_bound) {
|
||||||
|
if (have_edf_reject) {
|
||||||
|
if (cpu < edf_reject_min_cpu) edf_reject_min_cpu = cpu;
|
||||||
|
if (delay_bound> edf_reject_max_delay_bound) edf_reject_max_delay_bound = delay_bound;
|
||||||
|
} else {
|
||||||
|
edf_reject_min_cpu = cpu;
|
||||||
|
edf_reject_max_delay_bound = delay_bound;
|
||||||
|
have_edf_reject = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool edf_reject_test(double cpu, int delay_bound) {
|
||||||
|
if (!have_edf_reject) return false;
|
||||||
|
if (cpu < edf_reject_min_cpu) return false;
|
||||||
|
if (delay_bound > edf_reject_max_delay_bound) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RESOURCE disk;
|
||||||
|
RESOURCE mem;
|
||||||
|
RESOURCE speed;
|
||||||
|
RESOURCE bandwidth;
|
||||||
|
|
||||||
|
std::vector<USER_MESSAGE> no_work_messages;
|
||||||
|
std::vector<BEST_APP_VERSION*> best_app_versions;
|
||||||
|
std::vector<BEST_APP_VERSION*> all_best_app_versions;
|
||||||
|
std::vector<DB_HOST_APP_VERSION> host_app_versions;
|
||||||
|
std::vector<DB_HOST_APP_VERSION> host_app_versions_orig;
|
||||||
|
|
||||||
|
// various reasons for not sending jobs (used to explain why)
|
||||||
|
//
|
||||||
|
bool no_allowed_apps_available;
|
||||||
|
bool excessive_work_buf;
|
||||||
|
bool hr_reject_temp;
|
||||||
|
bool hr_reject_perm;
|
||||||
|
bool outdated_client;
|
||||||
|
bool no_cuda_prefs;
|
||||||
|
bool no_ati_prefs;
|
||||||
|
bool no_cpu_prefs;
|
||||||
|
bool max_jobs_on_host_exceeded;
|
||||||
|
bool max_jobs_on_host_cpu_exceeded;
|
||||||
|
bool max_jobs_on_host_gpu_exceeded;
|
||||||
|
bool no_jobs_available; // project has no work right now
|
||||||
|
|
||||||
|
//int max_jobs_per_day;
|
||||||
|
// host.max_results_day * (NCPUS + NGPUS*gpu_multiplier)
|
||||||
|
int max_jobs_per_rpc;
|
||||||
|
int njobs_on_host;
|
||||||
|
// How many jobs from this project are in progress on the host.
|
||||||
|
// Initially this is the number of "other_results"
|
||||||
|
// reported in the request message.
|
||||||
|
// If the resend_lost_results option is used,
|
||||||
|
// it's set to the number of outstanding results taken from the DB
|
||||||
|
// (those that were lost are resent).
|
||||||
|
// As new results are sent, it's incremented.
|
||||||
|
int njobs_on_host_cpu;
|
||||||
|
// same, but just CPU jobs.
|
||||||
|
int njobs_on_host_gpu;
|
||||||
|
// same, but just GPU jobs.
|
||||||
|
int max_jobs_on_host;
|
||||||
|
int max_jobs_on_host_cpu;
|
||||||
|
int max_jobs_on_host_gpu;
|
||||||
|
void update_for_result(double seconds_filled);
|
||||||
|
void add_no_work_message(const char*);
|
||||||
|
void get_job_limits();
|
||||||
|
|
||||||
|
~WORK_REQ() {
|
||||||
|
for (unsigned int i=0; i<all_best_app_versions.size(); i++) {
|
||||||
|
delete all_best_app_versions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: if any field requires initialization,
|
// NOTE: if any field requires initialization,
|
||||||
// you must do it in the constructor. Nothing is zeroed by default.
|
// you must do it in the constructor. Nothing is zeroed by default.
|
||||||
//
|
//
|
||||||
|
|
|
@ -405,6 +405,7 @@ BEST_APP_VERSION* get_app_version(
|
||||||
bavp->trusted = app_version_is_trusted(gavid);
|
bavp->trusted = app_version_is_trusted(gavid);
|
||||||
}
|
}
|
||||||
g_wreq->best_app_versions.push_back(bavp);
|
g_wreq->best_app_versions.push_back(bavp);
|
||||||
|
g_wreq->all_best_app_versions.push_back(bavp);
|
||||||
if (!bavp->present) return NULL;
|
if (!bavp->present) return NULL;
|
||||||
return bavp;
|
return bavp;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue