diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2010-07-12 15:16:04 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2010-08-03 12:42:59 -0400 |
commit | a0c6241d44317b55c790131d3215d52061ce4add (patch) | |
tree | c41b0ace72ea5829de6a0ac11eb06af4acd7bb67 | |
parent | 25b7346d1cf87d2eeb86f4d3a584b04aca5509a0 (diff) |
Update FMLP to use revised fmlp_semaphore.
7ef1e106db5a061682028fdc4d8ffd131729868a refactored pi_semaphore into two
structs: pi_semaphore and fmlp_semaphore. fmlp_semaphore encapsulates
pi_semaphore as its first field, pi. This patch updates the FMLP-Long
implementation to use the refactored structs.
-rw-r--r-- | litmus/fmlp.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/litmus/fmlp.c b/litmus/fmlp.c index 03fa7358d5eb..de46e626f43f 100644 --- a/litmus/fmlp.c +++ b/litmus/fmlp.c | |||
@@ -22,19 +22,23 @@ | |||
22 | 22 | ||
23 | static void* create_fmlp_semaphore(void) | 23 | static void* create_fmlp_semaphore(void) |
24 | { | 24 | { |
25 | struct pi_semaphore* sem; | 25 | struct fmlp_semaphore* sem; |
26 | int i; | 26 | int i; |
27 | 27 | ||
28 | sem = kmalloc(sizeof(*sem), GFP_KERNEL); | 28 | sem = kmalloc(sizeof(*sem), GFP_KERNEL); |
29 | if (!sem) | 29 | if (!sem) |
30 | return NULL; | 30 | return NULL; |
31 | atomic_set(&sem->count, 1); | 31 | atomic_set(&sem->pi.count, 1); |
32 | sem->sleepers = 0; | 32 | sem->pi.sleepers = 0; |
33 | init_waitqueue_head(&sem->wait); | 33 | init_waitqueue_head(&sem->pi.wait); |
34 | sem->hp.task = NULL; | 34 | sem->pi.hp.task = NULL; |
35 | sem->holder = NULL; | 35 | sem->holder = NULL; |
36 | for (i = 0; i < NR_CPUS; i++) | 36 | for (i = 0; i < NR_CPUS; i++) |
37 | sem->hp.cpu_task[i] = NULL; | 37 | sem->pi.hp.cpu_task[i] = NULL; |
38 | |||
39 | sem->pi.stack_node.inh_task = NULL; | ||
40 | INIT_LIST_HEAD(&sem->pi.stack_node.list); | ||
41 | |||
38 | return sem; | 42 | return sem; |
39 | } | 43 | } |
40 | 44 | ||
@@ -59,7 +63,7 @@ struct fdso_ops fmlp_sem_ops = { | |||
59 | 63 | ||
60 | struct wq_pair { | 64 | struct wq_pair { |
61 | struct task_struct* tsk; | 65 | struct task_struct* tsk; |
62 | struct pi_semaphore* sem; | 66 | struct fmlp_semaphore* sem; |
63 | }; | 67 | }; |
64 | 68 | ||
65 | static int rt_pi_wake_up(wait_queue_t *wait, unsigned mode, int sync, | 69 | static int rt_pi_wake_up(wait_queue_t *wait, unsigned mode, int sync, |
@@ -67,7 +71,7 @@ static int rt_pi_wake_up(wait_queue_t *wait, unsigned mode, int sync, | |||
67 | { | 71 | { |
68 | struct wq_pair* wqp = (struct wq_pair*) wait->private; | 72 | struct wq_pair* wqp = (struct wq_pair*) wait->private; |
69 | set_rt_flags(wqp->tsk, RT_F_EXIT_SEM); | 73 | set_rt_flags(wqp->tsk, RT_F_EXIT_SEM); |
70 | litmus->inherit_priority(wqp->sem, wqp->tsk); | 74 | litmus->fmlp_inherit_priority(to_pi(wqp->sem), wqp->tsk); |
71 | TRACE_TASK(wqp->tsk, | 75 | TRACE_TASK(wqp->tsk, |
72 | "woken up by rt_pi_wake_up() (RT_F_SEM_EXIT, PI)\n"); | 76 | "woken up by rt_pi_wake_up() (RT_F_SEM_EXIT, PI)\n"); |
73 | /* point to task for default_wake_function() */ | 77 | /* point to task for default_wake_function() */ |
@@ -84,21 +88,21 @@ static int rt_pi_wake_up(wait_queue_t *wait, unsigned mode, int sync, | |||
84 | } | 88 | } |
85 | 89 | ||
86 | /* caller is responsible for locking */ | 90 | /* caller is responsible for locking */ |
87 | int edf_set_hp_task(struct pi_semaphore *sem) | 91 | int edf_set_hp_task(struct fmlp_semaphore *sem) |
88 | { | 92 | { |
89 | struct list_head *tmp, *next; | 93 | struct list_head *tmp, *next; |
90 | struct task_struct *queued; | 94 | struct task_struct *queued; |
91 | int ret = 0; | 95 | int ret = 0; |
92 | 96 | ||
93 | sem->hp.task = NULL; | 97 | sem->pi.hp.task = NULL; |
94 | list_for_each_safe(tmp, next, &sem->wait.task_list) { | 98 | list_for_each_safe(tmp, next, &sem->pi.wait.task_list) { |
95 | queued = ((struct wq_pair*) | 99 | queued = ((struct wq_pair*) |
96 | list_entry(tmp, wait_queue_t, | 100 | list_entry(tmp, wait_queue_t, |
97 | task_list)->private)->tsk; | 101 | task_list)->private)->tsk; |
98 | 102 | ||
99 | /* Compare task prios, find high prio task. */ | 103 | /* Compare task prios, find high prio task. */ |
100 | if (edf_higher_prio(queued, sem->hp.task)) { | 104 | if (edf_higher_prio(queued, sem->pi.hp.task)) { |
101 | sem->hp.task = queued; | 105 | sem->pi.hp.task = queued; |
102 | ret = 1; | 106 | ret = 1; |
103 | } | 107 | } |
104 | } | 108 | } |
@@ -106,29 +110,29 @@ int edf_set_hp_task(struct pi_semaphore *sem) | |||
106 | } | 110 | } |
107 | 111 | ||
108 | /* caller is responsible for locking */ | 112 | /* caller is responsible for locking */ |
109 | int edf_set_hp_cpu_task(struct pi_semaphore *sem, int cpu) | 113 | int edf_set_hp_cpu_task(struct fmlp_semaphore *sem, int cpu) |
110 | { | 114 | { |
111 | struct list_head *tmp, *next; | 115 | struct list_head *tmp, *next; |
112 | struct task_struct *queued; | 116 | struct task_struct *queued; |
113 | int ret = 0; | 117 | int ret = 0; |
114 | 118 | ||
115 | sem->hp.cpu_task[cpu] = NULL; | 119 | sem->pi.hp.cpu_task[cpu] = NULL; |
116 | list_for_each_safe(tmp, next, &sem->wait.task_list) { | 120 | list_for_each_safe(tmp, next, &sem->pi.wait.task_list) { |
117 | queued = ((struct wq_pair*) | 121 | queued = ((struct wq_pair*) |
118 | list_entry(tmp, wait_queue_t, | 122 | list_entry(tmp, wait_queue_t, |
119 | task_list)->private)->tsk; | 123 | task_list)->private)->tsk; |
120 | 124 | ||
121 | /* Compare task prios, find high prio task. */ | 125 | /* Compare task prios, find high prio task. */ |
122 | if (get_partition(queued) == cpu && | 126 | if (get_partition(queued) == cpu && |
123 | edf_higher_prio(queued, sem->hp.cpu_task[cpu])) { | 127 | edf_higher_prio(queued, sem->pi.hp.cpu_task[cpu])) { |
124 | sem->hp.cpu_task[cpu] = queued; | 128 | sem->pi.hp.cpu_task[cpu] = queued; |
125 | ret = 1; | 129 | ret = 1; |
126 | } | 130 | } |
127 | } | 131 | } |
128 | return ret; | 132 | return ret; |
129 | } | 133 | } |
130 | 134 | ||
131 | static int do_fmlp_down(struct pi_semaphore* sem) | 135 | static int do_fmlp_down(struct fmlp_semaphore* sem) |
132 | { | 136 | { |
133 | unsigned long flags; | 137 | unsigned long flags; |
134 | struct task_struct *tsk = current; | 138 | struct task_struct *tsk = current; |
@@ -142,19 +146,19 @@ static int do_fmlp_down(struct pi_semaphore* sem) | |||
142 | 146 | ||
143 | pair.tsk = tsk; | 147 | pair.tsk = tsk; |
144 | pair.sem = sem; | 148 | pair.sem = sem; |
145 | spin_lock_irqsave(&sem->wait.lock, flags); | 149 | spin_lock_irqsave(&sem->pi.wait.lock, flags); |
146 | 150 | ||
147 | if (atomic_dec_return(&sem->count) < 0 || | 151 | if (atomic_dec_return(&sem->pi.count) < 0 || |
148 | waitqueue_active(&sem->wait)) { | 152 | waitqueue_active(&sem->pi.wait)) { |
149 | /* we need to suspend */ | 153 | /* we need to suspend */ |
150 | tsk->state = TASK_UNINTERRUPTIBLE; | 154 | tsk->state = TASK_UNINTERRUPTIBLE; |
151 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | 155 | add_wait_queue_exclusive_locked(&sem->pi.wait, &wait); |
152 | 156 | ||
153 | TRACE_CUR("suspends on PI lock %p\n", sem); | 157 | TRACE_CUR("suspends on PI lock %p\n", sem); |
154 | litmus->pi_block(sem, tsk); | 158 | litmus->fmlp_pi_block(to_pi(sem), tsk); |
155 | 159 | ||
156 | /* release lock before sleeping */ | 160 | /* release lock before sleeping */ |
157 | spin_unlock_irqrestore(&sem->wait.lock, flags); | 161 | spin_unlock_irqrestore(&sem->pi.wait.lock, flags); |
158 | 162 | ||
159 | TS_PI_DOWN_END; | 163 | TS_PI_DOWN_END; |
160 | preempt_enable_no_resched(); | 164 | preempt_enable_no_resched(); |
@@ -172,7 +176,7 @@ static int do_fmlp_down(struct pi_semaphore* sem) | |||
172 | /* try_to_wake_up() set our state to TASK_RUNNING, | 176 | /* try_to_wake_up() set our state to TASK_RUNNING, |
173 | * all we need to do is to remove our wait queue entry | 177 | * all we need to do is to remove our wait queue entry |
174 | */ | 178 | */ |
175 | remove_wait_queue(&sem->wait, &wait); | 179 | remove_wait_queue(&sem->pi.wait, &wait); |
176 | } else { | 180 | } else { |
177 | /* no priority inheritance necessary, since there are no queued | 181 | /* no priority inheritance necessary, since there are no queued |
178 | * tasks. | 182 | * tasks. |
@@ -182,35 +186,35 @@ static int do_fmlp_down(struct pi_semaphore* sem) | |||
182 | sem->holder = tsk; | 186 | sem->holder = tsk; |
183 | 187 | ||
184 | /* don't know if we're global or partitioned. */ | 188 | /* don't know if we're global or partitioned. */ |
185 | sem->hp.task = tsk; | 189 | sem->pi.hp.task = tsk; |
186 | sem->hp.cpu_task[get_partition(tsk)] = tsk; | 190 | sem->pi.hp.cpu_task[get_partition(tsk)] = tsk; |
187 | 191 | ||
188 | litmus->inherit_priority(sem, tsk); | 192 | litmus->fmlp_inherit_priority(to_pi(sem), tsk); |
189 | spin_unlock_irqrestore(&sem->wait.lock, flags); | 193 | spin_unlock_irqrestore(&sem->pi.wait.lock, flags); |
190 | } | 194 | } |
191 | return suspended; | 195 | return suspended; |
192 | } | 196 | } |
193 | 197 | ||
194 | static void do_fmlp_up(struct pi_semaphore* sem) | 198 | static void do_fmlp_up(struct fmlp_semaphore* sem) |
195 | { | 199 | { |
196 | unsigned long flags; | 200 | unsigned long flags; |
197 | 201 | ||
198 | spin_lock_irqsave(&sem->wait.lock, flags); | 202 | spin_lock_irqsave(&sem->pi.wait.lock, flags); |
199 | 203 | ||
200 | TRACE_CUR("releases PI lock %p\n", sem); | 204 | TRACE_CUR("releases PI lock %p\n", sem); |
201 | litmus->return_priority(sem); | 205 | litmus->fmlp_return_priority(to_pi(sem)); |
202 | sem->holder = NULL; | 206 | sem->holder = NULL; |
203 | if (atomic_inc_return(&sem->count) < 1) | 207 | if (atomic_inc_return(&sem->pi.count) < 1) |
204 | /* there is a task queued */ | 208 | /* there is a task queued */ |
205 | wake_up_locked(&sem->wait); | 209 | wake_up_locked(&sem->pi.wait); |
206 | 210 | ||
207 | spin_unlock_irqrestore(&sem->wait.lock, flags); | 211 | spin_unlock_irqrestore(&sem->pi.wait.lock, flags); |
208 | } | 212 | } |
209 | 213 | ||
210 | asmlinkage long sys_fmlp_down(int sem_od) | 214 | asmlinkage long sys_fmlp_down(int sem_od) |
211 | { | 215 | { |
212 | long ret = 0; | 216 | long ret = 0; |
213 | struct pi_semaphore * sem; | 217 | struct fmlp_semaphore * sem; |
214 | int suspended = 0; | 218 | int suspended = 0; |
215 | 219 | ||
216 | preempt_disable(); | 220 | preempt_disable(); |
@@ -233,7 +237,7 @@ asmlinkage long sys_fmlp_down(int sem_od) | |||
233 | asmlinkage long sys_fmlp_up(int sem_od) | 237 | asmlinkage long sys_fmlp_up(int sem_od) |
234 | { | 238 | { |
235 | long ret = 0; | 239 | long ret = 0; |
236 | struct pi_semaphore * sem; | 240 | struct fmlp_semaphore * sem; |
237 | 241 | ||
238 | preempt_disable(); | 242 | preempt_disable(); |
239 | TS_PI_UP_START; | 243 | TS_PI_UP_START; |