diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-04-07 17:05:57 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-05-01 11:44:50 -0400 |
commit | 673d40302d2f9f205d80599df1f7dc41c874a74b (patch) | |
tree | a487855aeb54b39b5fc0d37c4b2b95124f611806 | |
parent | 8b36e6fb97b15ad5953777e621bec9f3191267a9 (diff) |
SRP: record owner in semaphores
-rw-r--r-- | litmus/litmus_sem.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/litmus/litmus_sem.c b/litmus/litmus_sem.c index 486fb3bef7..8151087c1a 100644 --- a/litmus/litmus_sem.c +++ b/litmus/litmus_sem.c | |||
@@ -319,21 +319,35 @@ DEFINE_PER_CPU(struct srp, srp); | |||
319 | 319 | ||
320 | #define system_ceiling(srp) list2prio(srp->ceiling.next) | 320 | #define system_ceiling(srp) list2prio(srp->ceiling.next) |
321 | 321 | ||
322 | |||
323 | #define UNDEF_SEM -2 | ||
324 | |||
325 | |||
326 | /* struct for uniprocessor SRP "semaphore" */ | ||
327 | struct srp_semaphore { | ||
328 | struct srp_priority ceiling; | ||
329 | struct task_struct* owner; | ||
330 | int cpu; /* cpu associated with this "semaphore" and resource */ | ||
331 | }; | ||
332 | |||
333 | #define ceiling2sem(c) container_of(c, struct srp_semaphore, ceiling) | ||
334 | |||
322 | static int srp_exceeds_ceiling(struct task_struct* first, | 335 | static int srp_exceeds_ceiling(struct task_struct* first, |
323 | struct srp* srp) | 336 | struct srp* srp) |
324 | { | 337 | { |
325 | return list_empty(&srp->ceiling) || | 338 | return list_empty(&srp->ceiling) || |
326 | get_rt_period(first) < system_ceiling(srp)->period || | 339 | get_rt_period(first) < system_ceiling(srp)->period || |
327 | (get_rt_period(first) == system_ceiling(srp)->period && | 340 | (get_rt_period(first) == system_ceiling(srp)->period && |
328 | first->pid < system_ceiling(srp)->pid); | 341 | first->pid < system_ceiling(srp)->pid) || |
342 | ceiling2sem(system_ceiling(srp))->owner == first; | ||
329 | } | 343 | } |
330 | 344 | ||
331 | static void srp_add_prio(struct srp* srp, struct srp_priority* prio) | 345 | static void srp_add_prio(struct srp* srp, struct srp_priority* prio) |
332 | { | 346 | { |
333 | struct list_head *pos; | 347 | struct list_head *pos; |
334 | if (in_list(&prio->list)) { | 348 | if (in_list(&prio->list)) { |
335 | TRACE_CUR("WARNING: SRP violation detected, prio is already in " | 349 | printk(KERN_CRIT "WARNING: SRP violation detected, prio is already in " |
336 | "ceiling list!\n"); | 350 | "ceiling list!\n"); |
337 | return; | 351 | return; |
338 | } | 352 | } |
339 | list_for_each(pos, &srp->ceiling) | 353 | list_for_each(pos, &srp->ceiling) |
@@ -345,16 +359,6 @@ static void srp_add_prio(struct srp* srp, struct srp_priority* prio) | |||
345 | list_add_tail(&prio->list, &srp->ceiling); | 359 | list_add_tail(&prio->list, &srp->ceiling); |
346 | } | 360 | } |
347 | 361 | ||
348 | #define UNDEF_SEM -2 | ||
349 | |||
350 | |||
351 | /* struct for uniprocessor SRP "semaphore" */ | ||
352 | struct srp_semaphore { | ||
353 | struct srp_priority ceiling; | ||
354 | int cpu; /* cpu associated with this "semaphore" and resource */ | ||
355 | int claimed; /* is the resource claimed (ceiling should be used)? */ | ||
356 | }; | ||
357 | |||
358 | 362 | ||
359 | static void* create_srp_semaphore(void) | 363 | static void* create_srp_semaphore(void) |
360 | { | 364 | { |
@@ -366,8 +370,8 @@ static void* create_srp_semaphore(void) | |||
366 | 370 | ||
367 | INIT_LIST_HEAD(&sem->ceiling.list); | 371 | INIT_LIST_HEAD(&sem->ceiling.list); |
368 | sem->ceiling.period = 0; | 372 | sem->ceiling.period = 0; |
369 | sem->claimed = 0; | ||
370 | sem->cpu = UNDEF_SEM; | 373 | sem->cpu = UNDEF_SEM; |
374 | sem->owner = NULL; | ||
371 | atomic_inc(&srp_objects_in_use); | 375 | atomic_inc(&srp_objects_in_use); |
372 | return sem; | 376 | return sem; |
373 | } | 377 | } |
@@ -430,22 +434,20 @@ __initcall(srp_sema_boot_init); | |||
430 | 434 | ||
431 | void do_srp_down(struct srp_semaphore* sem) | 435 | void do_srp_down(struct srp_semaphore* sem) |
432 | { | 436 | { |
433 | /* claim... */ | 437 | /* Update ceiling. */ |
434 | sem->claimed = 1; | ||
435 | /* ...and update ceiling */ | ||
436 | srp_add_prio(&__get_cpu_var(srp), &sem->ceiling); | 438 | srp_add_prio(&__get_cpu_var(srp), &sem->ceiling); |
439 | WARN_ON(sem->owner != NULL); | ||
440 | sem->owner = current; | ||
437 | } | 441 | } |
438 | 442 | ||
439 | void do_srp_up(struct srp_semaphore* sem) | 443 | void do_srp_up(struct srp_semaphore* sem) |
440 | { | 444 | { |
441 | sem->claimed = 0; | ||
442 | |||
443 | /* Determine new system priority ceiling for this CPU. */ | 445 | /* Determine new system priority ceiling for this CPU. */ |
444 | if (in_list(&sem->ceiling.list)) | 446 | WARN_ON(!in_list(&sem->ceiling.list)); |
447 | if (!in_list(&sem->ceiling.list)) | ||
445 | list_del(&sem->ceiling.list); | 448 | list_del(&sem->ceiling.list); |
446 | else | 449 | |
447 | TRACE_CUR("WARNING: SRP violation detected, prio not in ceiling" | 450 | sem->owner = NULL; |
448 | " list!\n"); | ||
449 | 451 | ||
450 | /* Wake tasks on this CPU, if they exceed current ceiling. */ | 452 | /* Wake tasks on this CPU, if they exceed current ceiling. */ |
451 | wake_up_all(&__get_cpu_var(srp).ceiling_blocked); | 453 | wake_up_all(&__get_cpu_var(srp).ceiling_blocked); |