// 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.cpp: 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 "example_app". // - 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 #include #include #include #include "boinc_db.h" #include "error_numbers.h" #include "backend_lib.h" #include "parse.h" #include "util.h" #include "svn_version.h" #include "sched_config.h" #include "sched_util.h" #include "sched_msgs.h" #include "str_util.h" #define CUSHION 10 // maintain at least this many unsent results #define REPLICATION_FACTOR 1 const char* app_name = "example_app"; const char* in_template_file = "example_app_in.xml"; const char* out_template_file = "example_app_out.xml"; 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[256]; 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; 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, 0); if (retval) { log_messages.printf(MSG_CRITICAL, "count_unsent_jobs() failed: %s\n", boincerror(retval) ); exit(retval); } if (n > CUSHION) { sleep(10); } else { int njobs = (CUSHION-n)/REPLICATION_FACTOR; log_messages.printf(MSG_DEBUG, "Making %d jobs\n", njobs ); for (int i=0; i