aboutsummaryrefslogtreecommitdiffstats
path: root/include/litmus/sched_plugin.h
blob: a55d276c95ebad58045fe08faef7379043133ae6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * Definition of the scheduler plugin interface.
 *
 */
#ifndef _LINUX_SCHED_PLUGIN_H_
#define _LINUX_SCHED_PLUGIN_H_

#include <linux/sched.h>

/* struct for semaphore with priority inheritance */
struct pi_semaphore {
	atomic_t count;
	int sleepers;
	wait_queue_head_t wait;
	union {
		/* highest-prio holder/waiter */
		struct task_struct *task;
		struct task_struct* cpu_task[NR_CPUS];
	} hp;
	/* current lock holder */
	struct task_struct *holder;
};


/********************* scheduler invocation ******************/

/*  Plugin-specific realtime tick handler */
typedef void (*scheduler_tick_t) (void);
/* Novell make sched decision function */
typedef int (*schedule_t) (struct task_struct * prev,
			   struct task_struct ** next);
/* 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 */
typedef long (*prepare_task_t) (struct task_struct *task);
/* called to re-introduce a task after blocking */
typedef void (*wake_up_task_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_blocks_t)  (struct task_struct *task);
/* called when a real-time task exits. Free any allocated resources */
typedef long (*tear_down_t)    (struct task_struct *);

/* Called when the new_owner is released from the wait queue
 * it should now inherit the priority from sem, _before_ it gets readded
 * to any queue
 */
typedef long (*inherit_priority_t) (struct pi_semaphore *sem,
				    struct task_struct *new_owner);

/* Called when the current task releases a semahpore where it might have
 * inherited a piority from
 */
typedef long (*return_priority_t) (struct pi_semaphore *sem);

/* Called when a task tries to acquire a semaphore and fails. Check if its
 * priority is higher than that of the current holder.
 */
typedef long (*pi_block_t) (struct pi_semaphore *sem, struct task_struct *t);


/********************* sys call backends  ********************/
/* This function causes the caller to sleep until the next release */
typedef long (*sleep_next_period_t) (void);

struct sched_plugin {
	struct list_head	list;
	/* 	basic info 		*/
	char 			*plugin_name;

	/* 	scheduler invocation 	*/
	scheduler_tick_t 	scheduler_tick;
	schedule_t 		schedule;
	finish_switch_t 	finish_switch;

	/*	syscall backend 	*/
	sleep_next_period_t 	sleep_next_period;

	/*	task state changes 	*/
	prepare_task_t 		prepare_task;
	wake_up_task_t 		wake_up_task;
	task_blocks_t		task_blocks;
	tear_down_t 		tear_down;

	/*     priority inheritance 	*/
	inherit_priority_t	inherit_priority;
	return_priority_t	return_priority;
	pi_block_t		pi_block;
} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));


extern struct sched_plugin *curr_sched_plugin;

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);

#endif