// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2012 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 . #ifndef _RESULT_ #define _RESULT_ #include "project.h" struct RESULT { char name[256]; char wu_name[256]; double received_time; // when we got this from server double report_deadline; int version_num; // identifies the app used char plan_class[64]; char platform[256]; APP_VERSION* avp; std::vector output_files; bool ready_to_report; // we're ready to report this result to the server; // either computation is done and all the files have been uploaded // or there was an error double completed_time; // time when ready_to_report was set bool got_server_ack; // we've received the ack for this result from the server double final_cpu_time; double final_elapsed_time; double final_peak_working_set_size; double final_peak_swap_size; double final_peak_disk_usage; double final_bytes_sent; double final_bytes_received; #ifdef SIM double peak_flop_count; double sim_flops_left; #endif // the following are nonzero if reported by app double fpops_per_cpu_sec; double fpops_cumulative; double intops_per_cpu_sec; double intops_cumulative; int _state; // state of this result: see lib/result_state.h inline int state() { return _state; } inline void set_ready_to_report() { ready_to_report = true; } void set_state(int, const char*); int exit_status; // return value from the application std::string stderr_out; // the concatenation of: // // - if report_result_error() is called for this result: // x // x // x // - if called in FILES_DOWNLOADED state: // x // - if called in NEW state: // x for each failed download // - if called in COMPUTE_DONE state: // x for each failed upload // // - X, where X is the app's stderr output bool suspended_via_gui; bool coproc_missing; // a coproc needed by this job is missing // (e.g. because user removed their GPU board). bool report_immediately; bool not_started; // temp for CPU sched std::string name_md5; // see sort_results(); int index; // index in results vector APP* app; WORKUNIT* wup; PROJECT* project; RESULT(){} ~RESULT(){} void clear(); int parse_server(XML_PARSER&); int parse_state(XML_PARSER&); int parse_name(XML_PARSER&, const char* end_tag); int write(MIOFILE&, bool to_server); int write_gui(MIOFILE&); bool is_upload_done(); // files uploaded? void clear_uploaded_flags(); FILE_REF* lookup_file(FILE_INFO*); FILE_INFO* lookup_file_logical(const char*); void abort_inactive(int); // abort the result if it hasn't started computing yet // Called only for results with no active task // (otherwise you need to abort the active task) void append_log_record(); // stuff related to CPU scheduling bool is_not_started(); double estimated_runtime(); double estimated_runtime_uncorrected(); double estimated_runtime_remaining(); inline double estimated_flops_remaining() { #ifdef SIM return sim_flops_left; #else return estimated_runtime_remaining()*avp->flops; #endif } inline bool computing_done() { if (state() >= RESULT_COMPUTE_ERROR) return true; if (ready_to_report) return true; return false; } bool runnable(); // downloaded, not finished, not suspended, project not suspended bool nearly_runnable(); // downloading or downloaded, // not finished, suspended, project not suspended bool downloading(); // downloading, not downloaded, not suspended, project not suspended bool some_download_stalled(); // some input or app file is downloading, and backed off // i.e. it may be a long time before we can run this result inline bool uses_coprocs() { return (avp->gpu_usage.rsc_type != 0); } inline bool uses_gpu() { int rt = avp->gpu_usage.rsc_type; if (!rt) return false; if (coprocs.coprocs[rt].non_gpu) return false; return true; } inline int resource_type() { return avp->gpu_usage.rsc_type; } inline bool non_cpu_intensive() { if (project->non_cpu_intensive) return true; if (app->non_cpu_intensive) return true; return false; } inline bool dont_throttle() { if (non_cpu_intensive()) return true; if (avp->dont_throttle) return true; return false; } // temporaries used in CLIENT_STATE::rr_simulation(): double rrsim_flops_left; double rrsim_finish_delay; double rrsim_flops; bool rrsim_done; bool already_selected; // used to keep cpu scheduler from scheduling a result twice // transient; used only within schedule_cpus() // also used in round-robin simulation double computation_deadline(); // report deadline - prefs.work_buf_min - time slice bool rr_sim_misses_deadline; // temporaries used in enforce_schedule(): bool unfinished_time_slice; int seqno; bool edf_scheduled; // temporary used to tell GUI that this result is deadline-scheduled int coproc_indices[MAX_COPROCS_PER_JOB]; // keep track of coprocessor reservations char resources[256]; // textual description of resources used double schedule_backoff; // don't try to schedule until this time // (because the app called boinc_temporary_exit()) char schedule_backoff_reason[256]; }; inline bool max_concurrent_exceeded(RESULT* rp) { APP* app = rp->app; if (app->max_concurrent) { if (app->n_concurrent >= app->max_concurrent) { return true; } } PROJECT* p = rp->project; if (p->app_configs.project_max_concurrent) { if (p->n_concurrent >= p->app_configs.project_max_concurrent) { return true; } } return false; } inline void max_concurrent_inc(RESULT* rp) { rp->app->n_concurrent++; rp->project->n_concurrent++; } // a completed result, for which the RESULT record no longer exists. // We keep an in-memory log of these. // Keep this consistent with lib/gui_rpc_client.h // struct OLD_RESULT { char project_url[256]; char result_name[256]; char app_name[256]; int exit_status; double elapsed_time; double cpu_time; double completed_time; double create_time; // when this record was created }; extern std::deque old_results; void add_old_result(RESULT&); extern void print_old_results(MIOFILE&); #endif