diff --git a/checkin_notes b/checkin_notes
index 7da3674e98..3ce4de52db 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -27123,3 +27123,15 @@ Rom 12 April 2005
BOINCTaskCtrl.cpp
lib/
gui_rpc_client.C
+
+David 13 April 2005
+ client/
+ app_control.C
+ client_state.C,h
+ client_types.C,h
+ cs_apps.C
+ cs_scheduler.C
+ scheduler_op.C,h
+ lib/
+ boinc_win.h
+ prefs.C,h
diff --git a/client/app_control.C b/client/app_control.C
index 9a2ea5c99c..9cc514432f 100644
--- a/client/app_control.C
+++ b/client/app_control.C
@@ -673,6 +673,7 @@ int ACTIVE_TASK_SET::abort_project(PROJECT* project) {
task_iter++;
}
}
+ project->long_term_debt = 0;
return 0;
}
diff --git a/client/client_state.C b/client/client_state.C
index 12a8e6bb6b..4c5720477b 100644
Binary files a/client/client_state.C and b/client/client_state.C differ
diff --git a/client/client_state.h b/client/client_state.h
index dea5c67a80..2953409e4e 100644
--- a/client/client_state.h
+++ b/client/client_state.h
@@ -147,6 +147,8 @@ private:
//
double cpu_sched_last_time;
double cpu_sched_work_done_this_period;
+ bool work_fetch_no_new_work;
+ bool cpu_crunch_nearest_first;
// --------------- client_state.C:
public:
@@ -219,6 +221,7 @@ private:
int app_finished(ACTIVE_TASK&);
void assign_results_to_projects();
bool schedule_largest_debt_project(double expected_pay_off);
+ bool schedule_nearest_deadline_project(double expected_pay_off);
bool start_apps();
bool schedule_cpus(double);
bool handle_finished_apps(double);
@@ -282,6 +285,9 @@ private:
bool scheduler_rpc_poll(double);
double ettprc(PROJECT*, int);
double avg_proc_rate(PROJECT*);
+ bool should_get_work();
+ bool no_work_for_a_cpu();
+ void set_cpu_scheduler_modes();
// --------------- cs_statefile.C:
public:
diff --git a/client/client_types.C b/client/client_types.C
index 6adaf425c0..739af87fd8 100644
--- a/client/client_types.C
+++ b/client/client_types.C
@@ -86,6 +86,7 @@ void PROJECT::init() {
anonymous_platform = false;
non_cpu_intensive = false;
debt = 0;
+ long_term_debt = 0;
send_file_list = false;
suspended_via_gui = false;
dont_request_more_work = false;
@@ -176,6 +177,7 @@ int PROJECT::parse_state(MIOFILE& in) {
else if (match_tag(buf, "")) deletion_policy_expire = true;
#endif
else if (parse_double(buf, "", debt)) continue;
+ else if (parse_double(buf, "", long_term_debt)) continue;
else if (parse_double(buf, "", x)) continue; // not authoritative
else scope_messages.printf("PROJECT::parse_state(): unrecognized: %s\n", buf);
}
@@ -221,6 +223,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) {
" %d\n"
" %f\n"
" %f\n"
+ " %f\n"
" %f\n"
"%s%s%s%s%s%s",
master_url,
@@ -247,6 +250,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) {
master_fetch_failures,
min_rpc_time,
debt,
+ long_term_debt,
resource_share,
master_url_fetch_pending?" \n":"",
sched_rpc_pending?" \n":"",
@@ -314,6 +318,7 @@ void PROJECT::copy_state_fields(PROJECT& p) {
sched_rpc_pending = p.sched_rpc_pending;
safe_strcpy(code_sign_key, p.code_sign_key);
debt = p.debt;
+ long_term_debt = p.long_term_debt;
send_file_list = p.send_file_list;
non_cpu_intensive = p.non_cpu_intensive;
suspended_via_gui = p.suspended_via_gui;
@@ -657,7 +662,7 @@ int FILE_INFO::write_gui(MIOFILE& out) {
" %f\n"
" %f\n"
" %d\n",
- project->master_url,
+ project->master_url,
project->project_name,
name,
nbytes,
diff --git a/client/client_types.h b/client/client_types.h
index 356660ff00..3d762fe42d 100644
--- a/client/client_types.h
+++ b/client/client_types.h
@@ -232,6 +232,7 @@ public:
struct RESULT *next_runnable_result; // the next result to run for this project
// the following used by work-fetch algorithm
+ double long_term_debt; // how much CPU time we owe this project in the long term (secs)
double work_request;
// the unit is "normalized CPU seconds",
// i.e. the work should take 1 CPU on this host
diff --git a/client/cs_apps.C b/client/cs_apps.C
index 6082812d09..a3fb5c5fce 100644
--- a/client/cs_apps.C
+++ b/client/cs_apps.C
@@ -347,6 +347,36 @@ bool CLIENT_STATE::schedule_largest_debt_project(double expected_pay_off) {
best_project->next_runnable_result = 0;
return true;
}
+// The CPU scheduler is in panic mode.
+// Schedule the active task with the earliest deadline
+// Return true iff a task was scheduled.
+//
+bool CLIENT_STATE::schedule_nearest_deadline_project(double expected_pay_off) {
+ PROJECT *best_project = NULL;
+ RESULT *best_result = NULL;
+ double earliest_deadline;
+ bool first = true;
+ unsigned int i;
+
+ for (i=0; i < results.size(); ++i) {
+ RESULT *r = results[i];
+ if (RESULT_FILES_DOWNLOADED != r->state) continue;
+ if (r->project->non_cpu_intensive) continue;
+ if (r->already_selected) continue;
+ if (first || r->report_deadline < earliest_deadline) {
+ first = false;
+ best_project = r->project;
+ best_result = r;
+ earliest_deadline = r->report_deadline;
+ }
+ }
+ if (!best_result) return false;
+
+ schedule_result(best_result);
+ best_project->anticipated_debt -= expected_pay_off;
+ best_project->next_runnable_result = 0;
+ return true;
+}
// Schedule active tasks to be run and preempted.
//
@@ -399,6 +429,8 @@ bool CLIENT_STATE::schedule_cpus(double now) {
results[i]->already_selected = false;
}
+ set_cpu_scheduler_modes();
+
// do work accounting for active tasks
//
for (i=0; inon_cpu_intensive) continue;
+ count_cpu_intensive++;
+ double debt_inc =
+ (p->resource_share/local_total_resource_share)
+ * cpu_sched_work_done_this_period
+ - p->work_done_this_period;
+ p->long_term_debt += debt_inc;
+ total_long_term_debt += p->long_term_debt;
if (!p->next_runnable_result) {
p->debt = 0;
p->anticipated_debt = 0;
- } else {
- p->debt +=
- (p->resource_share/local_total_resource_share)
- * cpu_sched_work_done_this_period
- - p->work_done_this_period;
+ } else {
+ p->debt += debt_inc;
if (first) {
first = false;
min_debt = p->debt;
@@ -452,6 +490,8 @@ bool CLIENT_STATE::schedule_cpus(double now) {
);
}
+ double avg_long_term_debt = total_long_term_debt / count_cpu_intensive;
+
// Normalize debts to zero
//
for (i=0; idebt);
p->next_runnable_result = NULL;
}
+ p->long_term_debt -= avg_long_term_debt;
}
// schedule tasks for projects in order of decreasing anticipated debt
@@ -477,7 +518,11 @@ bool CLIENT_STATE::schedule_cpus(double now) {
expected_pay_off = cpu_sched_work_done_this_period / ncpus;
for (j=0; j
#include
#include
+#include