diff --git a/checkin_notes b/checkin_notes index 5fdbcca548..90ec564668 100755 --- a/checkin_notes +++ b/checkin_notes @@ -4883,3 +4883,25 @@ David 21 May 2006 html/inc/ prefs.inc stats_sites.inc + +David 21 May 2006 + - core client: implement "CPU usage limit" preference + - core client: print CPU scheduling messages only if + "tasks" log flag is set + - core client: mechanisms for suspending activities + (idle, time-of-day, explicit control) + affect only CPU, not network usage + - Manager: fix garbled message about needing network connection + + client/ + app_control.C + app_start.C + client_state.C,h + cs_apps.C + cs_prefs.C + log_flags.C + main.C + clientgui/ + BOINCDialupManager.cpp + lib/ + prefs.C,h diff --git a/client/app_control.C b/client/app_control.C index f8ee2d5c37..d31fe28da4 100644 --- a/client/app_control.C +++ b/client/app_control.C @@ -59,6 +59,7 @@ using std::vector; #include "client_msgs.h" #include "client_state.h" #include "file_names.h" +#include "log_flags.h" #include "app.h" @@ -153,10 +154,12 @@ int ACTIVE_TASK::preempt(bool quit_task) { scheduler_state = CPU_SCHED_PREEMPTED; - msg_printf(result->project, MSG_INFO, - "Pausing task %s (%s)", - result->name, (quit_task ? "removed from memory" : "left in memory") - ); + if (log_flags.task) { + msg_printf(result->project, MSG_INFO, + "Pausing task %s (%s)", + result->name, (quit_task ? "removed from memory" : "left in memory") + ); + } return 0; } diff --git a/client/app_start.C b/client/app_start.C index f355edb6fc..faeb1c048a 100644 --- a/client/app_start.C +++ b/client/app_start.C @@ -61,6 +61,7 @@ using std::vector; #include "client_msgs.h" #include "client_state.h" #include "file_names.h" +#include "log_flags.h" #include "app.h" @@ -611,13 +612,15 @@ int ACTIVE_TASK::resume_or_start() { ); return 0; } - msg_printf(result->project, MSG_INFO, - "%s task %s using %s version %d", - str, - result->name, - app_version->app->name, - app_version->version_num - ); + if (log_flags.task) { + msg_printf(result->project, MSG_INFO, + "%s task %s using %s version %d", + str, + result->name, + app_version->app->name, + app_version->version_num + ); + } return 0; } diff --git a/client/client_state.C b/client/client_state.C index bd07f58701..051d289abc 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -414,6 +414,7 @@ void CLIENT_STATE::do_io_or_sleep(double x) { // bool CLIENT_STATE::poll_slow_events() { int actions = 0, suspend_reason, network_suspend_reason, retval; + static int last_suspend_reason=0; SCOPE_MSG_LOG scope_messages(log_messages, CLIENT_MSG_LOG::DEBUG_POLL); static bool tasks_restarted = false; @@ -449,9 +450,10 @@ bool CLIENT_STATE::poll_slow_events() { if (!tasks_suspended) { suspend_tasks(suspend_reason); } + last_suspend_reason = suspend_reason; } else { if (tasks_suspended) { - resume_tasks(); + resume_tasks(last_suspend_reason); } } } @@ -470,24 +472,24 @@ bool CLIENT_STATE::poll_slow_events() { } check_suspend_network(network_suspend_reason); - suspend_reason |= network_suspend_reason; // if we've had a GUI RPC in last few minutes, relax the normal rules // if (gui_rpcs.got_recent_rpc(300)) { - suspend_reason &= !SUSPEND_REASON_USER_ACTIVE; - suspend_reason &= !SUSPEND_REASON_BATTERIES; + network_suspend_reason &= !SUSPEND_REASON_USER_ACTIVE; + network_suspend_reason &= !SUSPEND_REASON_BATTERIES; } - if (suspend_reason) { + if (network_suspend_reason) { if (!network_suspended) { - suspend_network(suspend_reason); + suspend_network(network_suspend_reason); + network_suspended = true; } } else { if (network_suspended) { resume_network(); + network_suspended = false; } } - network_suspended = (suspend_reason != 0); scope_messages.printf("CLIENT_STATE::poll_slow_events(): Begin poll:\n"); ++scope_messages; diff --git a/client/client_state.h b/client/client_state.h index 6087b92f1e..23613ec367 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -69,7 +69,8 @@ enum SUSPEND_REASON { SUSPEND_REASON_USER_REQ = 4, SUSPEND_REASON_TIME_OF_DAY = 8, SUSPEND_REASON_BENCHMARKS = 16, - SUSPEND_REASON_DISK_SIZE = 32 + SUSPEND_REASON_DISK_SIZE = 32, + SUSPEND_REASON_CPU_USAGE_LIMIT = 64, }; // CLIENT_STATE encapsulates the global variables of the core client. @@ -354,7 +355,7 @@ public: int allowed_disk_usage(double&); int allowed_project_disk_usage(double&); int suspend_tasks(int reason); - int resume_tasks(); + int resume_tasks(int reason=0); int suspend_network(int reason); int resume_network(); private: @@ -474,4 +475,5 @@ extern double calculate_exponential_backoff( int n, double MIN, double MAX ); +#define POLL_INTERVAL 1.0 #endif diff --git a/client/cs_apps.C b/client/cs_apps.C index ab8d9f4b6a..c62fa00d5c 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -352,7 +352,9 @@ void CLIENT_STATE::handle_file_xfer_apps() { void CLIENT_STATE::request_schedule_cpus(const char* where) { must_schedule_cpus = true; - msg_printf(0, MSG_INFO, "Rescheduling CPU: %s", where); + if (log_flags.task) { + msg_printf(0, MSG_INFO, "Rescheduling CPU: %s", where); + } } const char *BOINC_RCSID_7bf63ad771 = "$Id$"; diff --git a/client/cs_prefs.C b/client/cs_prefs.C index d8f60cadca..07e5a76d30 100644 --- a/client/cs_prefs.C +++ b/client/cs_prefs.C @@ -144,32 +144,52 @@ void CLIENT_STATE::check_suspend_activities(int& reason) { // Don't work while we're running CPU benchmarks // if (are_cpu_benchmarks_running()) { - reason |= SUSPEND_REASON_BENCHMARKS; - } - - if (user_run_request == USER_RUN_REQUEST_ALWAYS) return; - - if (user_run_request == USER_RUN_REQUEST_NEVER) { - reason |= SUSPEND_REASON_USER_REQ; + reason = SUSPEND_REASON_BENCHMARKS; return; } - if (!global_prefs.run_on_batteries - && host_info.host_is_running_on_batteries() - ) { - reason |= SUSPEND_REASON_BATTERIES; + switch(user_run_request) { + case USER_RUN_REQUEST_ALWAYS: break; + case USER_RUN_REQUEST_NEVER: + reason = SUSPEND_REASON_USER_REQ; + return; + default: + if (!global_prefs.run_on_batteries + && host_info.host_is_running_on_batteries() + ) { + reason = SUSPEND_REASON_BATTERIES; + return; + } + + if (!global_prefs.run_if_user_active + && !host_info.users_idle( + check_all_logins, global_prefs.idle_time_to_run + ) + ) { + reason = SUSPEND_REASON_USER_ACTIVE; + return; + } + + if (!now_between_two_hours(global_prefs.start_hour, global_prefs.end_hour)) { + reason = SUSPEND_REASON_TIME_OF_DAY; + return; + } } - if (!global_prefs.run_if_user_active - && !host_info.users_idle( - check_all_logins, global_prefs.idle_time_to_run - ) - ) { - reason |= SUSPEND_REASON_USER_ACTIVE; - } - - if (!now_between_two_hours(global_prefs.start_hour, global_prefs.end_hour)) { - reason |= SUSPEND_REASON_TIME_OF_DAY; + if (global_prefs.cpu_usage_limit != 100) { + static double last_time=0, debt=0; + if (last_time) { + double diff = now - last_time; + if (diff >= POLL_INTERVAL/2. && diff < POLL_INTERVAL*10.) { + debt += diff*global_prefs.cpu_usage_limit/100; + if (debt < 0) { + reason = SUSPEND_REASON_CPU_USAGE_LIMIT; + } else { + debt -= diff; + } + } + } + last_time = now; } } @@ -197,17 +217,26 @@ static string reason_string(int reason) { } int CLIENT_STATE::suspend_tasks(int reason) { - string s_reason; - s_reason = "Suspending computation" + reason_string(reason); - msg_printf(NULL, MSG_INFO, const_cast(s_reason.c_str())); - active_tasks.suspend_all(global_prefs.leave_apps_in_memory); + if (reason == SUSPEND_REASON_CPU_USAGE_LIMIT) { + active_tasks.suspend_all(true); + } else { + string s_reason; + s_reason = "Suspending computation" + reason_string(reason); + msg_printf(NULL, MSG_INFO, s_reason.c_str()); + active_tasks.suspend_all(global_prefs.leave_apps_in_memory); + } return 0; } -int CLIENT_STATE::resume_tasks() { - msg_printf(NULL, MSG_INFO, "Resuming computation"); - active_tasks.unsuspend_all(); - gstate.request_schedule_cpus("Resuming computation"); +int CLIENT_STATE::resume_tasks(int reason) { + if (reason == SUSPEND_REASON_CPU_USAGE_LIMIT) { + active_tasks.unsuspend_all(); + gstate.request_schedule_cpus("usage limit"); + } else { + msg_printf(NULL, MSG_INFO, "Resuming computation"); + active_tasks.unsuspend_all(); + gstate.request_schedule_cpus("Resuming computation"); + } return 0; } @@ -229,7 +258,7 @@ void CLIENT_STATE::check_suspend_network(int& reason) { int CLIENT_STATE::suspend_network(int reason) { string s_reason; s_reason = "Suspending network activity" + reason_string(reason); - msg_printf(NULL, MSG_INFO, const_cast(s_reason.c_str())); + msg_printf(NULL, MSG_INFO, s_reason.c_str()); pers_file_xfers->suspend(); return 0; } diff --git a/client/log_flags.C b/client/log_flags.C index 793b5493e8..4aae667fa0 100644 --- a/client/log_flags.C +++ b/client/log_flags.C @@ -44,7 +44,7 @@ LOG_FLAGS::LOG_FLAGS() { // informational output is on by default // - task = true; + task = false; file_xfer = true; sched_ops = true; diff --git a/client/main.C b/client/main.C index 71d517c74e..7785e4f5d9 100644 --- a/client/main.C +++ b/client/main.C @@ -537,7 +537,7 @@ int boinc_main_loop() { while (1) { if (!gstate.poll_slow_events()) { - gstate.do_io_or_sleep(1.0); + gstate.do_io_or_sleep(POLL_INTERVAL); } fflush(stdout); diff --git a/clientgui/BOINCDialupManager.cpp b/clientgui/BOINCDialupManager.cpp index 0fc5174897..0fe0b4595a 100644 --- a/clientgui/BOINCDialupManager.cpp +++ b/clientgui/BOINCDialupManager.cpp @@ -296,8 +296,7 @@ int CBOINCDialUpManager::NotifyUserNeedConnection() { // 2st %s is the application name // i.e. 'BOINC Manager', 'GridRepublic Manager' strDialogMessage.Printf( - _("%s needs a connection to the Internet to perform some maintenance, open the %s to connect" - "up and perform the needed work."), + _("%s needs to connect to the Internet. Please click to open %s."), wxGetApp().GetBrand()->GetProjectName().c_str(), wxGetApp().GetBrand()->GetApplicationName().c_str() ); diff --git a/lib/prefs.C b/lib/prefs.C index 114d301179..67533918bf 100644 --- a/lib/prefs.C +++ b/lib/prefs.C @@ -65,6 +65,7 @@ void GLOBAL_PREFS::defaults() { //max_memory_mbytes = 128; proc_priority = 1; cpu_affinity = -1; + cpu_usage_limit = 1; // don't initialize source_project, source_scheduler here // since they are outside of elements @@ -209,6 +210,8 @@ int GLOBAL_PREFS::parse_override( #endif } else if (parse_int(buf, "", cpu_affinity)) { continue; + } else if (parse_double(buf, "", cpu_usage_limit)) { + continue; } } return 0; diff --git a/lib/prefs.h b/lib/prefs.h index 6344f343d0..4208200b17 100644 --- a/lib/prefs.h +++ b/lib/prefs.h @@ -61,6 +61,7 @@ struct GLOBAL_PREFS { //int max_memory_mbytes; int proc_priority; int cpu_affinity; + double cpu_usage_limit; char source_project[256]; char source_scheduler[256];