boinc/sched/sched_util.cpp

139 lines
3.9 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/>.
// utility functions for BOINC server programs
#include "config.h"
#include <ctime>
#include "boinc_db.h"
#include "sched_util.h"
void compute_avg_turnaround(HOST& host, double turnaround) {
double new_avg;
if (host.avg_turnaround == 0) {
new_avg = turnaround;
} else {
new_avg = .7*host.avg_turnaround + .3*turnaround;
}
host.avg_turnaround = new_avg;
}
int PERF_INFO::get_from_db() {
int retval;
long n;
DB_HOST host;
host_fpops_mean = 2.2e9;
host_fpops_stddev = .7e9;
host_fpops_50_percentile = 3.3e9;
host_fpops_95_percentile = 3.3e9;
retval = host.count(n);
if (retval) return retval;
if (n < 10) return 0;
retval = host.fpops_mean(host_fpops_mean);
retval = host.fpops_stddev(host_fpops_stddev);
retval = host.fpops_percentile(50, host_fpops_50_percentile);
retval = host.fpops_percentile(95, host_fpops_95_percentile);
return 0;
}
int count_results(char* query, long& n) {
DB_RESULT result;
return result.count(n, query);
}
int count_workunits(long& n, const char* query) {
DB_WORKUNIT workunit;
return workunit.count(n, query);
}
int count_unsent_results(long& n, DB_ID_TYPE appid, int size_class) {
char query[1024], buf[256];
sprintf(query, "where server_state<=%d", RESULT_SERVER_STATE_UNSENT);
if (appid) {
sprintf(buf, " and appid=%lu", appid);
strcat(query, buf);
}
if (size_class >= 0) {
sprintf(buf, " and size_class=%d", size_class);
strcat(query, buf);
}
return count_results(query, n);
}
// Arrange that further results for this workunit
// will be sent only to the specific host(s).
// This could be used, for example, so that late workunits
// are sent only to cloud or cluster resources
//
static int restrict_wu(WORKUNIT& _wu, DB_ID_TYPE id, int assign_type) {
DB_RESULT result;
DB_ASSIGNMENT asg;
DB_WORKUNIT wu;
wu = _wu;
char buf[256];
int retval;
// mark unsent results as DIDNT_NEED
//
sprintf(buf, "where workunitid=%lu and server_state=%d",
wu.id, RESULT_SERVER_STATE_UNSENT
);
while (!result.enumerate(buf)) {
char buf2[256];
sprintf(buf2, "server_state=%d, outcome=%d",
RESULT_SERVER_STATE_OVER,
RESULT_OUTCOME_DIDNT_NEED
);
result.update_field(buf2);
}
// mark the WU as TRANSITION_NO_NEW_RESULTS
//
sprintf(buf, "transitioner_flags=%d", TRANSITION_NO_NEW_RESULTS);
retval = wu.update_field(buf);
if (retval) return retval;
// create an assignment record
//
asg.clear();
asg.create_time = time(0);
asg.target_id = id;
asg.target_type = assign_type;
asg.multi = 0;
asg.workunitid = wu.id;
retval = asg.insert();
return retval;
}
int restrict_wu_to_user(WORKUNIT& wu, DB_ID_TYPE userid) {
return restrict_wu(wu, userid, ASSIGN_USER);
}
int restrict_wu_to_host(WORKUNIT& wu, DB_ID_TYPE hostid) {
return restrict_wu(wu, hostid, ASSIGN_HOST);
}
// return the min transition time.
// This lets you check if the transitioner is backed up.
//
int min_transition_time(double& x) {
return boinc_db.get_double("select min(transition_time) from workunit", x);
}