diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-13 16:18:03 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-13 16:18:03 -0400 |
commit | c0667dc4894e913048cf8904f0ce9a79b481b556 (patch) | |
tree | 1803f6f9a6de45c949f57d1172aab4aa2546393b /litmus/locking.c | |
parent | 8eb55f8fa1a2c3854f0f77b9b8663178c0129f6c (diff) |
Move RSM and IKGLP imp. to own .c fileswip-ikglp
Also reformated code to be slightly more
standard coding practice compliant.
Diffstat (limited to 'litmus/locking.c')
-rw-r--r-- | litmus/locking.c | 276 |
1 files changed, 150 insertions, 126 deletions
diff --git a/litmus/locking.c b/litmus/locking.c index b2f4a205cd04..f78169dbbeef 100644 --- a/litmus/locking.c +++ b/litmus/locking.c | |||
@@ -22,6 +22,9 @@ struct fdso_ops generic_lock_ops = { | |||
22 | .destroy = destroy_generic_lock | 22 | .destroy = destroy_generic_lock |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static atomic_t lock_id_gen = ATOMIC_INIT(0); | ||
26 | |||
27 | |||
25 | static inline bool is_lock(struct od_table_entry* entry) | 28 | static inline bool is_lock(struct od_table_entry* entry) |
26 | { | 29 | { |
27 | return entry->class == &generic_lock_ops; | 30 | return entry->class == &generic_lock_ops; |
@@ -33,11 +36,6 @@ static inline struct litmus_lock* get_lock(struct od_table_entry* entry) | |||
33 | return (struct litmus_lock*) entry->obj->obj; | 36 | return (struct litmus_lock*) entry->obj->obj; |
34 | } | 37 | } |
35 | 38 | ||
36 | |||
37 | atomic_t lock_id_gen = ATOMIC_INIT(0); | ||
38 | //raw_spinlock_t rsm_global_lock; | ||
39 | |||
40 | |||
41 | static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user arg) | 39 | static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user arg) |
42 | { | 40 | { |
43 | struct litmus_lock* lock; | 41 | struct litmus_lock* lock; |
@@ -48,16 +46,11 @@ static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user ar | |||
48 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | 46 | #ifdef CONFIG_LITMUS_NESTED_LOCKING |
49 | lock->nest.lock = lock; | 47 | lock->nest.lock = lock; |
50 | lock->nest.hp_waiter_eff_prio = NULL; | 48 | lock->nest.hp_waiter_eff_prio = NULL; |
51 | 49 | ||
52 | INIT_BINHEAP_NODE(&lock->nest.hp_binheap_node); | 50 | INIT_BINHEAP_NODE(&lock->nest.hp_binheap_node); |
53 | WARN_ON(!(lock->nest.hp_waiter_ptr)); | 51 | WARN_ON(!(lock->nest.hp_waiter_ptr)); |
54 | |||
55 | lock->ident = atomic_inc_return(&lock_id_gen); | ||
56 | |||
57 | // if(lock->ident == 1) { | ||
58 | // raw_spin_lock_init(&rsm_global_lock); | ||
59 | // } | ||
60 | #endif | 52 | #endif |
53 | lock->ident = atomic_inc_return(&lock_id_gen); | ||
61 | *obj_ref = lock; | 54 | *obj_ref = lock; |
62 | } | 55 | } |
63 | return err; | 56 | return err; |
@@ -145,69 +138,86 @@ struct task_struct* __waitqueue_remove_first(wait_queue_head_t *wq) | |||
145 | return(t); | 138 | return(t); |
146 | } | 139 | } |
147 | 140 | ||
141 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
142 | |||
143 | void print_hp_waiters(struct binheap_node* n, int depth) | ||
144 | { | ||
145 | struct litmus_lock *l; | ||
146 | struct nested_info *nest; | ||
147 | char padding[81] = " "; | ||
148 | struct task_struct *hp = NULL; | ||
149 | struct task_struct *hp_eff = NULL; | ||
150 | struct task_struct *node_prio = NULL; | ||
151 | |||
152 | |||
153 | if(n == NULL) { | ||
154 | TRACE("+-> %p\n", NULL); | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | nest = binheap_entry(n, struct nested_info, hp_binheap_node); | ||
159 | l = nest->lock; | ||
160 | |||
161 | if(depth*2 <= 80) | ||
162 | padding[depth*2] = '\0'; | ||
163 | |||
164 | if(nest->hp_waiter_ptr && *(nest->hp_waiter_ptr)) { | ||
165 | hp = *(nest->hp_waiter_ptr); | ||
166 | |||
167 | if(tsk_rt(hp)->inh_task) { | ||
168 | hp_eff = tsk_rt(hp)->inh_task; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | node_prio = nest->hp_waiter_eff_prio; | ||
173 | |||
174 | TRACE("%s+-> %s/%d [waiter = %s/%d] [waiter's inh = %s/%d] (lock = %d)\n", | ||
175 | padding, | ||
176 | (node_prio) ? node_prio->comm : "nil", | ||
177 | (node_prio) ? node_prio->pid : -1, | ||
178 | (hp) ? hp->comm : "nil", | ||
179 | (hp) ? hp->pid : -1, | ||
180 | (hp_eff) ? hp_eff->comm : "nil", | ||
181 | (hp_eff) ? hp_eff->pid : -1, | ||
182 | l->ident); | ||
183 | |||
184 | if(n->left) print_hp_waiters(n->left, depth+1); | ||
185 | if(n->right) print_hp_waiters(n->right, depth+1); | ||
186 | } | ||
187 | #endif | ||
188 | |||
148 | 189 | ||
149 | #ifdef CONFIG_LITMUS_DGL_SUPPORT | 190 | #ifdef CONFIG_LITMUS_DGL_SUPPORT |
150 | 191 | ||
151 | void select_next_lock(dgl_wait_state_t* dgl_wait, struct litmus_lock* prev_lock) | 192 | void select_next_lock(dgl_wait_state_t* dgl_wait /*, struct litmus_lock* prev_lock*/) |
152 | { | 193 | { |
153 | // int i = dgl_wait->size - 1; | 194 | /* |
154 | 195 | We pick the next lock in reverse order. This causes inheritance propagation | |
155 | 196 | from locks received earlier to flow in the same direction as regular nested | |
197 | locking. This might make fine-grain DGL easier in the future. | ||
198 | */ | ||
199 | |||
156 | BUG_ON(tsk_rt(dgl_wait->task)->blocked_lock); | 200 | BUG_ON(tsk_rt(dgl_wait->task)->blocked_lock); |
157 | 201 | ||
158 | WARN_ON(dgl_wait->locks[dgl_wait->last_primary] != prev_lock); | 202 | //WARN_ON(dgl_wait->locks[dgl_wait->last_primary] != prev_lock); |
159 | // | 203 | |
160 | // // since dgl_wait->task->blocked_lock, all locks after prev_lock | 204 | // note reverse order |
161 | // // are already held. | ||
162 | // | ||
163 | // // find the lock after prev. | ||
164 | // if(prev_lock) { | ||
165 | // for(/**/; i >= 0; --i) { | ||
166 | // if(prev_lock == dgl_wait->locks[i]) { | ||
167 | // --i; | ||
168 | // break; | ||
169 | // } | ||
170 | // else { | ||
171 | // BUG_ON(!dgl_wait->locks[i]->ops->is_owner(dgl_wait->locks[i], dgl_wait->task)); | ||
172 | // } | ||
173 | // } | ||
174 | // } | ||
175 | |||
176 | for(dgl_wait->last_primary = dgl_wait->last_primary - 1; | 205 | for(dgl_wait->last_primary = dgl_wait->last_primary - 1; |
177 | dgl_wait->last_primary >= 0; | 206 | dgl_wait->last_primary >= 0; |
178 | --(dgl_wait->last_primary)){ | 207 | --(dgl_wait->last_primary)){ |
179 | if(!dgl_wait->locks[dgl_wait->last_primary]->ops->is_owner(dgl_wait->locks[dgl_wait->last_primary], dgl_wait->task)) { | 208 | if(!dgl_wait->locks[dgl_wait->last_primary]->ops->is_owner( |
180 | 209 | dgl_wait->locks[dgl_wait->last_primary], dgl_wait->task)) { | |
181 | tsk_rt(dgl_wait->task)->blocked_lock = dgl_wait->locks[dgl_wait->last_primary]; | 210 | |
211 | tsk_rt(dgl_wait->task)->blocked_lock = | ||
212 | dgl_wait->locks[dgl_wait->last_primary]; | ||
182 | mb(); | 213 | mb(); |
183 | 214 | ||
184 | TRACE_CUR("New blocked lock is %d\n", dgl_wait->locks[dgl_wait->last_primary]->ident); | 215 | TRACE_CUR("New blocked lock is %d\n", |
185 | 216 | dgl_wait->locks[dgl_wait->last_primary]->ident); | |
217 | |||
186 | break; | 218 | break; |
187 | } | 219 | } |
188 | } | 220 | } |
189 | |||
190 | // for(/**/; i >= 0; --i) { | ||
191 | // struct litmus_lock *l = dgl_wait->locks[i]; | ||
192 | // if(!l->ops->is_owner(l, dgl_wait->task)) { | ||
193 | // | ||
194 | // tsk_rt(dgl_wait->task)->blocked_lock = l; | ||
195 | // mb(); | ||
196 | // | ||
197 | // TRACE_CUR("New blocked lock is %d\n", l->ident); | ||
198 | // | ||
199 | // if(dgl_wait->last_primary >= 0) | ||
200 | // { | ||
201 | // TRACE_CUR("old meth = %d; new meth = %d\n", l->ident, dgl_wait->locks[dgl_wait->last_primary]->ident); | ||
202 | // WARN_ON(dgl_wait->locks[dgl_wait->last_primary] != l); | ||
203 | // } | ||
204 | // | ||
205 | // break; | ||
206 | // } | ||
207 | // else { | ||
208 | // TRACE_CUR("Lock %d is actually held!\n", l->ident); | ||
209 | // } | ||
210 | // } | ||
211 | } | 221 | } |
212 | 222 | ||
213 | int dgl_wake_up(wait_queue_t *wq_node, unsigned mode, int sync, void *key) | 223 | int dgl_wake_up(wait_queue_t *wq_node, unsigned mode, int sync, void *key) |
@@ -217,24 +227,26 @@ int dgl_wake_up(wait_queue_t *wq_node, unsigned mode, int sync, void *key) | |||
217 | return 1; | 227 | return 1; |
218 | } | 228 | } |
219 | 229 | ||
220 | void __waitqueue_dgl_remove_first(wait_queue_head_t *wq, dgl_wait_state_t** dgl_wait, struct task_struct **task) | 230 | void __waitqueue_dgl_remove_first(wait_queue_head_t *wq, |
231 | dgl_wait_state_t** dgl_wait, | ||
232 | struct task_struct **task) | ||
221 | { | 233 | { |
222 | wait_queue_t *q; | 234 | wait_queue_t *q; |
223 | 235 | ||
224 | *dgl_wait = NULL; | 236 | *dgl_wait = NULL; |
225 | *task = NULL; | 237 | *task = NULL; |
226 | 238 | ||
227 | if (waitqueue_active(wq)) { | 239 | if (waitqueue_active(wq)) { |
228 | q = list_entry(wq->task_list.next, | 240 | q = list_entry(wq->task_list.next, |
229 | wait_queue_t, task_list); | 241 | wait_queue_t, task_list); |
230 | 242 | ||
231 | if(q->func == dgl_wake_up) { | 243 | if(q->func == dgl_wake_up) { |
232 | *dgl_wait = (dgl_wait_state_t*) q->private; | 244 | *dgl_wait = (dgl_wait_state_t*) q->private; |
233 | } | 245 | } |
234 | else { | 246 | else { |
235 | *task = (struct task_struct*) q->private; | 247 | *task = (struct task_struct*) q->private; |
236 | } | 248 | } |
237 | 249 | ||
238 | __remove_wait_queue(wq, q); | 250 | __remove_wait_queue(wq, q); |
239 | } | 251 | } |
240 | } | 252 | } |
@@ -252,76 +264,76 @@ static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait) | |||
252 | int i; | 264 | int i; |
253 | unsigned long irqflags; //, dummyflags; | 265 | unsigned long irqflags; //, dummyflags; |
254 | raw_spinlock_t *dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task); | 266 | raw_spinlock_t *dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task); |
255 | 267 | ||
256 | BUG_ON(dgl_wait->task != current); | 268 | BUG_ON(dgl_wait->task != current); |
257 | 269 | ||
258 | raw_spin_lock_irqsave(dgl_lock, irqflags); | 270 | raw_spin_lock_irqsave(dgl_lock, irqflags); |
259 | 271 | ||
260 | 272 | ||
261 | dgl_wait->nr_remaining = dgl_wait->size; | 273 | dgl_wait->nr_remaining = dgl_wait->size; |
262 | //atomic_set(&dgl_wait->nr_remaining, dgl_wait->size); | 274 | |
263 | |||
264 | // try to acquire each lock. enqueue (non-blocking) if it is unavailable. | 275 | // try to acquire each lock. enqueue (non-blocking) if it is unavailable. |
265 | for(i = 0; i < dgl_wait->size; ++i) { | 276 | for(i = 0; i < dgl_wait->size; ++i) { |
266 | struct litmus_lock *l = dgl_wait->locks[i]; | 277 | struct litmus_lock *l = dgl_wait->locks[i]; |
267 | 278 | ||
268 | // dgl_lock() must set task state to TASK_UNINTERRUPTIBLE if task blocks. | 279 | // dgl_lock() must set task state to TASK_UNINTERRUPTIBLE if task blocks. |
269 | 280 | ||
270 | if(l->ops->dgl_lock(l, dgl_wait, &dgl_wait->wq_nodes[i])) { | 281 | if(l->ops->dgl_lock(l, dgl_wait, &dgl_wait->wq_nodes[i])) { |
271 | --(dgl_wait->nr_remaining); | 282 | --(dgl_wait->nr_remaining); |
272 | //atomic_dec(&dgl_wait->nr_remaining); | ||
273 | TRACE_CUR("Acquired lock %d immediatly.\n", l->ident); | 283 | TRACE_CUR("Acquired lock %d immediatly.\n", l->ident); |
274 | } | 284 | } |
275 | } | 285 | } |
276 | 286 | ||
277 | //if(atomic_read(&dgl_wait->nr_remaining) == 0) { | ||
278 | if(dgl_wait->nr_remaining == 0) { | 287 | if(dgl_wait->nr_remaining == 0) { |
279 | // acquired entire group immediatly | 288 | // acquired entire group immediatly |
280 | TRACE_CUR("Acquired all locks in DGL immediatly!\n"); | 289 | TRACE_CUR("Acquired all locks in DGL immediatly!\n"); |
281 | } | 290 | } |
282 | else { | 291 | else { |
292 | |||
293 | TRACE_CUR("As many as %d locks in DGL are pending. Suspending.\n", | ||
294 | dgl_wait->nr_remaining); | ||
283 | 295 | ||
284 | TRACE_CUR("As many as %d locks in DGL are pending. Suspending.\n", dgl_wait->nr_remaining); //atomic_read(&dgl_wait->nr_remaining)); | 296 | // note reverse order. see comments in select_next_lock for reason. |
285 | |||
286 | for(i = dgl_wait->size - 1; i >= 0; --i) { | 297 | for(i = dgl_wait->size - 1; i >= 0; --i) { |
287 | struct litmus_lock *l = dgl_wait->locks[i]; | 298 | struct litmus_lock *l = dgl_wait->locks[i]; |
288 | if(!l->ops->is_owner(l, dgl_wait->task)) { // double-check to be thread safe | 299 | if(!l->ops->is_owner(l, dgl_wait->task)) { // double-check to be thread safe |
289 | 300 | ||
290 | TRACE_CUR("Activating priority inheritance on lock %d\n", l->ident); | 301 | TRACE_CUR("Activating priority inheritance on lock %d\n", |
291 | 302 | l->ident); | |
303 | |||
292 | TS_DGL_LOCK_SUSPEND; | 304 | TS_DGL_LOCK_SUSPEND; |
293 | 305 | ||
294 | l->ops->enable_priority(l, dgl_wait); | 306 | l->ops->enable_priority(l, dgl_wait); |
295 | dgl_wait->last_primary = i; | 307 | dgl_wait->last_primary = i; |
296 | 308 | ||
297 | TRACE_CUR("Suspending for lock %d\n", l->ident); | 309 | TRACE_CUR("Suspending for lock %d\n", l->ident); |
298 | 310 | ||
299 | raw_spin_unlock_irqrestore(dgl_lock, irqflags); // free dgl_lock before suspending | 311 | raw_spin_unlock_irqrestore(dgl_lock, irqflags); // free dgl_lock before suspending |
300 | 312 | ||
301 | schedule(); // suspend!!! | 313 | schedule(); // suspend!!! |
302 | 314 | ||
303 | TS_DGL_LOCK_RESUME; | 315 | TS_DGL_LOCK_RESUME; |
304 | 316 | ||
305 | TRACE_CUR("Woken up from DGL suspension.\n"); | 317 | TRACE_CUR("Woken up from DGL suspension.\n"); |
306 | 318 | ||
307 | goto all_acquired; // we should hold all locks when we wake up. | 319 | goto all_acquired; // we should hold all locks when we wake up. |
308 | } | 320 | } |
309 | } | 321 | } |
310 | 322 | ||
311 | TRACE_CUR("Didn't have to suspend after all, but calling schedule() anyway.\n"); | 323 | TRACE_CUR("Didn't have to suspend after all, but calling schedule() anyway.\n"); |
312 | BUG(); | 324 | BUG(); |
313 | } | 325 | } |
314 | 326 | ||
315 | raw_spin_unlock_irqrestore(dgl_lock, irqflags); | 327 | raw_spin_unlock_irqrestore(dgl_lock, irqflags); |
316 | 328 | ||
317 | all_acquired: | 329 | all_acquired: |
318 | 330 | ||
319 | // FOR SANITY CHECK FOR TESTING | 331 | // FOR SANITY CHECK FOR TESTING |
320 | for(i = 0; i < dgl_wait->size; ++i) { | 332 | for(i = 0; i < dgl_wait->size; ++i) { |
321 | struct litmus_lock *l = dgl_wait->locks[i]; | 333 | struct litmus_lock *l = dgl_wait->locks[i]; |
322 | BUG_ON(!l->ops->is_owner(l, dgl_wait->task)); | 334 | BUG_ON(!l->ops->is_owner(l, dgl_wait->task)); |
323 | } | 335 | } |
324 | 336 | ||
325 | TRACE_CUR("Acquired entire DGL\n"); | 337 | TRACE_CUR("Acquired entire DGL\n"); |
326 | 338 | ||
327 | return 0; | 339 | return 0; |
@@ -330,7 +342,7 @@ all_acquired: | |||
330 | //static int supports_dgl(struct litmus_lock *l) | 342 | //static int supports_dgl(struct litmus_lock *l) |
331 | //{ | 343 | //{ |
332 | // struct litmus_lock_ops* ops = l->ops; | 344 | // struct litmus_lock_ops* ops = l->ops; |
333 | // | 345 | // |
334 | // return (ops->dgl_lock && | 346 | // return (ops->dgl_lock && |
335 | // ops->is_owner && | 347 | // ops->is_owner && |
336 | // ops->enable_priority); | 348 | // ops->enable_priority); |
@@ -342,23 +354,23 @@ asmlinkage long sys_litmus_dgl_lock(void* __user usr_dgl_ods, int dgl_size) | |||
342 | long err = -EINVAL; | 354 | long err = -EINVAL; |
343 | int dgl_ods[MAX_DGL_SIZE]; | 355 | int dgl_ods[MAX_DGL_SIZE]; |
344 | int i; | 356 | int i; |
345 | 357 | ||
346 | dgl_wait_state_t dgl_wait_state; // lives on the stack until all resources in DGL are held. | 358 | dgl_wait_state_t dgl_wait_state; // lives on the stack until all resources in DGL are held. |
347 | 359 | ||
348 | if(dgl_size > MAX_DGL_SIZE || dgl_size < 1) | 360 | if(dgl_size > MAX_DGL_SIZE || dgl_size < 1) |
349 | goto out; | 361 | goto out; |
350 | 362 | ||
351 | if(!access_ok(VERIFY_READ, usr_dgl_ods, dgl_size*(sizeof(int)))) | 363 | if(!access_ok(VERIFY_READ, usr_dgl_ods, dgl_size*(sizeof(int)))) |
352 | goto out; | 364 | goto out; |
353 | 365 | ||
354 | if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int)))) | 366 | if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int)))) |
355 | goto out; | 367 | goto out; |
356 | 368 | ||
357 | if (!is_realtime(t)) { | 369 | if (!is_realtime(t)) { |
358 | err = -EPERM; | 370 | err = -EPERM; |
359 | goto out; | 371 | goto out; |
360 | } | 372 | } |
361 | 373 | ||
362 | for(i = 0; i < dgl_size; ++i) { | 374 | for(i = 0; i < dgl_size; ++i) { |
363 | struct od_table_entry *entry = get_entry_for_od(dgl_ods[i]); | 375 | struct od_table_entry *entry = get_entry_for_od(dgl_ods[i]); |
364 | if(entry && is_lock(entry)) { | 376 | if(entry && is_lock(entry)) { |
@@ -374,17 +386,17 @@ asmlinkage long sys_litmus_dgl_lock(void* __user usr_dgl_ods, int dgl_size) | |||
374 | goto out; | 386 | goto out; |
375 | } | 387 | } |
376 | } | 388 | } |
377 | 389 | ||
378 | dgl_wait_state.task = t; | 390 | dgl_wait_state.task = t; |
379 | dgl_wait_state.size = dgl_size; | 391 | dgl_wait_state.size = dgl_size; |
380 | 392 | ||
381 | TS_DGL_LOCK_START; | 393 | TS_DGL_LOCK_START; |
382 | err = do_litmus_dgl_lock(&dgl_wait_state); | 394 | err = do_litmus_dgl_lock(&dgl_wait_state); |
383 | 395 | ||
384 | /* Note: task my have been suspended or preempted in between! Take | 396 | /* Note: task my have been suspended or preempted in between! Take |
385 | * this into account when computing overheads. */ | 397 | * this into account when computing overheads. */ |
386 | TS_DGL_LOCK_END; | 398 | TS_DGL_LOCK_END; |
387 | 399 | ||
388 | out: | 400 | out: |
389 | return err; | 401 | return err; |
390 | } | 402 | } |
@@ -393,26 +405,26 @@ static long do_litmus_dgl_unlock(struct litmus_lock* dgl_locks[], int dgl_size) | |||
393 | { | 405 | { |
394 | int i; | 406 | int i; |
395 | long err = 0; | 407 | long err = 0; |
396 | 408 | ||
397 | TRACE_CUR("Unlocking a DGL of %d size\n", dgl_size); | 409 | TRACE_CUR("Unlocking a DGL of %d size\n", dgl_size); |
398 | 410 | ||
399 | for(i = dgl_size - 1; i >= 0; --i) { // unlock in reverse order | 411 | for(i = dgl_size - 1; i >= 0; --i) { // unlock in reverse order |
400 | 412 | ||
401 | struct litmus_lock *l = dgl_locks[i]; | 413 | struct litmus_lock *l = dgl_locks[i]; |
402 | long tmp_err; | 414 | long tmp_err; |
403 | 415 | ||
404 | TRACE_CUR("Unlocking lock %d of DGL.\n", l->ident); | 416 | TRACE_CUR("Unlocking lock %d of DGL.\n", l->ident); |
405 | 417 | ||
406 | tmp_err = l->ops->unlock(l); | 418 | tmp_err = l->ops->unlock(l); |
407 | 419 | ||
408 | if(tmp_err) { | 420 | if(tmp_err) { |
409 | TRACE_CUR("There was an error unlocking %d: %d.\n", l->ident, tmp_err); | 421 | TRACE_CUR("There was an error unlocking %d: %d.\n", l->ident, tmp_err); |
410 | err = tmp_err; | 422 | err = tmp_err; |
411 | } | 423 | } |
412 | } | 424 | } |
413 | 425 | ||
414 | TRACE_CUR("DGL unlocked. err = %d\n", err); | 426 | TRACE_CUR("DGL unlocked. err = %d\n", err); |
415 | 427 | ||
416 | return err; | 428 | return err; |
417 | } | 429 | } |
418 | 430 | ||
@@ -422,18 +434,18 @@ asmlinkage long sys_litmus_dgl_unlock(void* __user usr_dgl_ods, int dgl_size) | |||
422 | int dgl_ods[MAX_DGL_SIZE]; | 434 | int dgl_ods[MAX_DGL_SIZE]; |
423 | struct od_table_entry* entry; | 435 | struct od_table_entry* entry; |
424 | int i; | 436 | int i; |
425 | 437 | ||
426 | struct litmus_lock* dgl_locks[MAX_DGL_SIZE]; | 438 | struct litmus_lock* dgl_locks[MAX_DGL_SIZE]; |
427 | 439 | ||
428 | if(dgl_size > MAX_DGL_SIZE || dgl_size < 1) | 440 | if(dgl_size > MAX_DGL_SIZE || dgl_size < 1) |
429 | goto out; | 441 | goto out; |
430 | 442 | ||
431 | if(!access_ok(VERIFY_READ, usr_dgl_ods, dgl_size*(sizeof(int)))) | 443 | if(!access_ok(VERIFY_READ, usr_dgl_ods, dgl_size*(sizeof(int)))) |
432 | goto out; | 444 | goto out; |
433 | 445 | ||
434 | if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int)))) | 446 | if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int)))) |
435 | goto out; | 447 | goto out; |
436 | 448 | ||
437 | for(i = 0; i < dgl_size; ++i) { | 449 | for(i = 0; i < dgl_size; ++i) { |
438 | entry = get_entry_for_od(dgl_ods[i]); | 450 | entry = get_entry_for_od(dgl_ods[i]); |
439 | if(entry && is_lock(entry)) { | 451 | if(entry && is_lock(entry)) { |
@@ -449,16 +461,28 @@ asmlinkage long sys_litmus_dgl_unlock(void* __user usr_dgl_ods, int dgl_size) | |||
449 | goto out; | 461 | goto out; |
450 | } | 462 | } |
451 | } | 463 | } |
452 | 464 | ||
453 | TS_DGL_UNLOCK_START; | 465 | TS_DGL_UNLOCK_START; |
454 | err = do_litmus_dgl_unlock(dgl_locks, dgl_size); | 466 | err = do_litmus_dgl_unlock(dgl_locks, dgl_size); |
455 | 467 | ||
456 | /* Note: task my have been suspended or preempted in between! Take | 468 | /* Note: task my have been suspended or preempted in between! Take |
457 | * this into account when computing overheads. */ | 469 | * this into account when computing overheads. */ |
458 | TS_DGL_UNLOCK_END; | 470 | TS_DGL_UNLOCK_END; |
459 | 471 | ||
460 | out: | 472 | out: |
461 | return err; | 473 | return err; |
474 | } | ||
475 | |||
476 | #else | ||
477 | |||
478 | asmlinkage long sys_litmus_dgl_lock(void* __user usr_dgl_ods, int dgl_size) | ||
479 | { | ||
480 | return -ENOSYS; | ||
481 | } | ||
482 | |||
483 | asmlinkage long sys_litmus_dgl_unlock(void* __user usr_dgl_ods, int dgl_size) | ||
484 | { | ||
485 | return -ENOSYS; | ||
462 | } | 486 | } |
463 | 487 | ||
464 | #endif | 488 | #endif |