diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-01-28 12:24:58 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-02-01 16:30:37 -0500 |
commit | 2dea9d5e7727b8474981557cbf925687b8f33865 (patch) | |
tree | 96134311a3b67372e19a5f7eb232acb3d0be9b09 | |
parent | fd8ae31c74975c8499983c9831bff2b136b98434 (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.h | 28 | ||||
-rw-r--r-- | include/litmus/sched_plugin.h | 50 | ||||
-rw-r--r-- | litmus/Kconfig | 23 | ||||
-rw-r--r-- | litmus/sched_plugin.c | 30 |
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 | |||
4 | struct litmus_lock_ops; | ||
5 | |||
6 | /* Generic base struct for LITMUS^RT userspace semaphores. | ||
7 | * This structure should be embedded in protocol-specific semaphores. | ||
8 | */ | ||
9 | struct litmus_lock { | ||
10 | struct litmus_lock_ops *ops; | ||
11 | int type; | ||
12 | }; | ||
13 | |||
14 | struct 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 |
11 | struct 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 | */ |
64 | typedef void (*task_exit_t) (struct task_struct *); | 54 | typedef 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 | 58 | typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type); |
69 | */ | ||
70 | typedef 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 | */ | ||
76 | typedef 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 | */ | ||
81 | typedef 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 | ||
52 | config SRP | 52 | config 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 | |||
61 | config 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 | ||
72 | endmenu | 63 | endmenu |
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 | ||
126 | static long litmus_dummy_inherit_priority(struct pi_semaphore *sem, | 126 | static 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 | |||
132 | static long litmus_dummy_return_priority(struct pi_semaphore *sem) | ||
133 | { | ||
134 | return -ENOSYS; | ||
135 | } | ||
136 | |||
137 | static 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 | ||