// 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 #include #include #include "edf_sim.h" using std::vector; //#define TEST //#define DEBUG #ifdef DEBUG #define INFO0 #define INFO1 #define INFO2 #else #define INFO0 // #define INFO1 // #define INFO2 // #endif // 0 shows initial workload and candidate decisions // 1 shows function calls results of sim: make/miss deadline // 2 shows every step of sim bool lessthan_deadline(const IP_RESULT& p1, const IP_RESULT& p2) { if (p1.computation_deadline < p2.computation_deadline) return true; return false; } // run an EDF simulation, marking which results will miss // their deadlines and when // void mark_edf_misses (int ncpus, vector& ip_results){ vector::iterator ipp_it; double booked_to[128]; int j; INFO1 fprintf(stderr, "mark_edf_misses\n"); // keeps track of when each cpu is next free // for (j=0; j r.computation_deadline) { r.misses_deadline = true; r.estimated_completion_time = booked_to[lowest_booked_cpu]; INFO1 fprintf(stderr, " %s misses_deadline; est completion %f\n", r.name, booked_to[lowest_booked_cpu] ); } else { r.misses_deadline = false; INFO1 fprintf(stderr, " %s makes deadline; est completion %f\n", r.name, booked_to[lowest_booked_cpu] ); // if result doesn't miss its deadline, // then the estimated_completion_time is of no use } } } // For each ip_result, computes computation_deadline from report_deadline, // and determines if the deadline would be missed by simulating edf // void init_ip_results( double work_buf_min, int ncpus, vector& ip_results ){ unsigned int i; INFO0 fprintf(stderr, "init_ip_results; work_buf_min %f ncpus %d:\n", work_buf_min, ncpus); for (i=0; i REQUEST_HANDLER_WORK_SEND::find_sendable_test_results ( vector test_results, int ncpus, vector ipp_results, double cpu_pessimism_factor // = 1 by default ) { //test results to send vector sendable_test_results; vector::iterator test_results_it; sort(test_results.begin(), test_results.end(), lessthan_deadline); // see if each test result can be added to the work queue without // causing deadline misses or deadline miss delays // for (test_results_it = test_results.begin(); test_results_it != test_results.end(); test_results_it++ ) { bool failed = result_cause_deadline_miss_or_delay( (*test_results_it).computation_deadline*cpu_pessimism_factor, (*test_results_it).cpu_time_remaining, ncpus, ipp_results ); if (!failed){ // add sendable result to work queue, copying by value, so that we // can evaluate what happens if we add more new results to the queue // ipp_results.push_back(*test_results_it); sendable_test_results.push_back (*test_results_it); } } return (sendable_test_results); } #endif // Return false if // 1) the candidate result X would cause another result Y to miss its deadline // (which Y would not have otherwise missed) // 2) X causes another result Y to miss its deadline by more than // it otherwise would have, or // 3) X would miss its deadline // bool check_candidate ( IP_RESULT& candidate, int ncpus, vector ip_results // passed by value (copy) ) { double booked_to[128]; // keeps track of when each cpu is free int j; INFO0 fprintf(stderr, "check_candidate %s: dl %f cpu %f\n", candidate.name, candidate.computation_deadline, candidate.cpu_time_remaining ); for (j=0; j computation_deadline AND // result would not have missed deadline to begin with // if (booked_to[lowest_booked_cpu] > r.computation_deadline && !r.misses_deadline ) { INFO0 fprintf(stderr, " cand. fails; %s now misses deadline: %f\n", r.name, booked_to[lowest_booked_cpu] ); return false; } // check a late result (i.e., one that would have missed its // deadline) // would be made even later // if (r.misses_deadline && booked_to[lowest_booked_cpu] > r.estimated_completion_time ){ INFO1 fprintf(stderr, " cand. fails; late result %s to be returned even later\n", r.name); return false; } } INFO1 fprintf(stderr, " cand. succeeds\n"); return true; } #ifdef TEST int main() { vector ip_results; double work_buf_min = 0; double cpu_pessimism_factor = 1; int ncpus = 1; bool flag; ip_results.push_back(IP_RESULT("R1", 5, 3)); ip_results.push_back(IP_RESULT("R2", 5, 3)); init_ip_results(work_buf_min, ncpus, ip_results); IP_RESULT c1 = IP_RESULT("C1", 10, 1); if (check_candidate(c1, ncpus, ip_results)) { printf("adding %s\n", c1.name); ip_results.push_back(c1); } IP_RESULT c2 = IP_RESULT("C2", 7, 2); if (check_candidate(c2, ncpus, ip_results)) { printf("adding %s\n", c2.name); ip_results.push_back(c2); } } #endif