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/>.
|
|
|
|
|
2017-04-08 06:54:49 +00:00
|
|
|
#ifndef BOINC_SCHED_LIMIT_H
|
|
|
|
#define BOINC_SCHED_LIMIT_H
|
2010-06-01 23:41:07 +00:00
|
|
|
|
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;
|
|
|
|
|
2016-07-30 07:07:33 +00:00
|
|
|
// represents a limit on # of jobs in progress for a given processor type
|
|
|
|
//
|
2010-05-24 23:14:48 +00:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2016-07-30 07:07:33 +00:00
|
|
|
// represents limits for a given app (or overall, if app_name is empty)
|
|
|
|
//
|
2010-05-24 23:14:48 +00:00
|
|
|
struct JOB_LIMIT {
|
|
|
|
char app_name[256];
|
|
|
|
RSC_JOB_LIMIT total;
|
2014-03-08 19:17:16 +00:00
|
|
|
RSC_JOB_LIMIT proc_type_limits[NPROC_TYPES];
|
2010-05-24 23:14:48 +00:00
|
|
|
|
|
|
|
int parse(XML_PARSER&, const char* end_tag);
|
|
|
|
|
2014-03-08 19:17:16 +00:00
|
|
|
inline void reset(int ninstances[]) {
|
2010-05-24 23:14:48 +00:00
|
|
|
total.reset(1);
|
2014-03-08 19:17:16 +00:00
|
|
|
for (int i=0; i<NPROC_TYPES; i++) {
|
|
|
|
proc_type_limits[i].reset(ninstances[i]);
|
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
|
2014-03-12 22:31:12 +00:00
|
|
|
inline bool exceeded(int proc_type) {
|
2010-05-24 23:14:48 +00:00
|
|
|
if (total.exceeded()) return true;
|
2014-03-08 19:17:16 +00:00
|
|
|
if (proc_type_limits[proc_type].exceeded()) return true;
|
2010-05-24 23:14:48 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-12 22:31:12 +00:00
|
|
|
inline void register_job(int proc_type) {
|
2010-05-24 23:14:48 +00:00
|
|
|
total.register_job();
|
2014-03-08 19:17:16 +00:00
|
|
|
proc_type_limits[proc_type].register_job();
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
2010-09-13 21:20:30 +00:00
|
|
|
|
|
|
|
inline bool any_limit() {
|
2014-03-08 19:17:16 +00:00
|
|
|
if (total.any_limit()) return true;
|
|
|
|
for (int i=0; i<NPROC_TYPES; i++) {
|
|
|
|
if (proc_type_limits[i].any_limit()) return true;
|
|
|
|
}
|
|
|
|
return false;
|
2010-09-13 21:20:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_log();
|
2010-05-24 23:14:48 +00:00
|
|
|
};
|
|
|
|
|
2016-07-30 07:07:33 +00:00
|
|
|
// combined limits, overall and per app
|
|
|
|
//
|
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
|
|
|
|
//
|
2014-03-08 19:17:16 +00:00
|
|
|
inline void reset(int ninstances[]) {
|
|
|
|
project_limits.reset(ninstances);
|
2010-05-24 23:14:48 +00:00
|
|
|
for (unsigned int i=0; i<app_limits.size(); i++) {
|
2014-03-08 19:17:16 +00:00
|
|
|
app_limits[i].reset(ninstances);
|
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;
|
|
|
|
}
|
|
|
|
|
2014-03-12 22:31:12 +00:00
|
|
|
inline bool exceeded(APP* app, int proc_type) {
|
|
|
|
if (project_limits.exceeded(proc_type)) return true;
|
2010-06-01 23:41:07 +00:00
|
|
|
if (app) {
|
|
|
|
JOB_LIMIT* jlp = lookup_app(app->name);
|
|
|
|
if (jlp) {
|
2014-03-12 22:31:12 +00:00
|
|
|
if (jlp->exceeded(proc_type)) return true;
|
2010-06-01 23:41:07 +00:00
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-12 22:31:12 +00:00
|
|
|
inline void register_job(APP* app, int proc_type) {
|
|
|
|
project_limits.register_job(proc_type);
|
2010-06-01 23:41:07 +00:00
|
|
|
if (app) {
|
|
|
|
JOB_LIMIT* jlp = lookup_app(app->name);
|
|
|
|
if (jlp) {
|
2014-03-12 22:31:12 +00:00
|
|
|
jlp->register_job(proc_type);
|
2010-06-01 23:41:07 +00:00
|
|
|
}
|
2010-05-24 23:14:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2010-06-01 23:41:07 +00:00
|
|
|
|
|
|
|
#endif
|