aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-28 12:24:58 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-02-01 16:30:37 -0500
commit2dea9d5e7727b8474981557cbf925687b8f33865 (patch)
tree96134311a3b67372e19a5f7eb232acb3d0be9b09
parentfd8ae31c74975c8499983c9831bff2b136b98434 (diff)
Litmus core: change plugin locking interface to generic 'allocate_lock()'
As the number of supported locking protocols is expected to rise, hard-coding things like priority inheritance in the plugin interface doesn't scale. Instead, use a new generic lock-ops approach. With this approach, each plugin can define its own protocol implementation (or use a generic one), and plugins can support multiple protocols without having to change the plugin interface for each protocol.
-rw-r--r--include/litmus/locking.h28
-rw-r--r--include/litmus/sched_plugin.h50
-rw-r--r--litmus/Kconfig23
-rw-r--r--litmus/sched_plugin.c30
4 files changed, 51 insertions, 80 deletions
diff --git a/include/litmus/locking.h b/include/litmus/locking.h
new file mode 100644
index 000000000000..4d7b870cb443
--- /dev/null
+++ b/include/litmus/locking.h
@@ -0,0 +1,28 @@
1#ifndef LITMUS_LOCKING_H
2#define LITMUS_LOCKING_H
3
4struct litmus_lock_ops;
5
6/* Generic base struct for LITMUS^RT userspace semaphores.
7 * This structure should be embedded in protocol-specific semaphores.
8 */
9struct litmus_lock {
10 struct litmus_lock_ops *ops;
11 int type;
12};
13
14struct litmus_lock_ops {
15 /* Current task tries to obtain / drop a reference to a lock.
16 * Optional methods, allowed by default. */
17 int (*open)(struct litmus_lock*, void* __user);
18 int (*close)(struct litmus_lock*);
19
20 /* Current tries to lock/unlock this lock (mandatory methods). */
21 int (*lock)(struct litmus_lock*);
22 int (*unlock)(struct litmus_lock*);
23
24 /* The lock is no longer being referenced (mandatory method). */
25 void (*deallocate)(struct litmus_lock*);
26};
27
28#endif
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 2d856d587041..27b719aebed9 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -7,19 +7,9 @@
7 7
8#include <linux/sched.h> 8#include <linux/sched.h>
9 9
10/* struct for semaphore with priority inheritance */ 10#ifdef CONFIG_LITMUS_LOCKING
11struct pi_semaphore { 11#include <litmus/locking.h>
12 atomic_t count; 12#endif
13 int sleepers;
14 wait_queue_head_t wait;
15 struct {
16 /* highest-prio holder/waiter */
17 struct task_struct *task;
18 struct task_struct* cpu_task[NR_CPUS];
19 } hp;
20 /* current lock holder */
21 struct task_struct *holder;
22};
23 13
24/************************ setup/tear down ********************/ 14/************************ setup/tear down ********************/
25 15
@@ -63,24 +53,9 @@ typedef void (*task_block_t) (struct task_struct *task);
63 */ 53 */
64typedef void (*task_exit_t) (struct task_struct *); 54typedef void (*task_exit_t) (struct task_struct *);
65 55
66/* Called when the new_owner is released from the wait queue 56/* Called when the current task attempts to create a new lock of a given
67 * it should now inherit the priority from sem, _before_ it gets readded 57 * protocol type. */
68 * to any queue 58typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type);
69 */
70typedef long (*inherit_priority_t) (struct pi_semaphore *sem,
71 struct task_struct *new_owner);
72
73/* Called when the current task releases a semahpore where it might have
74 * inherited a piority from
75 */
76typedef long (*return_priority_t) (struct pi_semaphore *sem);
77
78/* Called when a task tries to acquire a semaphore and fails. Check if its
79 * priority is higher than that of the current holder.
80 */
81typedef long (*pi_block_t) (struct pi_semaphore *sem, struct task_struct *t);
82
83
84 59
85 60
86/********************* sys call backends ********************/ 61/********************* sys call backends ********************/
@@ -100,10 +75,6 @@ struct sched_plugin {
100 activate_plugin_t activate_plugin; 75 activate_plugin_t activate_plugin;
101 deactivate_plugin_t deactivate_plugin; 76 deactivate_plugin_t deactivate_plugin;
102 77
103#ifdef CONFIG_SRP
104 unsigned int srp_active;
105#endif
106
107 /* scheduler invocation */ 78 /* scheduler invocation */
108 scheduler_tick_t tick; 79 scheduler_tick_t tick;
109 schedule_t schedule; 80 schedule_t schedule;
@@ -121,12 +92,9 @@ struct sched_plugin {
121 task_block_t task_block; 92 task_block_t task_block;
122 task_exit_t task_exit; 93 task_exit_t task_exit;
123 94
124#ifdef CONFIG_FMLP 95#ifdef CONFIG_LITMUS_LOCKING
125 /* priority inheritance */ 96 /* locking protocols */
126 unsigned int fmlp_active; 97 allocate_lock_t allocate_lock;
127 inherit_priority_t inherit_priority;
128 return_priority_t return_priority;
129 pi_block_t pi_block;
130#endif 98#endif
131} __attribute__ ((__aligned__(SMP_CACHE_BYTES))); 99} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
132 100
diff --git a/litmus/Kconfig b/litmus/Kconfig
index a2f267870f29..ad8dc8308cf0 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -46,28 +46,19 @@ config NP_SECTION
46 Note that plugins still need to explicitly support non-preemptivity. 46 Note that plugins still need to explicitly support non-preemptivity.
47 Currently, only GSN-EDF and PSN-EDF have such support. 47 Currently, only GSN-EDF and PSN-EDF have such support.
48 48
49 This is required to support the FMLP. 49 This is required to support locking protocols such as the FMLP.
50 If disabled, all tasks will be considered preemptable at all times. 50 If disabled, all tasks will be considered preemptable at all times.
51 51
52config SRP 52config LITMUS_LOCKING
53 bool "Stack Resource Policy (SRP)" 53 bool "Support for real-time locking protocols"
54 default n
55 help
56 Include support for Baker's Stack Resource Policy.
57
58 Say Yes if you want FMLP local long critical section
59 synchronization support.
60
61config FMLP
62 bool "FMLP support"
63 depends on NP_SECTION 54 depends on NP_SECTION
64 default n 55 default n
65 help 56 help
66 Include support for deterministic multiprocessor real-time 57 Enable LITMUS^RT's deterministic multiprocessor real-time
67 synchronization support. 58 locking protocols.
68 59
69 Say Yes if you want FMLP long critical section 60 Say Yes if you want to include locking protocols such as the FMLP and
70 synchronization support. 61 Baker's SRP.
71 62
72endmenu 63endmenu
73 64
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index d912a6494d20..2f8f399b195f 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -121,23 +121,11 @@ static long litmus_dummy_deactivate_plugin(void)
121 return 0; 121 return 0;
122} 122}
123 123
124#ifdef CONFIG_FMLP 124#ifdef CONFIG_LITMUS_LOCKING
125 125
126static long litmus_dummy_inherit_priority(struct pi_semaphore *sem, 126static long litmus_dummy_allocate_lock(struct litmus_lock **lock, int type)
127 struct task_struct *new_owner)
128{ 127{
129 return -ENOSYS; 128 return -ENXIO;
130}
131
132static long litmus_dummy_return_priority(struct pi_semaphore *sem)
133{
134 return -ENOSYS;
135}
136
137static long litmus_dummy_pi_block(struct pi_semaphore *sem,
138 struct task_struct *new_waiter)
139{
140 return -ENOSYS;
141} 129}
142 130
143#endif 131#endif
@@ -158,10 +146,8 @@ struct sched_plugin linux_sched_plugin = {
158 .finish_switch = litmus_dummy_finish_switch, 146 .finish_switch = litmus_dummy_finish_switch,
159 .activate_plugin = litmus_dummy_activate_plugin, 147 .activate_plugin = litmus_dummy_activate_plugin,
160 .deactivate_plugin = litmus_dummy_deactivate_plugin, 148 .deactivate_plugin = litmus_dummy_deactivate_plugin,
161#ifdef CONFIG_FMLP 149#ifdef CONFIG_LITMUS_LOCKING
162 .inherit_priority = litmus_dummy_inherit_priority, 150 .allocate_lock = litmus_dummy_allocate_lock,
163 .return_priority = litmus_dummy_return_priority,
164 .pi_block = litmus_dummy_pi_block,
165#endif 151#endif
166 .admit_task = litmus_dummy_admit_task 152 .admit_task = litmus_dummy_admit_task
167}; 153};
@@ -198,10 +184,8 @@ int register_sched_plugin(struct sched_plugin* plugin)
198 CHECK(complete_job); 184 CHECK(complete_job);
199 CHECK(activate_plugin); 185 CHECK(activate_plugin);
200 CHECK(deactivate_plugin); 186 CHECK(deactivate_plugin);
201#ifdef CONFIG_FMLP 187#ifdef CONFIG_LITMUS_LOCKING
202 CHECK(inherit_priority); 188 CHECK(allocate_lock);
203 CHECK(return_priority);
204 CHECK(pi_block);
205#endif 189#endif
206 CHECK(admit_task); 190 CHECK(admit_task);
207 191