Skip to content

Commit 36076fc

Browse files
authored
Merge pull request #6403 from BOINC/dpa_docker_cpu
client: avoid erroneous 'suspended - non-BOINC CPU' when running Docker apps
2 parents a97d69a + ea99566 commit 36076fc

5 files changed

Lines changed: 56 additions & 16 deletions

File tree

client/app.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ void ACTIVE_TASK_SET::get_memory_usage() {
415415
v = &(atp->other_pids);
416416
}
417417
procinfo_app(pi, v, pm, atp->app_version->graphics_exec_file);
418-
if (atp->app_version->is_vm_app) {
418+
if (atp->app_version->is_vbox_app) {
419419
vbox_app_running = true;
420420
// the memory of virtual machine apps is not reported correctly,
421421
// at least on Windows. Use the VM size instead.
@@ -538,12 +538,29 @@ void ACTIVE_TASK_SET::get_memory_usage() {
538538

539539
#if defined(__linux__) || defined(_WIN32) || defined(__APPLE__)
540540
// compute non_boinc_cpu_usage
541-
// Improved version for systems where we can get total CPU (Win, Linux, Mac)
541+
// Improved version for systems where we can get total CPU
542+
// (Win, Linux, Mac)
542543
//
543544
static double last_nbrc=0;
544545
double total_cpu_time_now = total_cpu_time();
545-
if (total_cpu_time_now != 0.0) { // total_cpu_time() returns 0.0 on error
546-
double nbrc = total_cpu_time_now - boinc_related_cpu_time(pm, vbox_app_running);
546+
547+
// total_cpu_time() returns 0.0 on error
548+
//
549+
if (total_cpu_time_now != 0.0) {
550+
double brc = boinc_related_cpu_time(pm, vbox_app_running);
551+
#ifndef _WIN32
552+
// on Win, boinc_related_cpu_time() includes CPU time of Docker jobs.
553+
// On other platforms we need to do it by looking at the
554+
// reported CPU times of the jobs
555+
// (which may be less reliable/accurate)
556+
//
557+
for (ACTIVE_TASK* atp: active_tasks) {
558+
if (atp->app_version->is_docker_app) {
559+
brc += atp->current_cpu_time;
560+
}
561+
}
562+
#endif
563+
double nbrc = total_cpu_time_now - brc;
547564
double delta_nbrc = nbrc - last_nbrc;
548565
if (delta_nbrc < 0) delta_nbrc = 0;
549566
last_nbrc = nbrc;

client/client_types.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,8 @@ void APP_VERSION::init() {
882882
graphics_exec_path[0] = 0;
883883
graphics_exec_file[0] = 0;
884884
max_working_set_size = 0;
885-
is_vm_app = false;
885+
is_vbox_app = false;
886+
is_docker_app = false;
886887
is_wrapper = false;
887888
index = 0;
888889
#ifdef SIM
@@ -902,7 +903,10 @@ int APP_VERSION::parse(XML_PARSER& xp) {
902903
dont_throttle = true;
903904
}
904905
if (strstr(plan_class, "vbox")) {
905-
is_vm_app = true;
906+
is_vbox_app = true;
907+
}
908+
if (strstr(plan_class, "docker")) {
909+
is_docker_app = true;
906910
}
907911
return 0;
908912
}
@@ -915,9 +919,6 @@ int APP_VERSION::parse(XML_PARSER& xp) {
915919
);
916920
return retval;
917921
}
918-
if (strstr(file_ref.file_name, "vboxwrapper")) {
919-
is_vm_app = true;
920-
}
921922
app_files.push_back(file_ref);
922923
continue;
923924
}

client/client_types.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,10 @@ struct APP_VERSION {
372372
// to use this much RAM,
373373
// so that we don't run a long sequence of jobs,
374374
// each of which turns out not to fit in available RAM
375-
bool is_vm_app;
376-
// currently this set if plan class includes "vbox" (kludge)
375+
bool is_vbox_app;
376+
// set if plan class includes "vbox"
377+
bool is_docker_app;
378+
// set if plan class includes "docker"
377379
bool is_wrapper;
378380
// the main program is a wrapper; run it above idle priority
379381

lib/procinfo.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,11 @@ void find_children(PROC_MAP& pm) {
123123
}
124124
}
125125

126-
// get resource usage of non-BOINC apps
126+
// get resource usage of non-BOINC apps running above background priority.
127127
// NOTE: this is flawed because it doesn't account for short-lived processes.
128-
// It's not used on Win, Mac, or Linux, which have better ways of getting total CPU usage.
128+
// It's not used on Win, Mac, or Linux,
129+
// which have ways of getting total CPU usage.
130+
// See client/app.cpp
129131
//
130132
void procinfo_non_boinc(PROCINFO& procinfo, PROC_MAP& pm) {
131133
procinfo.clear();
@@ -162,8 +164,20 @@ void procinfo_non_boinc(PROCINFO& procinfo, PROC_MAP& pm) {
162164
#endif
163165
}
164166

165-
// get CPU time of BOINC-related processes, low-priority processes,
166-
// and (if we're using Vbox) the Vbox daemon.
167+
// get CPU time of things we don't want to count as non-BOINC-related
168+
// - BOINC apps
169+
// - low-priority processes
170+
// - (if Vbox apps are running) the Vbox daemon
171+
// - Windows: WSL daemon ('vmmem')
172+
// - Linux/Mac:
173+
// we don't account Docker/podman CPU time here,
174+
// since we don't know what the processes are.
175+
// Instead we do it in the client (by looking at ACTIVE_TASKS)
176+
//
177+
// processes named 'podman'
178+
//
179+
// This is subtracted from total CPU time to get
180+
// the 'non-BOINC CPU time' used in computing preferences
167181
//
168182
double boinc_related_cpu_time(PROC_MAP& pm, bool vbox_app_running) {
169183
double sum = 0;
@@ -180,8 +194,11 @@ double boinc_related_cpu_time(PROC_MAP& pm, bool vbox_app_running) {
180194
// if a VBox app is running,
181195
// count VBox processes as BOINC-related
182196
// e.g. VBoxHeadless.exe and VBoxSVC.exe on Win
197+
#ifdef _WIN32
198+
|| strstr(p.command, "vmmem")
199+
#endif
183200
) {
184-
sum += p.user_time;
201+
sum += (p.user_time + p.kernel_time);
185202
}
186203
}
187204
return sum;

lib/procinfo_unix.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ struct PROC_STAT {
109109
int parse(char*);
110110
};
111111

112+
// parse a /proc/<pid>/stat files (1 line)
113+
// see https://man7.org/linux/man-pages/man5/proc_pid_stat.5.html
114+
//
112115
int PROC_STAT::parse(char* buf) {
113116
int n = sscanf(buf,
114117
"%d (%[^)]) %c %d %d %d %d %d "

0 commit comments

Comments
 (0)