void generate_taskset(vector<float_task> *tasks, long hyperperiod, int num_tasks, float comp_util, float thermal_util) { vector<int> factors; factorise(&factors, hyperperiod); float_task temp; // int num_tasks = // cout<<" number of tasks "<<num_tasks<<endl; float sumU=comp_util; float t_sumU=thermal_util; // cout<<" initial sumU "<<sumU<<" t_sumU "<<t_sumU<<endl; float t_next_sumU; float next_sumU; bool violation=false; for (int i = 0; i < num_tasks; i++) { int index = rand() % factors.size(); temp.period = factors[index]; float cutil; if(i<num_tasks-1) { next_sumU=sumU*pow((float)(rand()/((float)(RAND_MAX))),1.0/((float)(num_tasks-(i+1)))); // cout<<" sumu "<<sumU<<" next sumu "<<next_sumU<<endl; cutil=sumU-next_sumU; } else { cutil=sumU; } temp.computation_time=temp.period*(cutil); temp.computation_time=floor(temp.computation_time/(W_INT*temp.period))*W_INT*temp.period; sumU=sumU-(temp.computation_time/temp.period); if (temp.computation_time > 0) { tasks->push_back(temp); } } for(unsigned int i=0;i<tasks->size() && !violation;i++) { float tutil; float max_tutil=t_sumU; float min_tutil=t_sumU; if(i<num_tasks-1) { for(unsigned int j=i+1;j<tasks->size();j++) { max_tutil=max_tutil-MIN_POWER*(*tasks)[j].computation_time/(corrected_threshold*beta*(*tasks)[j].period); min_tutil=min_tutil-MAX_POWER*(*tasks)[j].computation_time/(corrected_threshold*beta*(*tasks)[j].period); } float local_max; float local_min; local_max=MAX_POWER*(*tasks)[i].computation_time/(corrected_threshold*beta*(*tasks)[i].period); local_min=MIN_POWER*(*tasks)[i].computation_time/(corrected_threshold*beta*(*tasks)[i].period); max_tutil=max_tutil>local_max?local_max:max_tutil; min_tutil=min_tutil<local_min?local_min:min_tutil; if(min_tutil>max_tutil || max_tutil<min_tutil) { cout<<" error detected min tutil "<<min_tutil<<" max util "<<max_tutil<<endl; } // cout<<" index "<<i<<" num tasks "<<num_tasks<<" max "<<max_tutil<<" min "<<min_tutil<<endl; tutil=-1; int iteration=0; while((tutil<min_tutil || tutil>max_tutil) && !violation) { t_next_sumU=t_sumU*pow(rand()/((float)(RAND_MAX)),1.0/((float)(num_tasks-(i+1)))); tutil=t_sumU-t_next_sumU; if(iteration>1000) { violation=true; } iteration=iteration+1; } // cout<<" exited while loop "<<endl; } else { tutil=t_sumU; } (*tasks)[i].power=corrected_threshold*beta * (*tasks)[i].period*tutil/(*tasks)[i].computation_time; (*tasks)[i].power=floor((*tasks)[i].power*10.0)/10.0; (*tasks)[i].power=(*tasks)[i].power>MAX_POWER?MAX_POWER:(*tasks)[i].power<MIN_POWER?MIN_POWER:(*tasks)[i].power; t_sumU=t_sumU-(*tasks)[i].computation_time*(*tasks)[i].power/(corrected_threshold*beta*(*tasks)[i].period); //cout<<"numerator "<<corrected_threshold*beta * temp.period*tutil<<endl; } // cout<<"checkpoint 1"<<endl; // for(unsigned int i=0;i<tasks->size();i++) // { // if((*tasks)[i].power<MIN_POWER || (*tasks)[i].power>MAX_POWER) // { // violation=true; // break; // } // } if(violation) { tasks->clear(); generate_taskset(tasks, hyperperiod, num_tasks, comp_util, thermal_util); } for(unsigned int i =0;i<tasks->size();i++) { (*tasks)[i].index=i; } }
/* entry point. */ int main(int argc, char *argv[]) { int i, j, k; /* temporary vaiables. */ int tmp; char strtmp[MAX_BUF]; /* the number of processors. */ int m = NR_RT_CPUS; /* path to a directory where a taskset file is located. */ char path[MAX_BUF]; /* path to a taskset file. */ char tsfile[MAX_BUF]; FILE *fp; /* minimum/maximum utilization of individual task [0, 1.0]. default: umin=0.1, umax=1.0. */ char umin[MAX_BUF] = "0.1", umax[MAX_BUF] = "1.0"; /* minimum/maximum period of individual task (milliseconds). default: pmin=10, pmax=1000. */ char pmin[MAX_BUF] = "10", pmax[MAX_BUF] = "1000"; /* distribution of utilization of tasks. default: uniform distribution. */ char dist[MAX_BUF] = "uniform"; /* parameters for bimodal & exponential distributions. default: all 0.5. */ char sep[MAX_BUF] = "0.5"; char prob[MAX_BUF] = "0.5"; char mean[MAX_BUF] = "0.5"; /* type of deadlines. default: implicit. */ char deadline[MAX_BUF] = "implicit"; /* type of periods. default: nonharmonic. */ char period[MAX_BUF] = "nonharmonic"; /* the length of benchmarking period (ms). default: 1000 seconds.*/ int time = 1000000; /* benchmarking range [0, 100] default: from system utilization 50% to 100% at every 5%. */ int start = 50; int end = 100; int step = 5; /* the number of tasksets per workload testing. */ int quantity = 1000; /* file name that outputs benchmarking results. */ char result[MAX_BUF] = "./result"; /* scheduling policy. */ int policy = SCHED_FP; /* print flag. */ int print = 0; /* loop counts that consume 1ms. */ int loop_1ms; /* benchmarking workload. */ int workload; /* success ratio. */ int nr_success; double *success_ratios; /*********************************************************************** * Options: * --cpus= the number of processors used. * --umin= the minimum utilization [0, 1.0] of every individual task. * --umax= the maximum utilization [0, 1.0] of every individual task. * --pmin= the minimum period of every individual task * (by milliseconds). * --pmax= the maximum period of every individual task * (by milliseconds). * --dist= the distribution of utilizations of tasks * (by uniform, bimodal, or exponential). * if bimodal is chosen, the utilization separator between * light tasks and heavy tasks must be set by --sep. * --sep= the utilization separator [0, 1.0] between light tasks * and heavy tasks in a bimodal distribution . * --prob= the probability [0, 1.0] of being heavy tasks in a * bimodal distribution. * --mean= the mean value [0, 1.0] in an exponetial distribution. * --deadline= the type of relative deadlines * (by implicit, constrained, or arbitrary). * if "implicit" is chosen, the relative deadline is equal * to the period. * if "constrained" is chosen, the relative deadline is set * uniformly between the exec. time and the period. * if "arbitrary" is chosen, the relative deadline is set * uniformly between the exec. time and 4 times the period. * --period= the type of periods (by arbitrary or harmonic). * --time= the length of benchmarking time (ms). * --start= benchmarking starts from this system load [0, 100]. * --end= benchmarking ends at this system load [0, 100]. * --step= the distance of every successive sampling system load * to be tested by benchmarking. * --quantity= the number of tasksets tested per workload. * --result= the file name, in which benchmarking results are saved. * --print print the progress of benchmarking. ***********************************************************************/ for (i = 1; i < argc; i++) { if (strncmp(argv[i], "--cpus", (tmp = strlen("--cpus"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } m = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--umin", (tmp = strlen("--umin"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(umin, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--umax", (tmp = strlen("--umax"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(umax, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--pmin", (tmp = strlen("--pmin"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(pmin, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--pmax", (tmp = strlen("--pmax"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(pmax, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--dist", (tmp = strlen("--dist"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(dist, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--sep", (tmp = strlen("--sep"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(sep, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--prob", (tmp = strlen("--prob"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(prob, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--mean", (tmp = strlen("--mean"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(mean, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--deadline", (tmp = strlen("--deadline"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(deadline, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--period", (tmp = strlen("--period"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(period, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--time", (tmp = strlen("--time"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } time = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--start", (tmp = strlen("--start"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } start = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--end", (tmp = strlen("--end"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } end = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--step", (tmp = strlen("--step"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } step = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--quantity", (tmp = strlen("--quantity"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } quantity = atoi(&argv[i][tmp+1]); } else if (strncmp(argv[i], "--result", (tmp = strlen("--result"))) == 0) { if (argv[i][tmp] != '=') { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } strncpy(result, &argv[i][tmp+1], MAX_BUF); } else if (strncmp(argv[i], "--edf", (tmp = strlen("--edf"))) == 0) { policy = SCHED_EDF; } else if (strncmp(argv[i], "--fair", (tmp = strlen("--fair"))) == 0) { policy = SCHED_FAIR; } else if (strncmp(argv[i], "--print", (tmp = strlen("--print"))) == 0) { print = 1; } else if (strncmp(argv[i], "--help", (tmp = strlen("--help"))) == 0) { help(); exit(0); } else { printf("option \"%s\" is invalid.\n", argv[i]); exit(1); } } /* measure the cycles that consume 1 millisecond. note that this procedure has to be done in real-time mode with the highest priority. otherwise, the loop count will be much less than what we expect... */ rt_init(); rt_set_priority(99); loop_1ms = measure_1ms(); rt_exit(); /* arrays to store the success ratios. */ success_ratios = (double*) malloc(sizeof(double) * ((end-start)/step+1)); /* benchmarking range of system utilization. */ start *= m; end *= m; step *= m; i = 0; for (workload = start; workload <= end; workload += step) { /* generate task set files, if necessary. */ generate_taskset(path, quantity, dist, deadline, period, workload, atof(sep), atof(prob), atof(mean), atof(umin), atof(umax), atoi(pmin), atoi(pmax)); /* success counter. */ nr_success = 0; /* schedule 1,000 tasksets, each of which include tasks with total workload = @workload. dont use @i! */ for (k = 1; k <= quantity; k++) { /* path to the taskset file. */ sprintf(tsfile, "%s/workload%d/ts%d", path, workload, k); if ((fp = fopen(tsfile, "r")) == NULL) { printf("Cannot open file %s\n", tsfile); goto end; } /* schedule this taskset. */ if (print) { printf("scheduling %s...\n", tsfile); } if (schedule(fp, m, loop_1ms, time, policy)) { nr_success++; } fclose(fp); } /* success ratio. */ success_ratios[i] = (double)nr_success / (double)quantity; if (print) { printf("%d %f\n", workload, success_ratios[i] * 100); } i++; } fp = fopen(result, "w"); i = 0; for (workload = start; workload <= end; workload += step) { fprintf(fp, "%d %f\n", workload, success_ratios[i] * 100); i++; } fclose(fp); end: free(success_ratios); return 0; }