diff --git a/checkin_notes b/checkin_notes index 7b60fa6471..d4c700484b 100755 --- a/checkin_notes +++ b/checkin_notes @@ -17743,3 +17743,14 @@ Rom 24 Sept 2004 client_state.C clientgui/ + +David 24 Sept 2004 + - support for 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 diff --git a/client/client_state.C b/client/client_state.C index 063bee1593..bd3fc613f9 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -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 diff --git a/client/client_state.h b/client/client_state.h index 638647c94f..ce03d9376f 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -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: diff --git a/client/client_types.C b/client/client_types.C index 9da808f389..9ad6f7bd83 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -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, "")) return 0; @@ -356,6 +358,7 @@ int PROJECT::parse_state(MIOFILE& in) { else if (match_tag(buf, "")) master_url_fetch_pending = true; else if (match_tag(buf, "")) sched_rpc_pending = true; else if (match_tag(buf, "")) send_file_list = true; + else if (match_tag(buf, "")) non_cpu_intensive = true; #if 0 else if (match_tag(buf, "")) deletion_policy_priority = true; else if (match_tag(buf, "")) deletion_policy_expire = true; @@ -407,7 +410,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) { " %d\n" " %f\n" " %f\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?" \n":"", sched_rpc_pending?" \n":"", - send_file_list?" \n":"" + send_file_list?" \n":"", + 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; diff --git a/client/cs_apps.C b/client/cs_apps.C index a243e7b7bc..b31ed84462 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -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; inext_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; inext_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; inon_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; inon_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; ialready_selected = false; } + expected_pay_off = cpu_sched_work_done_this_period / ncpus; for (j=0; jnon_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;