mirror of https://github.com/BOINC/boinc.git
- client: fix bugs with scheduling app that use coprocessors
- client: factor out "schedule_if_possible()" logic from two places in schedule_cpus() svn path=/trunk/boinc/; revision=15096
This commit is contained in:
parent
226a78443d
commit
3abc3de32f
|
@ -2941,8 +2941,8 @@ Eric K April 1 2008
|
|||
- Added checks for functions strdup(), strdupa(),
|
||||
daemon(), stat64(), strcasestr()
|
||||
- Fixed problems with kc_mysql.m4 and wxWidgets.m4 returning
|
||||
invalid CFLAGS and LIBS flags.
|
||||
- Fixed incorrect order of pthread flag checking on solaris.
|
||||
invalid CFLAGS and LIBS flags.
|
||||
- Fixed incorrect order of pthread flag checking on solaris.
|
||||
- New files: lib/unix_util.[Ch]. Currently contains implementation of
|
||||
daemon() for systems that lack it.
|
||||
- Access to binary files in /proc was failing on some systems when compiled
|
||||
|
@ -3097,7 +3097,7 @@ Eric K April 4 2008
|
|||
client/
|
||||
scripts/
|
||||
Makefile.am
|
||||
boinc-client.in
|
||||
boinc-client.in
|
||||
|
||||
Rom April 4 2008
|
||||
- WINSETUP: Fix the bug during uninstall where the data files were not
|
||||
|
@ -3218,16 +3218,16 @@ Eric K April 14 2008
|
|||
- Does not presume the existence of "pidof" or "runuser".
|
||||
- If started with an old style Bourne shell, will try to restart
|
||||
in bash, zsh or ksh.
|
||||
- Starts with no parameters by default.
|
||||
- Logs stdout and stderr to /var/log/boinc_client.log and
|
||||
- Starts with no parameters by default.
|
||||
- Logs stdout and stderr to /var/log/boinc_client.log and
|
||||
/var/log/boinc_client_err.log by default.
|
||||
- With appropriate "boinc-client.conf", the script can be run by
|
||||
a non-root user.
|
||||
- More changes are likely to be required.
|
||||
- With appropriate "boinc-client.conf", the script can be run by
|
||||
a non-root user.
|
||||
- More changes are likely to be required.
|
||||
client/
|
||||
scripts/
|
||||
boinc-client.in
|
||||
Makefile.am
|
||||
Makefile.am
|
||||
|
||||
David April 14 2008
|
||||
- client: improved user idle checking on Linux (from Frank Thomas)
|
||||
|
@ -3274,7 +3274,7 @@ Charlie April 15 2008
|
|||
|
||||
Charlie April 16 2008
|
||||
- Fix is_file() and is_dir() to compile properly on Windows by using
|
||||
the actual expressions instead of the macros which aren't defined.
|
||||
the actual expressions instead of the macros which aren't defined.
|
||||
|
||||
lib/
|
||||
filesys.C
|
||||
|
@ -3381,3 +3381,11 @@ Rom April 25 2008
|
|||
|
||||
clientgui/
|
||||
BOINCClientManager.cpp
|
||||
|
||||
David April 25 2008
|
||||
- client: fix bugs with scheduling app that use coprocessors
|
||||
- client: factor out "schedule_if_possible()" logic from
|
||||
two places in schedule_cpus()
|
||||
|
||||
client/
|
||||
cpu_sched.C
|
||||
|
|
|
@ -81,6 +81,12 @@ bool CLIENT_STATE::sufficient_coprocs(APP_VERSION& av) {
|
|||
return false;
|
||||
}
|
||||
if (cp2->used + cp->count > cp2->count) {
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[cpu_sched_debug] insufficient coproc %s (%d + %d > %d)",
|
||||
cp2->name, cp2->used, cp->count, cp2->count
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +98,12 @@ void CLIENT_STATE::reserve_coprocs(APP_VERSION& av) {
|
|||
COPROC* cp = av.coprocs.coprocs[i];
|
||||
COPROC* cp2 = coprocs.lookup(cp->name);
|
||||
if (!cp2) continue;
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[cpu_sched_debug] reserving %d of coproc %s",
|
||||
cp->count, cp2->name
|
||||
);
|
||||
}
|
||||
cp2->used += cp->count;
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +113,12 @@ void CLIENT_STATE::free_coprocs(APP_VERSION& av) {
|
|||
COPROC* cp = av.coprocs.coprocs[i];
|
||||
COPROC* cp2 = coprocs.lookup(cp->name);
|
||||
if (!cp2) continue;
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[cpu_sched_debug] freeing %d of coproc %s",
|
||||
cp->count, cp2->name
|
||||
);
|
||||
}
|
||||
cp2->used -= cp->count;
|
||||
}
|
||||
}
|
||||
|
@ -501,14 +519,64 @@ void CLIENT_STATE::print_deadline_misses() {
|
|||
}
|
||||
}
|
||||
|
||||
static bool schedule_if_possible(
|
||||
RESULT* rp, double& ncpus_used, double& ram_left, double rrs, double expected_payoff
|
||||
) {
|
||||
ACTIVE_TASK* atp;
|
||||
|
||||
atp = gstate.lookup_active_task_by_result(rp);
|
||||
if (!atp || atp->task_state() == PROCESS_UNINITIALIZED) {
|
||||
if (!gstate.sufficient_coprocs(*rp->avp)) {
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"[cpu_sched_debug] insufficient coprocessors for %s", rp->name
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (atp) {
|
||||
// see if it fits in available RAM
|
||||
//
|
||||
if (atp->procinfo.working_set_size_smoothed > ram_left) {
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"[cpu_sched_debug] %s misses deadline but too large: %.2fMB",
|
||||
rp->name, atp->procinfo.working_set_size_smoothed/MEGA
|
||||
);
|
||||
}
|
||||
atp->too_large = true;
|
||||
return false;
|
||||
}
|
||||
atp->too_large = false;
|
||||
|
||||
if (gstate.retry_shmem_time > gstate.now) {
|
||||
if (atp->app_client_shm.shm == NULL) {
|
||||
atp->needs_shmem = true;
|
||||
return false;
|
||||
}
|
||||
atp->needs_shmem = false;
|
||||
}
|
||||
ram_left -= atp->procinfo.working_set_size_smoothed;
|
||||
}
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"[cpu_sched_debug] scheduling %s",
|
||||
rp->name
|
||||
);
|
||||
}
|
||||
ncpus_used += rp->avp->avg_ncpus;
|
||||
rp->project->anticipated_debt -= (rp->project->resource_share / rrs) * expected_payoff;
|
||||
return true;
|
||||
}
|
||||
|
||||
// CPU scheduler - decide which results to run.
|
||||
// output: sets ordered_scheduled_result.
|
||||
//
|
||||
void CLIENT_STATE::schedule_cpus() {
|
||||
RESULT* rp;
|
||||
PROJECT* p;
|
||||
ACTIVE_TASK* atp;
|
||||
double expected_pay_off;
|
||||
double expected_payoff;
|
||||
unsigned int i;
|
||||
double rrs = runnable_resource_share();
|
||||
double ncpus_used;
|
||||
|
@ -543,7 +611,7 @@ void CLIENT_STATE::schedule_cpus() {
|
|||
active_tasks.active_tasks[i]->too_large = false;
|
||||
}
|
||||
|
||||
expected_pay_off = global_prefs.cpu_scheduling_period();
|
||||
expected_payoff = global_prefs.cpu_scheduling_period();
|
||||
ordered_scheduled_results.clear();
|
||||
double ram_left = available_ram();
|
||||
|
||||
|
@ -558,45 +626,10 @@ void CLIENT_STATE::schedule_cpus() {
|
|||
if (!rp) break;
|
||||
rp->already_selected = true;
|
||||
|
||||
if (!sufficient_coprocs(*rp->avp)) continue;
|
||||
if (!schedule_if_possible(rp, ncpus_used, ram_left, rrs, expected_payoff)) continue;
|
||||
|
||||
atp = lookup_active_task_by_result(rp);
|
||||
if (atp) {
|
||||
// see if it fits in available RAM
|
||||
//
|
||||
if (atp->procinfo.working_set_size_smoothed > ram_left) {
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"[cpu_sched_debug] %s misses deadline but too large: %.2fMB",
|
||||
rp->name, atp->procinfo.working_set_size_smoothed/MEGA
|
||||
);
|
||||
}
|
||||
atp->too_large = true;
|
||||
continue;
|
||||
}
|
||||
atp->too_large = false;
|
||||
|
||||
// TODO: merge this chunk of code with its clone
|
||||
if (gstate.retry_shmem_time > gstate.now) {
|
||||
if (atp->app_client_shm.shm == NULL) {
|
||||
atp->needs_shmem = true;
|
||||
continue;
|
||||
}
|
||||
atp->needs_shmem = false;
|
||||
}
|
||||
ram_left -= atp->procinfo.working_set_size_smoothed;
|
||||
}
|
||||
ncpus_used += rp->avp->avg_ncpus;
|
||||
|
||||
rp->project->anticipated_debt -= (rp->project->resource_share / rrs) * expected_pay_off;
|
||||
rp->project->deadlines_missed--;
|
||||
rp->edf_scheduled = true;
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(rp->project, MSG_INFO,
|
||||
"[cpu_sched_debug] scheduling (deadline) %s",
|
||||
rp->name
|
||||
);
|
||||
}
|
||||
ordered_scheduled_results.push_back(rp);
|
||||
}
|
||||
#ifdef SIM
|
||||
|
@ -609,39 +642,7 @@ void CLIENT_STATE::schedule_cpus() {
|
|||
assign_results_to_projects();
|
||||
rp = largest_debt_project_best_result();
|
||||
if (!rp) break;
|
||||
if (!sufficient_coprocs(*rp->avp)) continue;
|
||||
atp = lookup_active_task_by_result(rp);
|
||||
if (atp) {
|
||||
if (atp->procinfo.working_set_size_smoothed > ram_left) {
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[cpu_sched_debug] %s too large: %.2fMB",
|
||||
rp->name, atp->procinfo.working_set_size_smoothed/MEGA
|
||||
);
|
||||
}
|
||||
atp->too_large = true;
|
||||
continue;
|
||||
}
|
||||
atp->too_large = false;
|
||||
|
||||
// don't select if it would need a new shared-mem seg
|
||||
// and we're out of them
|
||||
//
|
||||
if (gstate.retry_shmem_time > gstate.now) {
|
||||
if (atp->app_client_shm.shm == NULL) {
|
||||
atp->needs_shmem = true;
|
||||
continue;
|
||||
}
|
||||
atp->needs_shmem = false;
|
||||
}
|
||||
ram_left -= atp->procinfo.working_set_size_smoothed;
|
||||
}
|
||||
ncpus_used += rp->avp->avg_ncpus;
|
||||
double xx = (rp->project->resource_share / rrs) * expected_pay_off;
|
||||
rp->project->anticipated_debt -= xx;
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO, "[cpu_sched_debug] scheduling (regular) %s", rp->name);
|
||||
}
|
||||
if (!schedule_if_possible(rp, ncpus_used, ram_left, rrs, expected_payoff)) continue;
|
||||
ordered_scheduled_results.push_back(rp);
|
||||
}
|
||||
|
||||
|
@ -981,8 +982,8 @@ bool CLIENT_STATE::enforce_schedule() {
|
|||
case CPU_SCHED_SCHEDULED:
|
||||
switch (atp->task_state()) {
|
||||
case PROCESS_UNINITIALIZED:
|
||||
case PROCESS_SUSPENDED:
|
||||
if (!sufficient_coprocs(*atp->app_version)) continue;
|
||||
case PROCESS_SUSPENDED:
|
||||
action = true;
|
||||
retval = atp->resume_or_start(
|
||||
atp->scheduler_state == CPU_SCHED_UNINITIALIZED
|
||||
|
|
Loading…
Reference in New Issue