*** empty log message ***

svn path=/trunk/boinc/; revision=4242
This commit is contained in:
David Anderson 2004-09-24 23:22:05 +00:00
parent 11b50acd8a
commit e0e9a59202
5 changed files with 61 additions and 28 deletions

View File

@ -17743,3 +17743,14 @@ Rom 24 Sept 2004
client_state.C
clientgui/
<Numerous Files>
David 24 Sept 2004
- support for <non_cpu_intensive/> projects.
The flag is parsed from scheduler and stored in state file
Non-CPU-intensive projects are treated specially
by the CPU scheduler: their results are always scheduled.
client/
client_state.C,h
client_types.C
cs_apps.C

View File

@ -107,7 +107,7 @@ CLIENT_STATE::CLIENT_STATE() {
executing_as_windows_service = false;
cpu_sched_last_time = 0;
cpu_sched_work_done_this_period = 0;
must_schedule_cpus = false;
must_schedule_cpus = true;
}
#if 0

View File

@ -209,6 +209,7 @@ private:
bool schedule_cpus();
bool handle_finished_apps();
void handle_file_xfer_apps();
int schedule_result(RESULT*);
// --------------- cs_benchmark.C:
public:

View File

@ -86,6 +86,7 @@ void PROJECT::init() {
next_runnable_result = NULL;
work_request = 0;
send_file_list = false;
non_cpu_intensive = false;
#if 0
deletion_policy_priority = false;
deletion_policy_expire = false;
@ -314,6 +315,7 @@ int PROJECT::parse_state(MIOFILE& in) {
master_url_fetch_pending = false;
sched_rpc_pending = false;
send_file_list = false;
non_cpu_intensive = false;
scheduler_urls.clear();
while (in.fgets(buf, 256)) {
if (match_tag(buf, "</project>")) return 0;
@ -356,6 +358,7 @@ int PROJECT::parse_state(MIOFILE& in) {
else if (match_tag(buf, "<master_url_fetch_pending/>")) master_url_fetch_pending = true;
else if (match_tag(buf, "<sched_rpc_pending/>")) sched_rpc_pending = true;
else if (match_tag(buf, "<send_file_list/>")) send_file_list = true;
else if (match_tag(buf, "<non_cpu_intensive/>")) non_cpu_intensive = true;
#if 0
else if (match_tag(buf, "<deletion_policy_priority/>")) deletion_policy_priority = true;
else if (match_tag(buf, "<deletion_policy_expire/>")) deletion_policy_expire = true;
@ -407,7 +410,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) {
" <min_rpc_time>%d</min_rpc_time>\n"
" <debt>%f</debt>\n"
" <resource_share>%f</resource_share>\n"
"%s%s%s",
"%s%s%s%s",
master_url,
project_name,
#if 0
@ -435,7 +438,8 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) {
resource_share,
master_url_fetch_pending?" <master_url_fetch_pending/>\n":"",
sched_rpc_pending?" <sched_rpc_pending/>\n":"",
send_file_list?" <send_file_list/>\n":""
send_file_list?" <send_file_list/>\n":"",
non_cpu_intensive?" <non_cpu_intensive/>\n":""
);
#if 0
out.printf(
@ -494,6 +498,7 @@ void PROJECT::copy_state_fields(PROJECT& p) {
safe_strcpy(code_sign_key, p.code_sign_key);
debt = p.debt;
send_file_list = p.send_file_list;
non_cpu_intensive = p.non_cpu_intensive;
#if 0
deletion_policy_priority = p.deletion_policy_priority;
deletion_policy_expire = p.deletion_policy_expire;

View File

@ -277,45 +277,54 @@ void CLIENT_STATE::assign_results_to_projects() {
}
}
// if there's not an active task for the result, make one
//
int CLIENT_STATE::schedule_result(RESULT* rp) {
ACTIVE_TASK *atp = lookup_active_task_by_result(rp);
if (!atp) {
atp = new ACTIVE_TASK;
atp->init(rp);
atp->slot = active_tasks.get_free_slot();
get_slot_dir(atp->slot, atp->slot_dir);
active_tasks.active_tasks.push_back(atp);
}
atp->next_scheduler_state = CPU_SCHED_SCHEDULED;
return 0;
}
// Schedule an active task for the project with the largest anticipated debt
// among those that have a runnable result.
// Return true iff a task was scheduled.
//
bool CLIENT_STATE::schedule_largest_debt_project(double expected_pay_off) {
PROJECT *best_project = NULL;
double best_debt = 0.; // initial value doesn't matter
double best_debt = 0;
bool first = true;
unsigned int i;
for (i=0; i<projects.size(); i++) {
if (!projects[i]->next_runnable_result) continue;
PROJECT* p = projects[i];
if (!p->next_runnable_result) continue;
if (p->non_cpu_intensive) continue;
if (!input_files_available(projects[i]->next_runnable_result)) {
report_result_error(
*(projects[i]->next_runnable_result), ERR_FILE_MISSING,
*(p->next_runnable_result), ERR_FILE_MISSING,
"One or more missing files"
);
projects[i]->next_runnable_result = NULL;
p->next_runnable_result = NULL;
continue;
}
if (first || projects[i]->anticipated_debt > best_debt) {
if (first || p->anticipated_debt > best_debt) {
first = false;
best_project = projects[i];
best_debt = best_project->anticipated_debt;
best_project = p;
best_debt = p->anticipated_debt;
}
}
if (!best_project) return false;
ACTIVE_TASK *atp = lookup_active_task_by_result(best_project->next_runnable_result);
if (!atp) {
atp = new ACTIVE_TASK;
atp->init(best_project->next_runnable_result);
atp->slot = active_tasks.get_free_slot();
get_slot_dir(atp->slot, atp->slot_dir);
active_tasks.active_tasks.push_back(atp);
}
schedule_result(best_project->next_runnable_result);
best_project->anticipated_debt -= expected_pay_off;
best_project->next_runnable_result = false;
atp->next_scheduler_state = CPU_SCHED_SCHEDULED;
best_project->next_runnable_result = 0;
return true;
}
@ -391,7 +400,9 @@ bool CLIENT_STATE::schedule_cpus() {
assign_results_to_projects(); // see which projects have work
total_resource_share = 0;
for (i=0; i<projects.size(); i++) {
if (projects[i]->next_runnable_result) {
p = projects[i];
if (p->non_cpu_intensive) continue;
if (p->next_runnable_result) {
total_resource_share += projects[i]->resource_share;
}
}
@ -403,6 +414,7 @@ bool CLIENT_STATE::schedule_cpus() {
first = true;
for (i=0; i<projects.size(); i++) {
p = projects[i];
if (p->non_cpu_intensive) continue;
if (!p->next_runnable_result) {
p->debt = 0;
p->anticipated_debt = 0;
@ -417,13 +429,6 @@ bool CLIENT_STATE::schedule_cpus() {
} else if (p->debt < min_debt) {
min_debt = p->debt;
}
#if 0
if (p->debt < -max_debt) {
p->debt = -max_debt;
} else if (p->debt > max_debt) {
p->debt = max_debt;
}
#endif
}
scope_messages.printf(
"CLIENT_STATE::schedule_cpus(): overall project debt; project '%s', debt '%f'\n",
@ -435,6 +440,7 @@ bool CLIENT_STATE::schedule_cpus() {
//
for (i=0; i<projects.size(); i++) {
p = projects[i];
if (p->non_cpu_intensive) continue;
if (p->next_runnable_result) {
p->debt -= min_debt;
p->anticipated_debt = p->debt;
@ -448,12 +454,22 @@ bool CLIENT_STATE::schedule_cpus() {
for (i=0; i<results.size(); i++) {
results[i]->already_selected = false;
}
expected_pay_off = cpu_sched_work_done_this_period / ncpus;
for (j=0; j<ncpus; j++) {
assign_results_to_projects();
if (!schedule_largest_debt_project(expected_pay_off)) break;
}
// schedule non CPU intensive tasks
//
for (i=0; i<projects.size(); i++) {
p = projects[i];
if (p->non_cpu_intensive && p->next_runnable_result) {
schedule_result(p->next_runnable_result);
}
}
// preempt, start, and resume tasks
//
vm_limit = global_prefs.vm_max_used_pct / 100.0 * host_info.m_swap;