mirror of
https://github.com/BOINC/boinc.git
synced 2025-02-26 20:45:07 +00:00
*** empty log message ***
svn path=/trunk/boinc/; revision=11107
This commit is contained in:
parent
1a99fddbd1
commit
59d5508392
@ -214,9 +214,7 @@ static int boinc_worker_thread_cpu_time(double& cpu) {
|
||||
// communicate to the core client (via shared mem)
|
||||
// the current CPU time and fraction done
|
||||
//
|
||||
static bool update_app_progress(
|
||||
double cpu_t, double cp_cpu_t, double rss=0, double vm=0
|
||||
) {
|
||||
static bool update_app_progress(double cpu_t, double cp_cpu_t) {
|
||||
char msg_buf[MSG_CHANNEL_SIZE], buf[256];
|
||||
|
||||
if (standalone) return true;
|
||||
@ -235,14 +233,6 @@ static bool update_app_progress(
|
||||
sprintf(buf, "<fraction_done>%2.8f</fraction_done>\n", fdone);
|
||||
strcat(msg_buf, buf);
|
||||
}
|
||||
if (rss) {
|
||||
sprintf(buf, "<rss_bytes>%f</rss_bytes>\n", rss);
|
||||
strcat(msg_buf, buf);
|
||||
}
|
||||
if (vm) {
|
||||
sprintf(buf, "<vm_bytes>%f</vm_bytes>\n", vm);
|
||||
strcat(msg_buf, buf);
|
||||
}
|
||||
if (fpops_per_cpu_sec) {
|
||||
sprintf(buf, "<fpops_per_cpu_sec>%f</fpops_per_cpu_sec>\n", fpops_per_cpu_sec);
|
||||
strcat(msg_buf, buf);
|
||||
|
@ -9782,3 +9782,31 @@ David 5 Sept 2006
|
||||
|
||||
lib/
|
||||
common_defs.h
|
||||
|
||||
David 5 Sept 2006
|
||||
- first pass at enforcing RAM limits:
|
||||
- if computer is in use (kbd/mouse input)
|
||||
BOINC will use at most half of RAM
|
||||
(i.e. it won't run a set of apps whose working set size
|
||||
exceeds RAM/2)
|
||||
_ if computer is not in use, BOINC will use at most all of RAM
|
||||
(it won't run a set of apps whose WSS exceeds RAM)
|
||||
|
||||
This is pretty lame. For example, in case 2 BOINC will
|
||||
run any set of programs, since by definitions their WSs
|
||||
all fit in RAM (they may be thrashing).
|
||||
So we need to do some thinking/experimenting.
|
||||
- Fix HTTP bug that affects 64-bit compiles
|
||||
(from Pav Lucistnik)
|
||||
|
||||
api/
|
||||
boinc_api.C
|
||||
client/
|
||||
app.C,h
|
||||
app_control.C
|
||||
client_state.h
|
||||
cpu_sched.C
|
||||
cs_prefs.C
|
||||
http_curl.h
|
||||
html/user/
|
||||
show_user.php
|
||||
|
75
client/app.C
75
client/app.C
@ -193,6 +193,47 @@ void ACTIVE_TASK_SET::free_mem() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void ACTIVE_TASK_SET::get_memory_usage() {
|
||||
static double last_mem_time=0;
|
||||
unsigned int i;
|
||||
|
||||
if (gstate.now - last_mem_time < 10) return;
|
||||
|
||||
last_mem_time = gstate.now;
|
||||
vector<PROCINFO> piv;
|
||||
PROCINFO pi;
|
||||
procinfo_setup(piv);
|
||||
for (i=0; i<active_tasks.size(); i++) {
|
||||
ACTIVE_TASK* atp = active_tasks[i];
|
||||
if (atp->task_state == PROCESS_EXECUTING) {
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
pi.id = atp->pid;
|
||||
procinfo_app(pi, piv);
|
||||
atp->rss_bytes = pi.working_set_size;
|
||||
atp->vm_bytes = pi.swap_size;
|
||||
if (log_flags.mem_usage_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"%s: RAM %dKB, page %dKB, user CPU %f, kernel CPU %f",
|
||||
atp->result->name,
|
||||
(int)(pi.working_set_size/1024), (int)(pi.swap_size/1024),
|
||||
pi.user_time, pi.kernel_time
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// the following is not useful because most OSs don't
|
||||
// move idle processes out of RAM, so physical memory is always full
|
||||
//
|
||||
procinfo_other(pi, piv);
|
||||
msg_printf(NULL, MSG_INFO, "All others: RAM %dKB, page %dKB, user %f, kernel %f",
|
||||
(int)(pi.working_set_size/1024), (int)(pi.swap_size/1024),
|
||||
pi.user_time, pi.kernel_time
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Do periodic checks on running apps:
|
||||
// - get latest CPU time and % done info
|
||||
// - check if any has exited, and clean up
|
||||
@ -210,6 +251,7 @@ bool ACTIVE_TASK_SET::poll() {
|
||||
send_trickle_downs();
|
||||
graphics_poll();
|
||||
process_control_poll();
|
||||
get_memory_usage();
|
||||
action |= check_rsc_limits_exceeded();
|
||||
action |= get_msgs();
|
||||
for (i=0; i<active_tasks.size(); i++) {
|
||||
@ -225,35 +267,6 @@ bool ACTIVE_TASK_SET::poll() {
|
||||
gstate.set_client_state_dirty("ACTIVE_TASK_SET::poll");
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || (defined(__GNUG__) && !defined(__APPLE__))
|
||||
if (log_flags.mem_usage_debug) {
|
||||
static double last_mem_time=0;
|
||||
if (gstate.now - last_mem_time > 10) {
|
||||
last_mem_time = gstate.now;
|
||||
vector<PROCINFO> piv;
|
||||
PROCINFO pi;
|
||||
procinfo_setup(piv);
|
||||
for (i=0; i<active_tasks.size(); i++) {
|
||||
ACTIVE_TASK* atp = active_tasks[i];
|
||||
if (atp->task_state == PROCESS_EXECUTING) {
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
pi.id = atp->pid;
|
||||
procinfo_app(pi, piv);
|
||||
msg_printf(NULL, MSG_INFO, "%s: RAM %dKB, page %dKB, user %f, kernel %f",
|
||||
atp->result->name,
|
||||
(int)(pi.working_set_size/1024), (int)(pi.swap_size/1024),
|
||||
pi.user_time, pi.kernel_time
|
||||
);
|
||||
}
|
||||
}
|
||||
procinfo_other(pi, piv);
|
||||
msg_printf(NULL, MSG_INFO, "All others: RAM %dKB, page %dKB, user %f, kernel %f",
|
||||
(int)(pi.working_set_size/1024), (int)(pi.swap_size/1024),
|
||||
pi.user_time, pi.kernel_time
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return action;
|
||||
}
|
||||
@ -477,8 +490,8 @@ int ACTIVE_TASK::parse(MIOFILE& fin) {
|
||||
else if (parse_double(buf, "<fraction_done>", fraction_done)) continue;
|
||||
else if (parse_double(buf, "<current_cpu_time>", current_cpu_time)) continue;
|
||||
else if (parse_int(buf, "<active_task_state>", n)) continue;
|
||||
else if (parse_double(buf, "<vm_bytes>", x)) continue;
|
||||
else if (parse_double(buf, "<rss_bytes>", x)) continue;
|
||||
else if (parse_double(buf, "<vm_bytes>", vm_bytes)) continue;
|
||||
else if (parse_double(buf, "<rss_bytes>", rss_bytes)) continue;
|
||||
else if (match_tag(buf, "<supports_graphics/>")) continue;
|
||||
else if (parse_int(buf, "<graphics_mode_acked>", n)) continue;
|
||||
else if (parse_int(buf, "<scheduler_state>", n)) continue;
|
||||
|
@ -104,9 +104,9 @@ public:
|
||||
double current_cpu_time;
|
||||
// most recent CPU time reported by app
|
||||
double vm_bytes;
|
||||
// virtual memory used
|
||||
// swap space used
|
||||
double rss_bytes;
|
||||
// resident set size
|
||||
// working set size
|
||||
int current_disk_usage(double&);
|
||||
// disk used by output files and temp files of this task
|
||||
char slot_dir[256]; // directory where process runs
|
||||
@ -230,6 +230,7 @@ public:
|
||||
void network_available(); // notify tasks that network is available
|
||||
void free_mem();
|
||||
bool slot_taken(int);
|
||||
void get_memory_usage();
|
||||
|
||||
// screensaver-related functions
|
||||
ACTIVE_TASK* get_ss_app();
|
||||
|
@ -462,25 +462,6 @@ bool ACTIVE_TASK::check_max_disk_exceeded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// if an app has exceeded its maximum allowed memory, abort it
|
||||
//
|
||||
bool ACTIVE_TASK::check_max_mem_exceeded() {
|
||||
// TODO: calculate working set size elsewhere
|
||||
if (working_set_size > max_mem_usage || working_set_size/1048576 > gstate.global_prefs.max_memory_mbytes) {
|
||||
msg_printf(
|
||||
result->project, MSG_INFO,
|
||||
"Aborting task %s: exceeded memory limit %f\n",
|
||||
result->name,
|
||||
min(max_mem_usage, gstate.global_prefs.max_memory_mbytes*1048576)
|
||||
);
|
||||
abort_task(ERR_RSC_LIMIT_EXCEEDED, "Maximum memory usage exceeded");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ACTIVE_TASK::check_max_mem_exceeded() {
|
||||
if (max_mem_usage != 0 && rss_bytes > max_mem_usage) {
|
||||
msg_printf(
|
||||
@ -887,8 +868,6 @@ bool ACTIVE_TASK::get_app_status_msg() {
|
||||
}
|
||||
parse_double(msg_buf, "<current_cpu_time>", current_cpu_time);
|
||||
parse_double(msg_buf, "<checkpoint_cpu_time>", checkpoint_cpu_time);
|
||||
parse_double(msg_buf, "<vm_bytes>", vm_bytes);
|
||||
parse_double(msg_buf, "<rss_bytes>", rss_bytes);
|
||||
parse_double(msg_buf, "<fpops_per_cpu_sec>", result->fpops_per_cpu_sec);
|
||||
parse_double(msg_buf, "<fpops_cumulative>", result->fpops_cumulative);
|
||||
parse_double(msg_buf, "<intops_per_cpu_sec>", result->intops_per_cpu_sec);
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
bool started_by_screensaver;
|
||||
bool exit_when_idle;
|
||||
bool check_all_logins;
|
||||
bool user_active; // there has been recent mouse/kbd input
|
||||
bool return_results_immediately;
|
||||
bool allow_remote_gui_rpc;
|
||||
int cmdline_gui_rpc_port;
|
||||
|
@ -564,12 +564,31 @@ bool CLIENT_STATE::enforce_schedule() {
|
||||
running_tasks.pop_back();
|
||||
}
|
||||
|
||||
// count of how many tasks have next_scheduler_state = SCHEDULED
|
||||
double mem_used = 0;
|
||||
double max_mem_used;
|
||||
|
||||
// if user is active, use at most half of RAM;
|
||||
// otherwise use all of it
|
||||
//
|
||||
if (gstate.user_active) {
|
||||
max_mem_used = host_info.m_nbytes/2;
|
||||
} else {
|
||||
max_mem_used = host_info.m_nbytes;
|
||||
}
|
||||
if (log_flags.mem_usage_debug) {
|
||||
msg_printf(0, MSG_INFO,
|
||||
"enforce: max mem used %f",
|
||||
max_mem_used
|
||||
);
|
||||
}
|
||||
|
||||
// keep track of how many tasks we plan on running
|
||||
// (i.e. have next_scheduler_state = SCHEDULED)
|
||||
//
|
||||
int nrunning = running_tasks.size();
|
||||
|
||||
// Loop through the scheduled results
|
||||
// to see if they should preempt something
|
||||
// to see if they should preempt a running task
|
||||
//
|
||||
for (i=0; i<ordered_scheduled_results.size(); i++) {
|
||||
RESULT* rp = ordered_scheduled_results[i];
|
||||
@ -592,7 +611,40 @@ bool CLIENT_STATE::enforce_schedule() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (atp) continue; // the scheduled result is already running.
|
||||
if (atp) {
|
||||
// the scheduled result is already running.
|
||||
// see if it fits in mem
|
||||
//
|
||||
if (mem_used + atp->rss_bytes > max_mem_used) {
|
||||
atp->next_scheduler_state = CPU_SCHED_PREEMPTED;
|
||||
nrunning--;
|
||||
if (log_flags.mem_usage_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"enforce: result %s mem1 %f %f %f",
|
||||
rp->name, mem_used, atp->rss_bytes, max_mem_used
|
||||
);
|
||||
}
|
||||
} else {
|
||||
mem_used += atp->rss_bytes;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if the result already has a (non-running) active task,
|
||||
// see if it fits in mem
|
||||
//
|
||||
atp = active_tasks.lookup_result(rp);
|
||||
if (atp) {
|
||||
if (mem_used + atp->rss_bytes > max_mem_used) {
|
||||
if (log_flags.mem_usage_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"enforce: result %s mem2 %f %f %f",
|
||||
rp->name, mem_used, atp->rss_bytes, max_mem_used
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The scheduled result is not already running.
|
||||
// Preempt something if needed and possible.
|
||||
@ -633,6 +685,24 @@ bool CLIENT_STATE::enforce_schedule() {
|
||||
atp = get_task(rp);
|
||||
atp->next_scheduler_state = CPU_SCHED_SCHEDULED;
|
||||
nrunning++;
|
||||
mem_used += atp->rss_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we don't exceed RAM limits
|
||||
//
|
||||
for (i=0; i<running_tasks.size(); i++) {
|
||||
atp = running_tasks[i];
|
||||
if (mem_used + atp->rss_bytes > max_mem_used) {
|
||||
atp->next_scheduler_state = CPU_SCHED_PREEMPTED;
|
||||
if (log_flags.mem_usage_debug) {
|
||||
msg_printf(atp->result->project, MSG_INFO,
|
||||
"enforce: result %s mem3 %f %f %f",
|
||||
atp->result->name, mem_used, atp->rss_bytes, max_mem_used
|
||||
);
|
||||
}
|
||||
} else {
|
||||
mem_used += atp->rss_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,9 @@ void CLIENT_STATE::check_suspend_activities(int& reason) {
|
||||
return;
|
||||
}
|
||||
|
||||
user_active = !host_info.users_idle(
|
||||
check_all_logins, global_prefs.idle_time_to_run
|
||||
);
|
||||
switch(user_run_request) {
|
||||
case RUN_MODE_ALWAYS: break;
|
||||
case RUN_MODE_NEVER:
|
||||
@ -150,11 +153,7 @@ void CLIENT_STATE::check_suspend_activities(int& reason) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!global_prefs.run_if_user_active
|
||||
&& !host_info.users_idle(
|
||||
check_all_logins, global_prefs.idle_time_to_run
|
||||
)
|
||||
) {
|
||||
if (!global_prefs.run_if_user_active && user_active) {
|
||||
reason = SUSPEND_REASON_USER_ACTIVE;
|
||||
return;
|
||||
}
|
||||
|
@ -89,8 +89,10 @@ public:
|
||||
|
||||
bool want_download; // at most one should be true
|
||||
bool want_upload;
|
||||
int connect_error; // errno from connect() (not used for anything)
|
||||
int response; // HTTP status code from server
|
||||
long connect_error; // errno from connect() (not used for anything)
|
||||
long response; // HTTP status code from server
|
||||
// the above two MUST be long (not int)
|
||||
// otherwise breaks on 64-bit machines
|
||||
double start_time;
|
||||
double xfer_speed;
|
||||
double bytes_xferred; // bytes transferred in this session
|
||||
|
@ -154,6 +154,7 @@ show_name("Tim Lan");
|
||||
show_name("Egon Larsson");
|
||||
show_name("Gilson Laurent");
|
||||
show_name("Matt Lebofsky");
|
||||
show_name("Pav Lucistnik");
|
||||
show_name("Bernd Machenschalk");
|
||||
show_name("Christopher Malton");
|
||||
show_name("Sebastian Masch");
|
||||
|
@ -26,11 +26,11 @@ if ($format=="xml"){
|
||||
start_cache(USER_PAGE_TTL, $cache_args);
|
||||
db_init();
|
||||
if ($auth){
|
||||
$user = lookup_user_auth($auth);
|
||||
$show_hosts = true;
|
||||
$user = lookup_user_auth($auth);
|
||||
$show_hosts = true;
|
||||
} else {
|
||||
$user = lookup_user_id($id);
|
||||
$show_hosts = false;
|
||||
$show_hosts = false;
|
||||
}
|
||||
if (!$user) xml_error("no such user ID");
|
||||
|
||||
@ -42,14 +42,14 @@ if ($format=="xml"){
|
||||
$cache_args="userid=".$id;
|
||||
$cached_data = get_cached_data(TOP_PAGES_TTL,$cache_args);
|
||||
if ($cached_data){
|
||||
// We found some old but non-stale data, let's use it
|
||||
$user = unserialize($cached_data);
|
||||
// We found some old but non-stale data, let's use it
|
||||
$user = unserialize($cached_data);
|
||||
} else {
|
||||
// No data was found, generate new data for the cache and store it
|
||||
db_init();
|
||||
// No data was found, generate new data for the cache and store it
|
||||
db_init();
|
||||
$user = lookup_user_id($id);
|
||||
$user = getForumPreferences($user);
|
||||
set_cache_data(serialize($user),$cache_args);
|
||||
$user = getForumPreferences($user);
|
||||
set_cache_data(serialize($user),$cache_args);
|
||||
}
|
||||
if (!$user->id) error_page("No such user found - please check the ID and try again. If the user is very new it may take a while before it can be displayed.");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user