/* * Definition of the scheduler plugin interface. * */ #ifndef _LINUX_SCHED_PLUGIN_H_ #define _LINUX_SCHED_PLUGIN_H_ #include #ifdef CONFIG_LITMUS_LOCKING #include #endif #ifdef CONFIG_LITMUS_AFFINITY_LOCKING #include #endif #include /************************ setup/tear down ********************/ typedef long (*activate_plugin_t) (void); typedef long (*deactivate_plugin_t) (void); /********************* scheduler invocation ******************/ /* Plugin-specific realtime tick handler */ typedef void (*scheduler_tick_t) (struct task_struct *cur); /* Novell make sched decision function */ typedef struct task_struct* (*schedule_t)(struct task_struct * prev); /* Clean up after the task switch has occured. * This function is called after every (even non-rt) task switch. */ typedef void (*finish_switch_t)(struct task_struct *prev); /********************* task state changes ********************/ /* Called to setup a new real-time task. * Release the first job, enqueue, etc. * Task may already be running. */ typedef void (*task_new_t) (struct task_struct *task, int on_rq, int running); /* Called to re-introduce a task after blocking. * Can potentially be called multiple times. */ typedef void (*task_wake_up_t) (struct task_struct *task); /* called to notify the plugin of a blocking real-time task * it will only be called for real-time tasks and before schedule is called */ typedef void (*task_block_t) (struct task_struct *task); /* Called when a real-time task exits or changes to a different scheduling * class. * Free any allocated resources */ typedef void (*task_exit_t) (struct task_struct *); /* Called when the current task attempts to create a new lock of a given * protocol type. */ typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type, void* __user config); struct affinity_observer; typedef long (*allocate_affinity_observer_t) ( struct affinity_observer **aff_obs, int type, void* __user config); typedef void (*increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh); typedef void (*decrease_prio_t)(struct task_struct* t, struct task_struct* prio_inh); typedef int (*__increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh); typedef int (*__decrease_prio_t)(struct task_struct* t, struct task_struct* prio_inh); typedef void (*nested_increase_prio_t)(struct task_struct* t, struct task_struct* prio_inh, raw_spinlock_t *to_unlock, unsigned long irqflags); typedef void (*nested_decrease_prio_t)(struct task_struct* t, struct task_struct* prio_inh, raw_spinlock_t *to_unlock, unsigned long irqflags); typedef void (*increase_prio_klitirq_t)(struct task_struct* klitirqd, struct task_struct* old_owner, struct task_struct* new_owner); typedef void (*decrease_prio_klitirqd_t)(struct task_struct* klitirqd, struct task_struct* old_owner); typedef int (*enqueue_pai_tasklet_t)(struct tasklet_struct* tasklet); typedef void (*change_prio_pai_tasklet_t)(struct task_struct *old_prio, struct task_struct *new_prio); typedef void (*run_tasklets_t)(struct task_struct* next); typedef raw_spinlock_t* (*get_dgl_spinlock_t) (struct task_struct *t); typedef int (*higher_prio_t)(struct task_struct* a, struct task_struct* b); #ifdef CONFIG_LITMUS_NESTED_LOCKING typedef enum { BASE, EFFECTIVE } comparison_mode_t; typedef int (*__higher_prio_t)(struct task_struct* a, comparison_mode_t a_mod, struct task_struct* b, comparison_mode_t b_mod); #endif /********************* sys call backends ********************/ /* This function causes the caller to sleep until the next release */ typedef long (*complete_job_t) (void); typedef long (*admit_task_t)(struct task_struct* tsk); typedef void (*release_at_t)(struct task_struct *t, lt_t start); struct sched_plugin { struct list_head list; /* basic info */ char *plugin_name; /* setup */ activate_plugin_t activate_plugin; deactivate_plugin_t deactivate_plugin; /* scheduler invocation */ scheduler_tick_t tick; schedule_t schedule; finish_switch_t finish_switch; /* syscall backend */ complete_job_t complete_job; release_at_t release_at; /* task state changes */ admit_task_t admit_task; task_new_t task_new; task_wake_up_t task_wake_up; task_block_t task_block; task_exit_t task_exit; higher_prio_t compare; #ifdef CONFIG_LITMUS_LOCKING /* locking protocols */ allocate_lock_t allocate_lock; increase_prio_t increase_prio; decrease_prio_t decrease_prio; __increase_prio_t __increase_prio; __decrease_prio_t __decrease_prio; #endif #ifdef CONFIG_LITMUS_NESTED_LOCKING nested_increase_prio_t nested_increase_prio; nested_decrease_prio_t nested_decrease_prio; __higher_prio_t __compare; #endif #ifdef CONFIG_LITMUS_DGL_SUPPORT get_dgl_spinlock_t get_dgl_spinlock; #endif #ifdef CONFIG_LITMUS_AFFINITY_LOCKING allocate_affinity_observer_t allocate_aff_obs; #endif #ifdef CONFIG_LITMUS_SOFTIRQD increase_prio_klitirq_t increase_prio_klitirqd; decrease_prio_klitirqd_t decrease_prio_klitirqd; #endif #ifdef CONFIG_LITMUS_PAI_SOFTIRQD enqueue_pai_tasklet_t enqueue_pai_tasklet; change_prio_pai_tasklet_t change_prio_pai_tasklet; run_tasklets_t run_tasklets; #endif } __attribute__ ((__aligned__(SMP_CACHE_BYTES))); extern struct sched_plugin *litmus; int register_sched_plugin(struct sched_plugin* plugin); struct sched_plugin* find_sched_plugin(const char* name); int print_sched_plugins(char* buf, int max); extern struct sched_plugin linux_sched_plugin; #endif