aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2010-07-12 15:16:04 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2010-08-03 12:42:59 -0400
commita0c6241d44317b55c790131d3215d52061ce4add (patch)
treec41b0ace72ea5829de6a0ac11eb06af4acd7bb67
parent25b7346d1cf87d2eeb86f4d3a584b04aca5509a0 (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.c80
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
23static void* create_fmlp_semaphore(void) 23static 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
60struct wq_pair { 64struct 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
65static int rt_pi_wake_up(wait_queue_t *wait, unsigned mode, int sync, 69static 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 */
87int edf_set_hp_task(struct pi_semaphore *sem) 91int 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 */
109int edf_set_hp_cpu_task(struct pi_semaphore *sem, int cpu) 113int 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
131static int do_fmlp_down(struct pi_semaphore* sem) 135static 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
194static void do_fmlp_up(struct pi_semaphore* sem) 198static 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
210asmlinkage long sys_fmlp_down(int sem_od) 214asmlinkage 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)
233asmlinkage long sys_fmlp_up(int sem_od) 237asmlinkage 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;