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); |
