boinc/sched/sched_nci.cpp

191 lines
5.7 KiB
C++

// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2014 University of California
//
// 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.
//
// BOINC is distributed in the hope that it will be useful,
// 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.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// try to send a job for the given app; used for non-compute-intensive apps
// Logic for sending non-compute-intensive (NCI) jobs
#include "sched_check.h"
#include "sched_main.h"
#include "sched_msgs.h"
#include "sched_send.h"
#include "sched_version.h"
#include "sched_nci.h"
static bool can_send_nci(
WU_RESULT& wu_result,
WORKUNIT& wu,
BEST_APP_VERSION* &bavp,
APP* app
) {
bavp = get_app_version(wu, true, false);
if (!bavp) {
if (config.debug_send_job) {
log_messages.printf(MSG_NORMAL,
"[send_job] [WU#%u] No app version for NCI job; skipping\n",
wu.id
);
}
return false;
}
int retval = wu_is_infeasible_fast(
wu,
wu_result.res_server_state, wu_result.res_priority,
wu_result.res_report_deadline,
*app, *bavp
);
if (retval) {
if (config.debug_send_job) {
log_messages.printf(MSG_NORMAL,
"[send_job] [WU#%u] wu_is_infeasible_fast() failed for NCI job; skipping\n",
wu.id
);
}
return false;
}
return true;
}
static int send_job_for_app(APP& app) {
BEST_APP_VERSION* bavp;
SCHED_DB_RESULT result;
lock_sema();
for (int i=0; i<ssp->max_wu_results; i++) {
WU_RESULT& wu_result = ssp->wu_results[i];
if (wu_result.state != WR_STATE_PRESENT && wu_result.state != g_pid) {
continue;
}
WORKUNIT wu = wu_result.workunit;
if (wu.appid != app.id) continue;
if (!can_send_nci(wu_result, wu, bavp, &app)) {
// All jobs for a given NCI app are identical.
// If we can't send one, we can't send any.
//
unlock_sema();
log_messages.printf(MSG_NORMAL,
"can_send_nci() failed for NCI job\n"
);
return -1;
}
wu_result.state = g_pid;
unlock_sema();
result.id = wu_result.resultid;
wu_result.state = WR_STATE_EMPTY;
if (result_still_sendable(result, wu)) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL,
"Sending non-CPU-intensive job: %s\n", wu.name
);
}
add_result_to_reply(result, wu, bavp, false);
return 0;
}
log_messages.printf(MSG_NORMAL,
"NCI job was not still sendable\n"
);
lock_sema();
}
log_messages.printf(MSG_NORMAL,
"no sendable NCI jobs for %s\n", app.user_friendly_name
);
unlock_sema();
return 1;
}
// try to send jobs for non-CPU-intensive (NCI) apps
// for which the host doesn't have a job in progress
//
int send_nci() {
int retval;
vector<APP> nci_apps;
char buf[1024];
if (config.debug_send) {
log_messages.printf(MSG_NORMAL, "checking for NCI jobs\n");
}
// make a vector of NCI apps
//
for (int i=0; i<ssp->napps; i++) {
if (!ssp->apps[i].non_cpu_intensive) continue;
APP app = ssp->apps[i];
app.have_job = false;
nci_apps.push_back(app);
}
// scan through the list of in-progress jobs,
// flagging the associated apps as having jobs
//
for (unsigned int i=0; i<g_request->other_results.size(); i++) {
DB_RESULT r;
OTHER_RESULT &ores = g_request->other_results[i];
sprintf(buf, "where name='%s'", ores.name);
retval = r.lookup(buf);
if (retval) {
log_messages.printf(MSG_NORMAL, "No such result: %s\n", ores.name);
continue;
}
for (unsigned int j=0; j<nci_apps.size(); j++) {
APP& app = nci_apps[j];
if (app.id == r.appid) {
app.have_job = true;
break;
}
}
}
// For each NCI app w/o a job, try to send one
//
for (unsigned int i=0; i<nci_apps.size(); i++) {
APP& app = nci_apps[i];
if (app.have_job) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL,
"Already have job for %s\n", app.name
);
}
continue;
}
if (app.beta && !g_wreq->allow_beta_work) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL, "%s is beta\n", app.name);
}
continue;
}
if (app_not_selected(app.id)) {
if (!g_wreq->allow_non_preferred_apps) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL,
"%s is not selected\n", app.name
);
}
continue;
}
}
retval = send_job_for_app(app);
if (retval) {
log_messages.printf(MSG_NORMAL,
"failed to send job for NCI app %s\n", app.user_friendly_name
);
}
}
return 0;
}