/* returns a task schedule object for the stochastic taskset "ts" */ tasks_schedule *new_task_schedule(stochastic_taskset * ts) { tasks_schedule *t_sched; if (!ts) return NULL; t_sched = malloc(sizeof(tasks_schedule)); if (!t_sched) return NULL; t_sched->ts = ts; t_sched->hyperperiod = get_hyperperiod(ts); { int i; unsigned int t_num = 0; for (i = 0; i < ts->tasks_num; i++) { t_num += t_sched->hyperperiod / ts->task_list[i]->period; } t_sched->timeline_len = t_num; } t_sched->timeline.is_new = 1; get_max_idle_FP(t_sched, 0); return t_sched; }
END_PERIODIC_TASK int sc_main (int, char *[]) { sc_time sim_time; // Definition of a task set (set to be assigned to a processor) // with the kista::taskset_by_name_t and task_info_t classes taskset_by_name_t task_set1; task_info_t task_info_t1("task1",task1); task_info_t task_info_t2("task2",task2); task_info_t1.set_WCET(WCET_T1); task_info_t2.set_WCET(WCET_T2); task_info_t1.set_Period(PERIOD_T1); task_info_t2.set_Period(PERIOD_T2); // // NOW WE ESTABLISH PRIORITIES (In KisTA: the lowest the value, the highest the priority, 0 reserved) // (The user assignation of this example is the opposite to Rate Monotonic scheduling) // You later can see how the set_rate_monotonic method makes an automatic assignation, // which overrides the user assignation once it is invoked afterwards, within the task set // #ifdef _SET_USER_PRIORITIES task_info_t1.set_priority(5); task_info_t2.set_priority(3); #endif #ifdef _SET_USER_DEADLINES task_info_t1.set_Deadline(DEADLINE_T1); task_info_t2.set_Deadline(DEADLINE_T2); #endif task_set1["task1"] = &task_info_t1; task_set1["task2"] = &task_info_t2; // gs->tasks_assigned["task1"] = task_info_t("task1",task1, gs); // gs->tasks_assigned["task2"] = task_info_t("task2",task2, gs); // Declaration of an scheduler and assignation of the task set // with the kista::scheduler class scheduler scheduler1(&task_set1, "scheduler1"); // Equivalently, the scheduler can be declared... // scheduler *scheduler1; // ... and assigned the task set afterwards, at construnction time // scheduler1 = new scheduler(&task_set1, "scheduler1"); // by default, non-preemptive, one processor // configuring the scheduler scheduler1.set_preemptive(); // enabling time slicing (we keep it disabled) // scheduler1.enable_time_slicing(); #ifdef _SET_STATIC_PRIORITIES scheduler1.set_policy(STATIC_PRIORITIES); #endif #ifdef _SET_RATE_MONOTONIC scheduler1.set_rate_monotonic(); // it already includes the set_dispatch_policy(STATIC_PRIORITIES) #endif #ifdef _SET_DEADLINE_MONOTONIC scheduler1.set_deadline_monotonic(); // it already includes the set_dispatch_policy(STATIC_PRIORITIES) #endif // Tracing of the tasks and scheduler ocupation signals // with the kista::trace method of the kista::scheduler class scheduler1.trace_utilizations(); tikz_activity_trace_handler gen_tikz_report_handler; // create_tikz_activity_trace(); //gen_tikz_report_handler = create_tikz_activity_trace(); gen_tikz_report_handler = create_tikz_activity_trace("2tasks_tikz_trace"); set_scale(gen_tikz_report_handler,1.25); set_landscape(gen_tikz_report_handler); no_text_in_traces(gen_tikz_report_handler); do_not_show_unactive_boxes(gen_tikz_report_handler); set_time_stamps_max_separation(gen_tikz_report_handler,3); only_image(gen_tikz_report_handler); // cluster(gen_tikz_report_handler); // compact(gen_tikz_report_handler); sketch_report.set_file_name("ex3_sketch"); // This will set the file name of the sketch report to "ex3_sketch.tex" // otherwise, the default name "system_sketch.tex" will be applied sketch_report.enable(); // sketch_report.set_file_name("ex3_sketch"); // Here, it would be overriden, and the the default name used sim_time = get_hyperperiod(task_set1); cout << "Hyperperiod of task set : " << sim_time << endl; cout << "Global simulation time limit : " << get_global_simulation_time_limit() << endl; // to enable scheduling times enable_scheduling_times(); set_scheduling_time(sc_time(1,SC_NS)); set_default_scheduling_time_calculators(); sc_start(sim_time); cout << "End of simulation at " << sc_time_stamp() << endl; sc_stop(); taskset_by_name_t::iterator ts_it; cout << "-------------------------" << endl; cout << "POST-SIM. REPORTS" << endl; cout << "-------------------------" << endl; cout << "*********************************************" << endl; cout << " Utilization and Starvation Report " << endl; cout << "*********************************************" << endl; cout << "Hyperperiod of task set task_set1: " << get_hyperperiod(task_set1) << endl; for(ts_it = task_set1.begin(); ts_it != task_set1.end(); ts_it++) { cout << ts_it->first << " task utilization : (static) " << (float)(ts_it->second->utilization()*100.0) << "% (simulation): " << (float)(scheduler1.get_task_utilization(ts_it->first)*100.0) << "%" << endl; } cout << "Task Set utilization : (static) " << (float)(utilization(task_set1)*100.0) << "% (simulation) " << (float)(scheduler1.get_tasks_utilization()*100.0) << "%" << endl; for(ts_it = task_set1.begin(); ts_it != task_set1.end(); ts_it++) { cout << ts_it->first << " task density : (static) " << (float)(ts_it->second->density()*100.0) << "%" << endl; } cout << "Task Set density : (static) " << (float)(density(task_set1)*100.0) << "% " << endl; cout << scheduler1.name() << " (sim) number of schedulings: " << (unsigned int)scheduler1.get_number_of_schedulings() << endl; cout << scheduler1.name() << " (sim) scheduler utilization : " << (float)(scheduler1.get_scheduler_utilization()*100.0) << "%" << endl; cout << scheduler1.name() << " (sim) platform utilization : " << (float)(scheduler1.get_platform_utilization()*100.0) << "%" << endl; cout << "last simulation time: " << sc_time_stamp() << endl; if(scheduler1.assess_starvation()!=true) { cout << scheduler1.name() << " scheduler: No starvation detected. All tasks had chance to execute." << endl; } scheduler1.report_miss_deadlines(); scheduler1.report_response_times(); return 0; }