idle_time_sumsq/running_time;
double s = sqrt(avg_ss);
sum += s;
}
int n = (int)projects.size();
double x = sum/(n*schedint*n);
double m = 1-(1/(x+1));
//printf("sum: %f; x: %f m: %f\n", sum, x, m);
return m;
}
// the CPU totals are there; compute the other fields
//
void SIM_RESULTS::compute() {
double total = cpu_used + cpu_wasted + cpu_idle;
cpu_wasted_frac = cpu_wasted/total;
cpu_idle_frac = cpu_idle/total;
share_violation = gstate.share_violation();
monotony = gstate.monotony();
}
// top-level results (for aggregating multiple simulations)
//
void SIM_RESULTS::print(FILE* f, const char* title) {
if (title) {
fprintf(f, "%s: ", title);
}
fprintf(f, "wasted_frac %f idle_frac %f share_violation %f monotony %f\n",
cpu_wasted_frac, cpu_idle_frac, share_violation, monotony
);
}
void SIM_RESULTS::parse(FILE* f) {
fscanf(f, "wasted_frac %lf idle_frac %lf share_violation %lf monotony %lf",
&cpu_wasted_frac, &cpu_idle_frac, &share_violation, &monotony
);
}
void SIM_RESULTS::add(SIM_RESULTS& r) {
cpu_wasted_frac += r.cpu_wasted_frac;
cpu_idle_frac += r.cpu_idle_frac;
share_violation += r.share_violation;
monotony += r.monotony;
}
void SIM_RESULTS::divide(int n) {
cpu_wasted_frac /= n;
cpu_idle_frac /= n;
share_violation /= n;
monotony /= n;
}
void SIM_RESULTS::clear() {
memset(this, 0, sizeof(*this));
}
void SIM_PROJECT::print_results(FILE* f, SIM_RESULTS& sr) {
double t = project_results.cpu_used + project_results.cpu_wasted;
double gt = sr.cpu_used + sr.cpu_wasted;
fprintf(f, "%s: share %.2f total CPU %2f (%.2f%%)\n"
" used %.2f wasted %.2f\n"
" met %d missed %d\n",
project_name, resource_share,
t, (t/gt)*100,
project_results.cpu_used,
project_results.cpu_wasted,
project_results.nresults_met_deadline,
project_results.nresults_missed_deadline
);
}
char* colors[] = {
"#ffffdd",
"#ffddff",
"#ddffff",
"#ddffdd",
"#ddddff",
"#ffdddd",
};
static int outfile_num=0;
void CLIENT_STATE::html_start(bool show_prev) {
char buf[256];
sprintf(buf, "sim_out_%d.html", outfile_num++);
html_out = fopen(buf, "w");
if (!html_out) {
fprintf(stderr, "can't open %s for writing\n", buf);
exit(1);
}
setbuf(html_out, 0);
fprintf(html_out, "Simulator output
\n");
if (show_prev) {
fprintf(html_out,
"Previous file\n",
outfile_num-2
);
}
fprintf(html_out,
"message log
"
"
Time | \n"
);
for (int i=0; iCPU %d
Job name and estimated time left
color denotes project
* means EDF mode", i
);
}
fprintf(html_out, "Notes |
\n");
}
void CLIENT_STATE::html_rec() {
static int line_num=0;
fprintf(html_out, "%s | ", time_to_string(now));
if (!running) {
for (int j=0; jOFF");
}
} else {
int n=0;
for (unsigned int i=0; itask_state() == PROCESS_EXECUTING) {
SIM_PROJECT* p = (SIM_PROJECT*)atp->result->project;
fprintf(html_out, "%s%s: %.2f | ",
colors[p->index],
atp->result->rr_sim_misses_deadline?"*":"",
atp->result->name, atp->cpu_time_left
);
n++;
}
}
while (nIDLE");
n++;
}
}
fprintf(html_out, "%s |
\n", html_msg.c_str());
html_msg = "";
if (++line_num == line_limit) {
line_num = 0;
html_end(true);
html_start(true);
}
}
void CLIENT_STATE::html_end(bool show_next) {
fprintf(html_out, "
");
if (show_next) {
fprintf(html_out,
"Next file\n",
outfile_num
);
} else {
fprintf(html_out, "
\n");
sim_results.compute();
sim_results.print(html_out);
print_project_results(html_out);
fprintf(html_out, "
\n");
}
if (show_next) {
fprintf(html_out, "Last file\n");
} else {
char buf[256];
sprintf(buf, "sim_out_%d.html", outfile_num-1);
#ifndef _WIN32
symlink(buf, "sim_out_last.html");
#endif
}
fclose(html_out);
}
void CLIENT_STATE::simulate() {
bool action;
now = 0;
html_start(false);
while (1) {
running = host_info.available.sample(now);
while (1) {
action = active_tasks.poll();
if (running) {
action |= handle_finished_apps();
action |= possibly_schedule_cpus();
action |= enforce_schedule();
action |= scheduler_rpc_poll();
}
if (!action) break;
}
now += delta;
html_rec();
if (now > duration) break;
}
html_end(false);
}
void parse_error(char* file, int retval) {
printf("can't parse %s: %d\n", file, retval);
exit(1);
}
void help(char* prog) {
fprintf(stderr, "usage: %s\n"
"[--duration X]\n"
"[--delta X]\n"
"[--server_uses_workload]\n"
"[--dcf_dont_user]\n"
"[--dcf_stats]\n"
"[--dual_dcf]\n"
"[--cpu_sched_rr_only]\n"
"[--work_fetch_old]\n"
"[--dirs ...]\n",
prog
);
exit(1);
}
char* next_arg(int argc, char** argv, int& i) {
if (i >= argc) {
fprintf(stderr, "Missing command-line argument\n");
help(argv[0]);
}
return argv[i++];
}
#define PROJECTS_FILE "sim_projects.xml"
#define HOST_FILE "sim_host.xml"
#define PREFS_FILE "sim_prefs.xml"
#define SUMMARY_FILE "sim_summary.txt"
#define LOG_FILE "sim_log.txt"
int main(int argc, char** argv) {
int i, retval;
vector dirs;
logfile = fopen("sim_log.txt", "w");
if (!logfile) {
fprintf(stderr, "Can't open sim_log.txt\n");
exit(1);
}
sim_results.clear();
for (i=1; i %s",
SIM_EXEC, duration, delta, SUMMARY_FILE
);
retval = system(buf);
if (retval) {
printf("simulation in %s failed\n", dir.c_str());
exit(1);
}
FILE* f = fopen(SUMMARY_FILE, "r");
sim_results.parse(f);
fclose(f);
sim_results.print(stdout, dir.c_str());
total_results.add(sim_results);
chdir("..");
}
total_results.divide((int)(dirs.size()));
total_results.print(stdout, "Total");
} else {
msg_printf(0, MSG_INFO, "SIMULATION START");
read_config_file(true);
config.show();
int retval;
bool flag;
retval = gstate.parse_host(HOST_FILE);
if (retval) parse_error(HOST_FILE, retval);
retval = gstate.parse_projects(PROJECTS_FILE);
if (retval) parse_error(PROJECTS_FILE, retval);
retval = gstate.global_prefs.parse_file(PREFS_FILE, "", flag);
if (retval) parse_error(PREFS_FILE, retval);
gstate.set_ncpus();
work_fetch.init();
gstate.request_work_fetch("init");
gstate.simulate();
sim_results.compute();
// print machine-readable first
sim_results.print(stdout);
// then other
gstate.print_project_results(stdout);
}
}