// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2008 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 . // sample_work_generator: example BOINC work generator. // // --app name app name (default example_app) // --in_template_file input template file (default example_app_in) // --out_template_file output template file (default example_app_out) // -d N log verbosity level (0..4) // --help show usage // --version show version // // - Runs as a daemon, and creates an unbounded supply of work. // It attempts to maintain a "cushion" of 100 unsent job instances // for the given app. // (your app may not work this way; e.g. you might create work in batches) // - Creates a new input file for each job; // the file (and the workunit names) contain a timestamp // and sequence number, so they're unique. // // This is an example - customize for your needs #include #include #include #include #include #include "backend_lib.h" #include "boinc_db.h" #include "error_numbers.h" #include "filesys.h" #include "parse.h" #include "str_replace.h" #include "str_util.h" #include "svn_version.h" #include "util.h" #include "sched_config.h" #include "sched_util.h" #include "sched_msgs.h" #define CUSHION 10 // maintain at least this many unsent results #define REPLICATION_FACTOR 1 // number of instances of each job const char* app_name = "example_app"; const char* in_template_file = "example_app_in"; const char* out_template_file = "example_app_out"; char* in_template; DB_APP app; int start_time; int seqno; // create one new job // int make_job() { DB_WORKUNIT wu; char name[256], path[MAXPATHLEN]; const char* infiles[1]; int retval; // make a unique name (for the job and its input file) // sprintf(name, "%s_%d_%d", app_name, 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; safe_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 // sprintf(path, "templates/%s", out_template_file); return create_work( wu, in_template, path, config.project_path(path), infiles, 1, config ); } void main_loop() { int retval; while (1) { check_stop_daemons(); int n; retval = count_unsent_results(n, app.id); if (retval) { log_messages.printf(MSG_CRITICAL, "count_unsent_jobs() failed: %s\n", boincerror(retval) ); exit(retval); } if (n > CUSHION) { daemon_sleep(10); } else { int njobs = (CUSHION-n)/REPLICATION_FACTOR; log_messages.printf(MSG_DEBUG, "Making %d jobs\n", njobs ); for (int i=0; i now) break; } } } } void usage(char *name) { fprintf(stderr, "This is an example BOINC work generator.\n" "This work generator has the following properties\n" "(you may need to change some or all of these):\n" " It attempts to maintain a \"cushion\" of 100 unsent job instances.\n" " (your app may not work this way; e.g. you might create work in batches)\n" "- Creates work for the application \"example_app\".\n" "- Creates a new input file for each job;\n" " the file (and the workunit names) contain a timestamp\n" " and sequence number, so that they're unique.\n\n" "Usage: %s [OPTION]...\n\n" "Options:\n" " [ --app X Application name (default: example_app)\n" " [ --in_template_file Input template (default: example_app_in)\n" " [ --out_template_file Output template (default: example_app_out)\n" " [ -d X ] Sets debug level to X.\n" " [ -h | --help ] Shows this help text.\n" " [ -v | --version ] Shows version information.\n", name ); } int main(int argc, char** argv) { int i, retval; char buf[256]; for (i=1; i