/* * Definition of the scheduler plugin interface. * */ #ifndef _LINUX_RT_PARAM_H_ #define _LINUX_RT_PARAM_H_ #include typedef unsigned long jiffie_t; /* different types of clients */ typedef enum { RT_CLASS_HARD, RT_CLASS_SOFT, RT_CLASS_BEST_EFFORT } task_class_t; typedef struct rt_param { unsigned long exec_cost; unsigned long period; unsigned int cpu; task_class_t class; } rt_param_t; typedef struct { /* when will this task be release the next time? */ jiffie_t release; /* time instant the last job was released */ jiffie_t last_release; /* what is the current deadline? */ jiffie_t deadline; /* b-bit tie breaker for PFAIR, it is ignored in EDF */ int b_bit; /* group deadline tie breaker, it is ignored in EDF */ jiffie_t group_deadline; /* how long has this task executed so far? * In case of capacity sharing a job completion cannot be * detected by checking time_slice == 0 as the job may have * executed while using another capacity. Use this counter * to keep track of the time spent on a CPU by a job. * * In other words: The number of consumed quanta since the * last job release. */ unsigned int exec_time; } in_times_t; /* RT task parameters for scheduling extensions * These parameters are inherited during clone and therefore must * be explicitly set up before the task set is launched. */ typedef struct task_rt_param { /* Real-time marker */ int is_realtime; /* user controlled parameters */ rt_param_t basic_params; /* is the task sleeping? */ unsigned int flags; /* task representing the current "inherited" task * priority, assigned by inherit_priority and * return priority in the scheduler plugins. * could point to self if PI does not result in * an increased task priority. */ struct task_struct* inh_task; unsigned int is_non_preemptable; /* put information for feedback control stuff and * information about the performance of the task here */ struct { /* How many non-tardy jobs since the last tardy job? */ unsigned int nontardy_jobs_ctr; } stats; in_times_t times; in_times_t backup; /* is this task under control of litmus? * * this is necessary because otherwise signal delivery code * may try to wake up a task that is already queued in plugin * data structures. */ int litmus_controlled:1; int subject_to_srp:1; /* This field can be used by plugins to store where the task * is currently scheduled. It is the responsibility of the * plugin to avoid race conditions. */ int scheduled_on; /* This field can be used by plugins to store where the task * is currently linked. It is the responsibility of the plugin * to avoid race conditions. */ int linked_on; } task_rt_param_t; /* Possible RT flags */ #define RT_F_RUNNING 0x00000000 #define RT_F_SLEEP 0x00000001 #define RT_F_EXP_QUANTA 0x00000002 #define RT_F_NON_PREEMTABLE 0x00000004 #define RT_F_EXIT_SEM 0x00000008 /* Realtime utility macros */ #define get_passed_quanta(t) ((t)->rt_param.times.exec_time) #define inc_passed_quanta(t) ((t)->rt_param.times.exec_time += 1) #define get_rt_flags(t) ((t)->rt_param.flags) #define set_rt_flags(t,f) (t)->rt_param.flags=(f) #define get_exec_cost(t) ((t)->rt_param.basic_params.exec_cost) #define get_rt_period(t) ((t)->rt_param.basic_params.period) #define set_rt_period(t,p) (t)->rt_param.basic_params.period=(p) #define set_exec_cost(t,e) (t)->rt_param.basic_params.exec_cost=(e) #define get_partition(t) (t)->rt_param.basic_params.cpu #define get_deadline(t) ((t)->rt_param.times.deadline) #define get_class(t) ((t)->rt_param.basic_params.class) #define is_realtime(t) ((t)->rt_param.is_realtime) #define is_subject_to_srp(t) ((t)->rt_param.subject_to_srp) #define is_hrt(t) \ ((t)->rt_param.basic_params.class == RT_CLASS_HARD) #define is_srt(t) \ ((t)->rt_param.basic_params.class == RT_CLASS_SOFT) #define is_be(t) \ ((t)->rt_param.basic_params.class == RT_CLASS_BEST_EFFORT) #define is_np(t) ((t)->rt_param.is_non_preemptable) #define clear_rt_params(t) \ memset(&(t)->rt_param,0, sizeof(struct task_rt_param)) #define get_last_release_time(t) ((t)->rt_param.times.last_release) #define set_last_release_time(t,r) ((t)->rt_param.times.last_release=(r)) #define get_release(t) ((t)->rt_param.times.release) #define set_release(t,r) ((t)->rt_param.times.release=(r)) /* honor the flag that is set when scheduling is in progress * This is some dirty hack in Linux that creates race conditions in our code * if don't pay attention to it. */ #define is_running(t) \ ((t)->state == TASK_RUNNING || \ (t)->thread_info->preempt_count & PREEMPT_ACTIVE) #define is_blocked(t) (!is_running(t)) #define is_released(t) (time_before_eq((t)->rt_param.times.release, jiffies)) #define is_tardy(t) (time_before_eq((t)->rt_param.times.deadline, jiffies)) #define task_slack(t) ( (int) (t)->rt_param.times.deadline - (int) jiffies - \ (int) ((t)->rt_param.basic_params.exec_cost - \ (t)->rt_param.times.exec_time)) /* real-time comparison macros */ #define earlier_deadline(a, b) (time_before(\ (a)->rt_param.times.deadline,\ (b)->rt_param.times.deadline)) #define earlier_release(a, b) (time_before(\ (a)->rt_param.times.release,\ (b)->rt_param.times.release)) #define backup_times(t) do { (t)->rt_param.backup=(t)->rt_param.times; \ } while(0); #define restore_times(t) do { (t)->rt_param.times=(t)->rt_param.backup; \ } while(0); #endif