mirror of https://github.com/BOINC/boinc.git
180 lines
5.1 KiB
C
180 lines
5.1 KiB
C
// Berkeley Open Infrastructure for Network Computing
|
|
// http://boinc.berkeley.edu
|
|
// Copyright (C) 2007 University of California
|
|
//
|
|
// This 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 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This software 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.
|
|
//
|
|
// To view the GNU Lesser General Public License visit
|
|
// http://www.gnu.org/copyleft/lesser.html
|
|
// or write to the Free Software Foundation, Inc.,
|
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
// sample_work_generator.C: an example BOINC work generator.
|
|
// This work generator has the following properties
|
|
// (you may need to change some or all of these):
|
|
//
|
|
// - Runs as a daemon, and creates an unbounded supply of work.
|
|
// It attempts to maintain a "cushion" of 100 unsent job instances.
|
|
// (your app may not work this way; e.g. you might create work in batches)
|
|
// - Creates work for the application "uppercase".
|
|
// - Creates a new input file for each job;
|
|
// the file (and the workunit names) contain a timestamp
|
|
// and sequence number, so that they're unique.
|
|
|
|
#include "boinc_db.h"
|
|
#include "error_numbers.h"
|
|
#include "backend_lib.h"
|
|
#include "parse.h"
|
|
#include "util.h"
|
|
|
|
#include "sched_config.h"
|
|
#include "sched_util.h"
|
|
#include "sched_msgs.h"
|
|
|
|
#define CUSHION 100
|
|
// maintain at least this many unsent results
|
|
#define REPLICATION_FACTOR 2
|
|
|
|
// globals
|
|
//
|
|
char* wu_template;
|
|
DB_APP app;
|
|
int start_time;
|
|
int seqno;
|
|
SCHED_CONFIG config;
|
|
|
|
// create one new job
|
|
//
|
|
int make_job() {
|
|
DB_WORKUNIT wu;
|
|
char name[256], path[256];
|
|
const char* infiles[1];
|
|
int retval;
|
|
|
|
// make a unique name (for the job and its input file)
|
|
//
|
|
sprintf(name, "uc_%d_%d", start_time, seqno++);
|
|
|
|
// Create the input file.
|
|
// Put it at the right place in the download dir hierarchy
|
|
//
|
|
retval = config.download_path(name, path);
|
|
if (retval) return retval;
|
|
FILE* f = fopen(path, "w");
|
|
if (!f) return ERR_FOPEN;
|
|
fprintf(f, "This is the input file for job %s", name);
|
|
fclose(f);
|
|
|
|
// Fill in the job parameters
|
|
//
|
|
wu.clear();
|
|
wu.appid = app.id;
|
|
strcpy(wu.name, name);
|
|
wu.rsc_fpops_est = 1e12;
|
|
wu.rsc_fpops_bound = 1e14;
|
|
wu.rsc_memory_bound = 1e8;
|
|
wu.rsc_disk_bound = 1e8;
|
|
wu.delay_bound = 86400;
|
|
wu.min_quorum = REPLICATION_FACTOR;
|
|
wu.target_nresults = REPLICATION_FACTOR;
|
|
wu.max_error_results = REPLICATION_FACTOR*4;
|
|
wu.max_total_results = REPLICATION_FACTOR*8;
|
|
wu.max_success_results = REPLICATION_FACTOR*4;
|
|
infiles[0] = name;
|
|
|
|
// Register the job with BOINC
|
|
//
|
|
return create_work(
|
|
wu,
|
|
wu_template,
|
|
"templates/uc_result",
|
|
"../templates/uc_result",
|
|
infiles,
|
|
1,
|
|
config
|
|
);
|
|
}
|
|
|
|
void main_loop() {
|
|
int retval;
|
|
|
|
while (1) {
|
|
check_stop_daemons();
|
|
int n;
|
|
retval = count_unsent_results(n, 0);
|
|
if (n > CUSHION) {
|
|
sleep(60);
|
|
} else {
|
|
int njobs = (CUSHION-n)/REPLICATION_FACTOR;
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
|
|
"Making %d jobs\n", njobs
|
|
);
|
|
for (int i=0; i<njobs; i++) {
|
|
retval = make_job();
|
|
if (retval) {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
|
|
"can't make job: %d\n", retval
|
|
);
|
|
exit(retval);
|
|
}
|
|
}
|
|
// Now sleep for a few seconds to let the transitioner
|
|
// create instances for the jobs we just created.
|
|
// Otherwise we could end up creating an excess of jobs.
|
|
sleep(5);
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
int i, retval;
|
|
|
|
for (i=1; i<argc; i++) {
|
|
if (!strcmp(argv[i], "-d")) {
|
|
log_messages.set_debug_level(atoi(argv[++i]));
|
|
} else {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
|
|
"bad cmdline arg: %s", argv[i]
|
|
);
|
|
}
|
|
}
|
|
|
|
if (config.parse_file("..")) {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
|
|
"can't read config file\n"
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
retval = boinc_db.open(
|
|
config.db_name, config.db_host, config.db_user, config.db_passwd
|
|
);
|
|
if (retval) {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't open db\n");
|
|
exit(1);
|
|
}
|
|
if (app.lookup("where name='uppercase'")) {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't find app\n");
|
|
exit(1);
|
|
}
|
|
if (read_file_malloc("../templates/uc_wu", wu_template)) {
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't read WU template\n");
|
|
exit(1);
|
|
}
|
|
|
|
start_time = time(0);
|
|
seqno = 0;
|
|
|
|
log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "Starting\n");
|
|
|
|
main_loop();
|
|
}
|