2010-05-24 23:14:48 +00:00
|
|
|
// This file is part of BOINC.
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2010 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/>.
|
|
|
|
|
2010-06-01 23:41:07 +00:00
|
|
|
#ifndef _SCHED_LIMIT_
|
|
|
|
#define _SCHED_LIMIT_
|
|
|
|
|
2010-05-24 23:14:48 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "boinc_db.h"
|
|
|
|
|
|
|
|
#include "hostinfo.h"
|
|
|
|
#include "error_numbers.h"
|
|
|
|
#include "parse.h"
|
|
|
|
|
|
|
|
#include "sched_msgs.h"
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
struct RSC_JOB_LIMIT {
|
|
|
|
int base_limit; // 0 means no limit
|
|
|
|
int scaled_limit; // the actual limit
|
|
|
|
int njobs;
|
|
|
|
bool per_proc; // if true, scaled limit is limit*nprocs
|
|
|
|
|
|
|
|
int parse(XML_PARSER&, const char* end_tag);
|
|
|
|
|
|
|
|
inline void reset(int nprocs) {
|
|
|
|
njobs = 0;
|
|
|
|
if (per_proc) {
|
|
|
|
scaled_limit = base_limit*nprocs;
|
|
|
|
} else {
|
|
|
|
scaled_limit = base_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool exceeded() {
|
|
|
|
return (scaled_limit && njobs >= scaled_limit);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void register_job() {
|
|
|
|
njobs++;
|
|
|
|
}
|
2010-09-13 21:20:30 +00:00
|
|
|
|
|
|
|
inline bool any_limit() {
|
|
|
|
return (base_limit != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_log(const char*);
|
2011-04-04 22:15:04 +00:00
|
|
|
|
|
|
|
RSC_JOB_LIMIT() {
|
|
|
|
base_limit = 0;
|
|
|
|
scaled_limit = 0;
|
|
|
|
njobs = 0;
|
|
|
|
per_proc = false;
|
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct JOB_LIMIT {
|
|
|
|
char app_name[256];
|
|
|
|
RSC_JOB_LIMIT total;
|
|
|
|
RSC_JOB_LIMIT cpu;
|
|
|
|
RSC_JOB_LIMIT gpu;
|
|
|
|
|
|
|
|
int parse(XML_PARSER&, const char* end_tag);
|
|
|
|
|
2011-05-13 22:04:10 +00:00
|
|
|
inline void reset(int ncpus, int ngpus) {
|
2010-05-24 23:14:48 +00:00
|
|
|
total.reset(1);
|
2011-05-13 22:04:10 +00:00
|
|
|
cpu.reset(ncpus);
|
|
|
|
gpu.reset(ngpus);
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool exceeded(bool is_gpu) {
|
|
|
|
if (total.exceeded()) return true;
|
|
|
|
if (is_gpu) {
|
|
|
|
if (gpu.exceeded()) return true;
|
|
|
|
} else {
|
|
|
|
if (cpu.exceeded()) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void register_job(bool is_gpu) {
|
|
|
|
total.register_job();
|
|
|
|
if (is_gpu) {
|
|
|
|
gpu.register_job();
|
|
|
|
} else {
|
|
|
|
cpu.register_job();
|
|
|
|
}
|
|
|
|
}
|
2010-09-13 21:20:30 +00:00
|
|
|
|
|
|
|
inline bool any_limit() {
|
|
|
|
return total.any_limit() || cpu.any_limit() || gpu.any_limit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_log();
|
2010-05-24 23:14:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct JOB_LIMITS {
|
|
|
|
JOB_LIMIT project_limits; // project-wide limits
|
|
|
|
vector<JOB_LIMIT> app_limits; // per-app limits
|
|
|
|
|
|
|
|
int parse(XML_PARSER&, const char* end_tag);
|
2010-09-13 21:20:30 +00:00
|
|
|
void print_log();
|
2010-05-24 23:14:48 +00:00
|
|
|
|
|
|
|
// called at start of each request
|
|
|
|
//
|
2011-05-13 22:04:10 +00:00
|
|
|
inline void reset(int ncpus, int ngpus) {
|
|
|
|
project_limits.reset(ncpus, ngpus);
|
2010-05-24 23:14:48 +00:00
|
|
|
for (unsigned int i=0; i<app_limits.size(); i++) {
|
2011-05-13 22:04:10 +00:00
|
|
|
app_limits[i].reset(ncpus, ngpus);
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline JOB_LIMIT* lookup_app(char* name) {
|
|
|
|
for (unsigned int i=0; i<app_limits.size(); i++) {
|
|
|
|
JOB_LIMIT* jlp = &app_limits[i];
|
|
|
|
if (!strcmp(name, jlp->app_name)) {
|
|
|
|
return jlp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-01 23:41:07 +00:00
|
|
|
inline bool exceeded(APP* app, bool is_gpu) {
|
2010-05-24 23:14:48 +00:00
|
|
|
if (project_limits.exceeded(is_gpu)) return true;
|
2010-06-01 23:41:07 +00:00
|
|
|
if (app) {
|
|
|
|
JOB_LIMIT* jlp = lookup_app(app->name);
|
|
|
|
if (jlp) {
|
|
|
|
if (jlp->exceeded(is_gpu)) return true;
|
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-01 23:41:07 +00:00
|
|
|
inline void register_job(APP* app, bool is_gpu) {
|
2010-05-24 23:14:48 +00:00
|
|
|
project_limits.register_job(is_gpu);
|
2010-06-01 23:41:07 +00:00
|
|
|
if (app) {
|
|
|
|
JOB_LIMIT* jlp = lookup_app(app->name);
|
|
|
|
if (jlp) {
|
|
|
|
jlp->register_job(is_gpu);
|
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2010-06-01 23:41:07 +00:00
|
|
|
|
|
|
|
#endif
|