2008-08-06 18:36:30 +00:00
|
|
|
// This file is part of BOINC.
|
2005-01-20 23:22:22 +00:00
|
|
|
// http://boinc.berkeley.edu
|
2008-08-06 18:36:30 +00:00
|
|
|
// Copyright (C) 2008 University of California
|
2003-10-18 19:35:58 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
2005-01-20 23:22:22 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
2005-01-20 23:22:22 +00:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
2003-10-18 19:35:58 +00:00
|
|
|
|
2004-01-30 22:19:19 +00:00
|
|
|
// Logic related to general (also known as global) preferences:
|
|
|
|
// when to compute, how much disk to use, etc.
|
|
|
|
//
|
|
|
|
|
2004-03-05 04:37:53 +00:00
|
|
|
#ifdef _WIN32
|
2004-06-16 23:16:08 +00:00
|
|
|
#include "boinc_win.h"
|
2004-03-05 04:37:53 +00:00
|
|
|
#endif
|
|
|
|
|
2004-06-10 00:12:29 +00:00
|
|
|
#ifndef _WIN32
|
2005-11-21 18:34:44 +00:00
|
|
|
#include "config.h"
|
2004-06-10 00:12:29 +00:00
|
|
|
#if HAVE_SYS_STAT_H
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
#if HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2007-02-21 16:26:51 +00:00
|
|
|
#include "str_util.h"
|
2009-06-16 20:54:44 +00:00
|
|
|
#include "str_replace.h"
|
2007-06-22 20:17:08 +00:00
|
|
|
#include "util.h"
|
2003-10-18 19:35:58 +00:00
|
|
|
#include "filesys.h"
|
2004-10-01 18:48:34 +00:00
|
|
|
#include "parse.h"
|
2003-10-18 19:35:58 +00:00
|
|
|
#include "file_names.h"
|
2003-10-19 19:03:49 +00:00
|
|
|
#include "cpu_benchmark.h"
|
2004-04-08 08:15:23 +00:00
|
|
|
#include "client_msgs.h"
|
2003-10-18 19:35:58 +00:00
|
|
|
#include "client_state.h"
|
|
|
|
|
2004-06-30 18:17:21 +00:00
|
|
|
using std::min;
|
|
|
|
using std::string;
|
|
|
|
|
2005-10-03 18:05:58 +00:00
|
|
|
#define MAX_PROJ_PREFS_LEN 65536
|
|
|
|
// max length of project-specific prefs
|
|
|
|
|
2003-10-18 19:35:58 +00:00
|
|
|
// Return the maximum allowed disk usage as determined by user preferences.
|
|
|
|
// There are three different settings in the prefs;
|
|
|
|
// return the least of the three.
|
|
|
|
//
|
2008-11-02 20:09:59 +00:00
|
|
|
double CLIENT_STATE::allowed_disk_usage(double boinc_total) {
|
|
|
|
double limit_pct, limit_min_free, limit_abs;
|
2003-10-18 19:35:58 +00:00
|
|
|
|
2008-11-02 20:09:59 +00:00
|
|
|
limit_pct = host_info.d_total*global_prefs.disk_max_used_pct/100.0;
|
|
|
|
limit_min_free = boinc_total + host_info.d_free - global_prefs.disk_min_free_gb*GIGA;
|
|
|
|
limit_abs = global_prefs.disk_max_used_gb*(GIGA);
|
2003-10-18 19:35:58 +00:00
|
|
|
|
2008-11-02 20:09:59 +00:00
|
|
|
double size = min(min(limit_abs, limit_pct), limit_min_free);
|
2004-08-12 10:13:01 +00:00
|
|
|
if (size < 0) size = 0;
|
2007-03-27 18:36:22 +00:00
|
|
|
return size;
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CLIENT_STATE::project_disk_usage(PROJECT* p, double& size) {
|
2004-07-21 21:30:25 +00:00
|
|
|
char buf[256];
|
|
|
|
unsigned int i;
|
|
|
|
double s;
|
2003-10-18 19:35:58 +00:00
|
|
|
|
2007-03-13 19:33:27 +00:00
|
|
|
get_project_dir(p, buf, sizeof(buf));
|
2004-07-21 21:30:25 +00:00
|
|
|
dir_size(buf, size);
|
2003-11-04 22:22:06 +00:00
|
|
|
|
2004-07-21 21:30:25 +00:00
|
|
|
for (i=0; i<active_tasks.active_tasks.size(); i++) {
|
|
|
|
ACTIVE_TASK* atp = active_tasks.active_tasks[i];
|
|
|
|
if (atp->wup->project != p) continue;
|
2007-03-13 19:33:27 +00:00
|
|
|
get_slot_dir(atp->slot, buf, sizeof(buf));
|
2004-07-21 21:30:25 +00:00
|
|
|
dir_size(buf, s);
|
|
|
|
size += s;
|
|
|
|
}
|
2003-10-18 19:35:58 +00:00
|
|
|
|
2004-07-21 21:30:25 +00:00
|
|
|
return 0;
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
|
|
|
|
2003-11-04 22:22:06 +00:00
|
|
|
int CLIENT_STATE::total_disk_usage(double& size) {
|
2003-10-18 19:35:58 +00:00
|
|
|
return dir_size(".", size);
|
|
|
|
}
|
|
|
|
|
2007-12-27 21:40:20 +00:00
|
|
|
// See if we should suspend processing
|
2003-10-18 19:35:58 +00:00
|
|
|
//
|
2007-07-19 23:22:19 +00:00
|
|
|
int CLIENT_STATE::check_suspend_processing() {
|
2004-03-21 00:10:15 +00:00
|
|
|
if (are_cpu_benchmarks_running()) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_BENCHMARKS;
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
|
|
|
|
2007-12-27 21:40:20 +00:00
|
|
|
if (config.start_delay && now < client_start_time + config.start_delay) {
|
|
|
|
return SUSPEND_REASON_INITIAL_DELAY;
|
|
|
|
}
|
|
|
|
|
2009-12-10 23:26:35 +00:00
|
|
|
switch (run_mode.get_current()) {
|
2006-09-01 21:06:30 +00:00
|
|
|
case RUN_MODE_ALWAYS: break;
|
|
|
|
case RUN_MODE_NEVER:
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_USER_REQ;
|
2006-05-21 22:03:36 +00:00
|
|
|
default:
|
2009-09-26 20:23:39 +00:00
|
|
|
// "run according to prefs" checks:
|
|
|
|
//
|
2006-05-21 22:03:36 +00:00
|
|
|
if (!global_prefs.run_on_batteries
|
|
|
|
&& host_info.host_is_running_on_batteries()
|
|
|
|
) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_BATTERIES;
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
2006-09-05 19:00:59 +00:00
|
|
|
if (!global_prefs.run_if_user_active && user_active) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_USER_ACTIVE;
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
2007-08-25 09:53:33 +00:00
|
|
|
if (global_prefs.cpu_times.suspended()) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_TIME_OF_DAY;
|
|
|
|
}
|
2009-09-26 20:23:39 +00:00
|
|
|
if (global_prefs.suspend_if_no_recent_input) {
|
|
|
|
bool idle = host_info.users_idle(
|
|
|
|
check_all_logins, global_prefs.suspend_if_no_recent_input
|
|
|
|
);
|
|
|
|
if (idle) {
|
|
|
|
return SUSPEND_REASON_NO_RECENT_INPUT;
|
|
|
|
}
|
|
|
|
}
|
2009-11-13 17:49:18 +00:00
|
|
|
if (exclusive_app_running) {
|
2009-09-26 20:23:39 +00:00
|
|
|
return SUSPEND_REASON_EXCLUSIVE_APP_RUNNING;
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
2010-02-18 23:53:14 +00:00
|
|
|
if (global_prefs.suspend_cpu_usage && non_boinc_cpu_usage*100 > global_prefs.suspend_cpu_usage) {
|
2010-01-19 00:03:38 +00:00
|
|
|
return SUSPEND_REASON_CPU_USAGE;
|
|
|
|
}
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
|
|
|
|
2009-02-26 17:12:55 +00:00
|
|
|
if (global_prefs.cpu_usage_limit < 99) { // round-off?
|
2006-05-21 22:03:36 +00:00
|
|
|
static double last_time=0, debt=0;
|
2008-01-11 04:34:34 +00:00
|
|
|
double diff = now - last_time;
|
|
|
|
last_time = now;
|
|
|
|
if (diff >= POLL_INTERVAL/2. && diff < POLL_INTERVAL*10.) {
|
|
|
|
debt += diff*global_prefs.cpu_usage_limit/100;
|
|
|
|
if (debt < 0) {
|
2010-03-10 18:59:40 +00:00
|
|
|
return SUSPEND_REASON_CPU_THROTTLE;
|
2008-01-11 04:34:34 +00:00
|
|
|
} else {
|
|
|
|
debt -= diff;
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
|
|
|
}
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
2008-09-29 18:51:46 +00:00
|
|
|
|
2009-12-17 18:09:23 +00:00
|
|
|
bool old_gpu_suspended = gpu_suspended;
|
2009-12-10 23:26:35 +00:00
|
|
|
gpu_suspended = false;
|
|
|
|
switch (gpu_mode.get_current()) {
|
|
|
|
case RUN_MODE_ALWAYS:
|
|
|
|
break;
|
|
|
|
case RUN_MODE_NEVER:
|
|
|
|
gpu_suspended = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (exclusive_gpu_app_running) {
|
|
|
|
gpu_suspended = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (user_active && !global_prefs.run_gpu_if_user_active) {
|
|
|
|
gpu_suspended = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-17 18:09:23 +00:00
|
|
|
if (log_flags.cpu_sched) {
|
|
|
|
if (old_gpu_suspended && !gpu_suspended) {
|
|
|
|
msg_printf(NULL, MSG_INFO, "[cpu_sched] resuming GPU activity");
|
|
|
|
} else if (!old_gpu_suspended && gpu_suspended) {
|
|
|
|
msg_printf(NULL, MSG_INFO, "[cpu_sched] suspending GPU activity");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-19 23:22:19 +00:00
|
|
|
return 0;
|
2003-10-18 19:35:58 +00:00
|
|
|
}
|
|
|
|
|
2005-12-24 06:32:07 +00:00
|
|
|
static string reason_string(int reason) {
|
2010-01-19 00:03:38 +00:00
|
|
|
switch (reason) {
|
|
|
|
case SUSPEND_REASON_BATTERIES: return " - on batteries";
|
|
|
|
case SUSPEND_REASON_USER_ACTIVE: return " - user is active";
|
|
|
|
case SUSPEND_REASON_USER_REQ: return " - user request";
|
|
|
|
case SUSPEND_REASON_TIME_OF_DAY: return " - time of day";
|
|
|
|
case SUSPEND_REASON_BENCHMARKS: return " - running CPU benchmarks";
|
|
|
|
case SUSPEND_REASON_DISK_SIZE: return " - out of disk space - change global prefs";
|
|
|
|
case SUSPEND_REASON_NO_RECENT_INPUT: return " - no recent user activity";
|
|
|
|
case SUSPEND_REASON_INITIAL_DELAY: return " - initial delay";
|
|
|
|
case SUSPEND_REASON_EXCLUSIVE_APP_RUNNING: return " - an exclusive app is running";
|
|
|
|
case SUSPEND_REASON_CPU_USAGE: return " - CPU usage is too high";
|
|
|
|
}
|
|
|
|
return "";
|
2005-12-24 06:32:07 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 20:57:12 +00:00
|
|
|
void print_suspend_tasks_message(int reason) {
|
|
|
|
string s_reason = "Suspending computation" + reason_string(reason);
|
|
|
|
msg_printf(NULL, MSG_INFO, s_reason.c_str());
|
|
|
|
}
|
|
|
|
|
2005-12-24 06:32:07 +00:00
|
|
|
int CLIENT_STATE::suspend_tasks(int reason) {
|
2010-03-10 18:59:40 +00:00
|
|
|
if (reason == SUSPEND_REASON_CPU_THROTTLE) {
|
2006-06-23 20:05:12 +00:00
|
|
|
if (log_flags.cpu_sched) {
|
2006-09-07 20:39:25 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, "[cpu_sched] Suspending - CPU throttle");
|
2006-06-23 20:05:12 +00:00
|
|
|
}
|
2006-05-21 22:03:36 +00:00
|
|
|
} else {
|
2008-05-22 20:57:12 +00:00
|
|
|
print_suspend_tasks_message(reason);
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
2010-03-02 01:24:03 +00:00
|
|
|
active_tasks.suspend_all(reason);
|
2003-10-18 19:35:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-05-21 22:03:36 +00:00
|
|
|
int CLIENT_STATE::resume_tasks(int reason) {
|
2010-03-10 18:59:40 +00:00
|
|
|
if (reason == SUSPEND_REASON_CPU_THROTTLE) {
|
2006-08-02 16:57:09 +00:00
|
|
|
if (log_flags.cpu_sched) {
|
2006-09-07 20:39:25 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, "[cpu_sched] Resuming - CPU throttle");
|
2006-08-02 16:57:09 +00:00
|
|
|
}
|
2006-05-21 22:03:36 +00:00
|
|
|
active_tasks.unsuspend_all();
|
|
|
|
} else {
|
|
|
|
msg_printf(NULL, MSG_INFO, "Resuming computation");
|
|
|
|
active_tasks.unsuspend_all();
|
2007-05-10 16:23:10 +00:00
|
|
|
request_schedule_cpus("Resuming computation");
|
2006-05-21 22:03:36 +00:00
|
|
|
}
|
2003-10-18 19:35:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-19 23:22:19 +00:00
|
|
|
int CLIENT_STATE::check_suspend_network() {
|
2009-10-07 18:42:51 +00:00
|
|
|
// no network traffic if we're allowing unsigned apps
|
|
|
|
//
|
|
|
|
if (unsigned_apps_ok) return SUSPEND_REASON_USER_REQ;
|
|
|
|
|
2006-11-10 17:55:22 +00:00
|
|
|
switch(network_mode.get_current()) {
|
2007-07-19 23:22:19 +00:00
|
|
|
case RUN_MODE_ALWAYS: return 0;
|
2006-11-10 17:55:22 +00:00
|
|
|
case RUN_MODE_NEVER:
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_USER_REQ;
|
2007-07-10 17:49:51 +00:00
|
|
|
}
|
|
|
|
if (!global_prefs.run_if_user_active && user_active) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_USER_ACTIVE;
|
2004-04-01 23:19:13 +00:00
|
|
|
}
|
2007-08-25 09:53:33 +00:00
|
|
|
if (global_prefs.net_times.suspended()) {
|
2007-07-19 23:22:19 +00:00
|
|
|
return SUSPEND_REASON_TIME_OF_DAY;
|
2005-06-08 23:55:21 +00:00
|
|
|
}
|
2009-11-13 17:49:18 +00:00
|
|
|
if (exclusive_app_running) {
|
2008-11-24 21:27:43 +00:00
|
|
|
return SUSPEND_REASON_EXCLUSIVE_APP_RUNNING;
|
|
|
|
}
|
2007-07-19 23:22:19 +00:00
|
|
|
return 0;
|
2004-04-01 23:19:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CLIENT_STATE::suspend_network(int reason) {
|
|
|
|
string s_reason;
|
2005-12-24 06:32:07 +00:00
|
|
|
s_reason = "Suspending network activity" + reason_string(reason);
|
2006-05-21 22:03:36 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, s_reason.c_str());
|
2004-04-01 23:19:13 +00:00
|
|
|
pers_file_xfers->suspend();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CLIENT_STATE::resume_network() {
|
2004-04-02 00:19:22 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, "Resuming network activity");
|
2004-04-01 23:19:13 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-10-01 08:15:58 +00:00
|
|
|
// call this only after parsing global prefs
|
|
|
|
//
|
|
|
|
PROJECT* CLIENT_STATE::global_prefs_source_project() {
|
2004-10-06 19:09:37 +00:00
|
|
|
return lookup_project(global_prefs.source_project);
|
2004-10-01 08:15:58 +00:00
|
|
|
}
|
|
|
|
|
2004-03-30 23:05:34 +00:00
|
|
|
void CLIENT_STATE::show_global_prefs_source(bool found_venue) {
|
2004-10-01 08:15:58 +00:00
|
|
|
PROJECT* pp = global_prefs_source_project();
|
2004-03-30 23:05:34 +00:00
|
|
|
if (pp) {
|
2009-02-26 17:12:55 +00:00
|
|
|
msg_printf(pp, MSG_INFO,
|
2006-01-17 22:48:09 +00:00
|
|
|
"General prefs: from %s (last modified %s)",
|
2004-03-30 23:05:34 +00:00
|
|
|
pp->get_project_name(), time_to_string(global_prefs.mod_time)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
2006-01-17 22:48:09 +00:00
|
|
|
"General prefs: from %s (last modified %s)",
|
2004-10-06 19:09:37 +00:00
|
|
|
global_prefs.source_project,
|
2004-03-30 23:05:34 +00:00
|
|
|
time_to_string(global_prefs.mod_time)
|
|
|
|
);
|
|
|
|
}
|
2004-10-01 08:15:58 +00:00
|
|
|
if (strlen(main_host_venue)) {
|
2009-02-26 17:12:55 +00:00
|
|
|
msg_printf(pp, MSG_INFO, "Computer location: %s", main_host_venue);
|
2004-03-30 23:05:34 +00:00
|
|
|
if (found_venue) {
|
2004-03-31 23:39:12 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
2006-01-17 22:48:09 +00:00
|
|
|
"General prefs: using separate prefs for %s", main_host_venue
|
2004-03-31 23:39:12 +00:00
|
|
|
);
|
2004-03-30 23:05:34 +00:00
|
|
|
} else {
|
2009-02-26 17:12:55 +00:00
|
|
|
msg_printf(pp, MSG_INFO,
|
2006-01-17 22:48:09 +00:00
|
|
|
"General prefs: no separate prefs for %s; using your defaults",
|
2004-10-01 08:15:58 +00:00
|
|
|
main_host_venue
|
2004-03-31 23:39:12 +00:00
|
|
|
);
|
2004-03-30 23:05:34 +00:00
|
|
|
}
|
|
|
|
} else {
|
2009-02-26 17:12:55 +00:00
|
|
|
msg_printf(pp, MSG_INFO, "Host location: none");
|
|
|
|
msg_printf(pp, MSG_INFO, "General prefs: using your defaults");
|
2004-03-30 23:05:34 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-01 18:48:34 +00:00
|
|
|
|
|
|
|
// parse user's project preferences,
|
|
|
|
// generating FILE_REF and FILE_INFO objects for each <app_file> element.
|
|
|
|
//
|
|
|
|
int PROJECT::parse_preferences_for_user_files() {
|
|
|
|
char buf[1024];
|
|
|
|
string timestamp, open_name, url, filename;
|
|
|
|
FILE_INFO* fip;
|
|
|
|
FILE_REF fr;
|
|
|
|
|
|
|
|
user_files.clear();
|
2008-08-09 16:39:20 +00:00
|
|
|
size_t n=0, start, end;
|
2004-10-01 18:48:34 +00:00
|
|
|
while (1) {
|
2008-08-09 16:39:20 +00:00
|
|
|
start = project_specific_prefs.find("<app_file>", n);
|
|
|
|
if (start == string::npos) break;
|
|
|
|
end = project_specific_prefs.find("</app_file>", n);
|
|
|
|
if (end == string::npos) break;
|
|
|
|
start += strlen("<app_file>");
|
|
|
|
string x = project_specific_prefs.substr(start, end);
|
|
|
|
n = end + strlen("</app_file>");
|
|
|
|
|
|
|
|
strlcpy(buf, x.c_str(), sizeof(buf));
|
2004-10-01 18:48:34 +00:00
|
|
|
if (!parse_str(buf, "<timestamp>", timestamp)) break;
|
|
|
|
if (!parse_str(buf, "<open_name>", open_name)) break;
|
|
|
|
if (!parse_str(buf, "<url>", url)) break;
|
|
|
|
|
|
|
|
filename = open_name + "_" + timestamp;
|
|
|
|
fip = gstate.lookup_file_info(this, filename.c_str());
|
|
|
|
if (!fip) {
|
|
|
|
fip = new FILE_INFO;
|
|
|
|
fip->project = this;
|
2005-03-09 23:28:37 +00:00
|
|
|
fip->urls.push_back(url);
|
2004-10-01 18:48:34 +00:00
|
|
|
strcpy(fip->name, filename.c_str());
|
|
|
|
fip->is_user_file = true;
|
|
|
|
gstate.file_infos.push_back(fip);
|
|
|
|
}
|
|
|
|
|
|
|
|
fr.file_info = fip;
|
|
|
|
strcpy(fr.open_name, open_name.c_str());
|
|
|
|
user_files.push_back(fr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2004-12-08 00:40:19 +00:00
|
|
|
|
2007-08-01 20:26:08 +00:00
|
|
|
// Read global preferences into the global_prefs structure.
|
2006-10-26 21:22:38 +00:00
|
|
|
// 1) read the override file to get venue in case it's there
|
2007-08-01 20:26:08 +00:00
|
|
|
// 2) read global_prefs.xml
|
2006-10-06 22:48:07 +00:00
|
|
|
// 3) read the override file again
|
2006-06-01 20:53:59 +00:00
|
|
|
//
|
2007-08-01 20:26:08 +00:00
|
|
|
// This is called:
|
|
|
|
// - on startup
|
|
|
|
// - on completion of a scheduler or AMS RPC, if they sent prefs
|
|
|
|
// - in response to read_global_prefs_override GUI RPC
|
|
|
|
//
|
2006-06-01 20:53:59 +00:00
|
|
|
void CLIENT_STATE::read_global_prefs() {
|
|
|
|
bool found_venue;
|
2009-02-26 00:52:50 +00:00
|
|
|
bool venue_specified_in_override = false;
|
2006-06-01 20:53:59 +00:00
|
|
|
int retval;
|
2009-02-18 19:47:02 +00:00
|
|
|
FILE* f;
|
2007-06-22 18:53:55 +00:00
|
|
|
string foo;
|
2006-10-06 22:48:07 +00:00
|
|
|
|
2007-06-22 18:53:55 +00:00
|
|
|
retval = read_file_string(GLOBAL_PREFS_OVERRIDE_FILE, foo);
|
|
|
|
if (!retval) {
|
2009-02-18 19:47:02 +00:00
|
|
|
parse_str(foo.c_str(), "<host_venue>", main_host_venue, sizeof(main_host_venue));
|
2009-02-26 00:52:50 +00:00
|
|
|
if (strlen(main_host_venue)) {
|
|
|
|
venue_specified_in_override = true;
|
|
|
|
}
|
2009-02-18 19:47:02 +00:00
|
|
|
}
|
2006-06-01 20:53:59 +00:00
|
|
|
|
2006-06-02 20:32:20 +00:00
|
|
|
retval = global_prefs.parse_file(
|
|
|
|
GLOBAL_PREFS_FILE_NAME, main_host_venue, found_venue
|
|
|
|
);
|
2006-06-01 20:53:59 +00:00
|
|
|
if (retval) {
|
2008-08-05 21:40:53 +00:00
|
|
|
if (retval == ERR_FOPEN) {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
"No general preferences found - using BOINC defaults"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
"Couldn't parse preferences file - using BOINC defaults"
|
|
|
|
);
|
|
|
|
boinc_delete_file(GLOBAL_PREFS_FILE_NAME);
|
|
|
|
}
|
2009-02-18 19:47:02 +00:00
|
|
|
global_prefs.init();
|
2006-06-01 20:53:59 +00:00
|
|
|
} else {
|
2009-02-26 00:52:50 +00:00
|
|
|
if (!venue_specified_in_override) {
|
|
|
|
// check that the source project's venue matches main_host_venue.
|
|
|
|
// If not, read file again.
|
|
|
|
// This is a fix for cases where main_host_venue is out of synch
|
|
|
|
//
|
|
|
|
PROJECT* p = global_prefs_source_project();
|
|
|
|
if (p && strcmp(main_host_venue, p->host_venue)) {
|
|
|
|
strcpy(main_host_venue, p->host_venue);
|
|
|
|
global_prefs.parse_file(GLOBAL_PREFS_FILE_NAME, main_host_venue, found_venue);
|
|
|
|
}
|
2009-02-18 19:47:02 +00:00
|
|
|
}
|
2006-06-01 20:53:59 +00:00
|
|
|
show_global_prefs_source(found_venue);
|
|
|
|
}
|
|
|
|
|
2006-06-02 20:32:20 +00:00
|
|
|
// read the override file
|
|
|
|
//
|
2006-10-06 22:48:07 +00:00
|
|
|
f = fopen(GLOBAL_PREFS_OVERRIDE_FILE, "r");
|
2006-06-01 20:53:59 +00:00
|
|
|
if (f) {
|
|
|
|
MIOFILE mf;
|
2006-11-14 10:12:24 +00:00
|
|
|
GLOBAL_PREFS_MASK mask;
|
2006-06-01 20:53:59 +00:00
|
|
|
mf.init_file(f);
|
2006-09-11 19:03:00 +00:00
|
|
|
XML_PARSER xp(&mf);
|
2006-11-14 10:12:24 +00:00
|
|
|
global_prefs.parse_override(xp, "", found_venue, mask);
|
2006-06-01 20:53:59 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, "Reading preferences override file");
|
|
|
|
fclose(f);
|
|
|
|
}
|
2006-06-02 20:32:20 +00:00
|
|
|
|
2009-11-23 22:47:10 +00:00
|
|
|
msg_printf(NULL, MSG_INFO, "Preferences:");
|
2007-03-27 18:36:22 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
2009-11-23 22:47:10 +00:00
|
|
|
" max memory usage when active: %.2fMB",
|
2007-04-20 16:28:35 +00:00
|
|
|
(host_info.m_nbytes*global_prefs.ram_max_used_busy_frac)/MEGA
|
2007-04-20 03:11:48 +00:00
|
|
|
);
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
2009-11-23 22:47:10 +00:00
|
|
|
" max memory usage when idle: %.2fMB",
|
2009-02-18 19:47:02 +00:00
|
|
|
(host_info.m_nbytes*global_prefs.ram_max_used_idle_frac)/MEGA
|
2007-04-20 03:11:48 +00:00
|
|
|
);
|
2008-11-02 20:09:59 +00:00
|
|
|
double x;
|
|
|
|
total_disk_usage(x);
|
2007-04-20 03:11:48 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
2009-11-23 22:47:10 +00:00
|
|
|
" max disk usage: %.2fGB",
|
2008-11-02 20:09:59 +00:00
|
|
|
allowed_disk_usage(x)/GIGA
|
2007-03-27 18:36:22 +00:00
|
|
|
);
|
2006-10-25 00:01:18 +00:00
|
|
|
// max_cpus, bandwidth limits may have changed
|
2006-06-02 20:32:20 +00:00
|
|
|
//
|
|
|
|
set_ncpus();
|
2008-10-22 22:25:16 +00:00
|
|
|
if (ncpus != host_info.p_ncpus) {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
2009-11-23 22:47:10 +00:00
|
|
|
" max CPUs used: %d", ncpus
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!global_prefs.run_if_user_active) {
|
|
|
|
msg_printf(NULL, MSG_INFO, " don't compute while active");
|
|
|
|
}
|
|
|
|
if (!global_prefs.run_gpu_if_user_active) {
|
|
|
|
msg_printf(NULL, MSG_INFO, " don't use GPU while active");
|
|
|
|
}
|
2010-02-18 23:53:14 +00:00
|
|
|
if (global_prefs.suspend_cpu_usage) {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
" suspend work if non-BOINC CPU load exceeds %.0f %%",
|
|
|
|
global_prefs.suspend_cpu_usage
|
|
|
|
);
|
|
|
|
}
|
2009-11-23 22:47:10 +00:00
|
|
|
if (global_prefs.max_bytes_sec_down) {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
" max download rate: %.0f bytes/sec",
|
|
|
|
global_prefs.max_bytes_sec_down
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (global_prefs.max_bytes_sec_up) {
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
" max upload rate: %.0f bytes/sec",
|
|
|
|
global_prefs.max_bytes_sec_up
|
2008-10-22 22:25:16 +00:00
|
|
|
);
|
|
|
|
}
|
2009-02-18 19:47:02 +00:00
|
|
|
file_xfers->set_bandwidth_limits(true);
|
|
|
|
file_xfers->set_bandwidth_limits(false);
|
2009-11-23 22:47:10 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
" (to change, visit the web site of an attached project,"
|
|
|
|
);
|
|
|
|
msg_printf(NULL, MSG_INFO,
|
|
|
|
" or click on Preferences)"
|
|
|
|
);
|
2009-02-18 19:47:02 +00:00
|
|
|
request_schedule_cpus("Prefs update");
|
|
|
|
request_work_fetch("Prefs update");
|
2006-06-01 20:53:59 +00:00
|
|
|
}
|
|
|
|
|
2006-06-01 19:03:00 +00:00
|
|
|
int CLIENT_STATE::save_global_prefs(
|
|
|
|
char* global_prefs_xml, char* master_url, char* scheduler_url
|
|
|
|
) {
|
|
|
|
FILE* f = boinc_fopen(GLOBAL_PREFS_FILE_NAME, "w");
|
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
fprintf(f,
|
|
|
|
"<global_preferences>\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
// tag with the project and scheduler URL,
|
|
|
|
// but only if not already tagged
|
|
|
|
//
|
|
|
|
if (!strstr(global_prefs_xml, "<source_project>")) {
|
|
|
|
fprintf(f,
|
|
|
|
" <source_project>%s</source_project>\n"
|
|
|
|
" <source_scheduler>%s</source_scheduler>\n",
|
|
|
|
master_url,
|
|
|
|
scheduler_url
|
|
|
|
);
|
|
|
|
}
|
|
|
|
fprintf(f,
|
|
|
|
"%s"
|
|
|
|
"</global_preferences>\n",
|
|
|
|
global_prefs_xml
|
|
|
|
);
|
|
|
|
fclose(f);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:15:16 +00:00
|
|
|
// amount of RAM usable now
|
|
|
|
//
|
2006-10-02 23:42:38 +00:00
|
|
|
double CLIENT_STATE::available_ram() {
|
|
|
|
if (user_active) {
|
|
|
|
return host_info.m_nbytes * global_prefs.ram_max_used_busy_frac;
|
|
|
|
} else {
|
2009-02-18 19:47:02 +00:00
|
|
|
return host_info.m_nbytes * global_prefs.ram_max_used_idle_frac;
|
2006-10-02 23:42:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:15:16 +00:00
|
|
|
// max amount that will ever be usable
|
|
|
|
//
|
2006-10-02 23:42:38 +00:00
|
|
|
double CLIENT_STATE::max_available_ram() {
|
2009-02-18 19:47:02 +00:00
|
|
|
return host_info.m_nbytes*std::max(
|
|
|
|
global_prefs.ram_max_used_busy_frac, global_prefs.ram_max_used_idle_frac
|
|
|
|
);
|
2006-10-02 23:42:38 +00:00
|
|
|
}
|
|
|
|
|
2005-01-02 18:29:53 +00:00
|
|
|
const char *BOINC_RCSID_92ad99cddf = "$Id$";
|