CPU usage limit

svn path=/trunk/boinc/; revision=10168
This commit is contained in:
David Anderson 2006-05-21 22:03:36 +00:00
parent 7c6619c122
commit 6c29f101bf
12 changed files with 121 additions and 55 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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$";

View File

@ -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<char*>(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<char*>(s_reason.c_str()));
msg_printf(NULL, MSG_INFO, s_reason.c_str());
pers_file_xfers->suspend();
return 0;
}

View File

@ -44,7 +44,7 @@ LOG_FLAGS::LOG_FLAGS() {
// informational output is on by default
//
task = true;
task = false;
file_xfer = true;
sched_ops = true;

View File

@ -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);

View File

@ -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()
);

View File

@ -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 <venue> elements
@ -209,6 +210,8 @@ int GLOBAL_PREFS::parse_override(
#endif
} else if (parse_int(buf, "<cpu_affinity>", cpu_affinity)) {
continue;
} else if (parse_double(buf, "<cpu_usage_limit>", cpu_usage_limit)) {
continue;
}
}
return 0;

View File

@ -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];