diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-09-30 21:36:51 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-09-30 21:36:51 -0400 |
commit | 3cbebe44aefbb312b004c7d428748e98dfa18e41 (patch) | |
tree | 271722b3de44df303bd8c4bd0511a4d86b0b33d6 /litmus | |
parent | b0466ecb422692bd0d30764075af834101849bd2 (diff) |
Bug fix for cancel events
Diffstat (limited to 'litmus')
-rw-r--r-- | litmus/event_group.c | 45 | ||||
-rw-r--r-- | litmus/sched_mc_ce.c | 2 |
2 files changed, 24 insertions, 23 deletions
diff --git a/litmus/event_group.c b/litmus/event_group.c index a130a68c731a..daf964fbb8cc 100644 --- a/litmus/event_group.c +++ b/litmus/event_group.c | |||
@@ -203,39 +203,39 @@ void add_event(struct event_group *group, struct rt_event *e, lt_t fire) | |||
203 | */ | 203 | */ |
204 | void cancel_event(struct rt_event *e) | 204 | void cancel_event(struct rt_event *e) |
205 | { | 205 | { |
206 | struct list_head *swap = NULL; | 206 | struct rt_event *swap; |
207 | struct rt_event *swappy; | ||
208 | struct event_list *tmp; | 207 | struct event_list *tmp; |
209 | struct event_group *group = e->_event_group; | 208 | struct event_group *group = e->_event_group; |
210 | 209 | ||
211 | if (e->list.next != &e->list) { | 210 | VTRACE("Canceling event 0x%p with priority %d\n", e, e->prio); |
212 | raw_spin_lock(&group->queue_lock); | 211 | if (!group) return; |
213 | VTRACE("Canceling event 0x%p with priority %d\n", e, e->prio); | 212 | |
213 | /* If our event_list contains any events, it is in use */ | ||
214 | raw_spin_lock(&group->queue_lock); | ||
215 | if (!list_empty(&e->event_list->events)) { | ||
214 | 216 | ||
215 | /* If somebody else is hooked up to our event list, swap | 217 | /* If our event_list contains events, we are the first element |
216 | * with their event list and leave our old event list | 218 | * in that list. If there is anyone after us in the list, then |
217 | * to execute. | 219 | * swap our list with theirs to that the event_list can still |
220 | * trigger the queued events. | ||
218 | */ | 221 | */ |
219 | if (!list_empty(&e->list)) { | 222 | if (!list_is_singular(&e->list)) { |
220 | swap = (e->list.next == &e->event_list->events) ? | 223 | swap = list_entry(e->list.next, struct rt_event, list); |
221 | (e->list.prev == &e->event_list->events) ? | 224 | VTRACE("Swapping with event 0x%p of priority %d\n", |
222 | NULL : e->list.prev : e->list.next; | 225 | swap, swap->prio); |
223 | list_del_init(&e->list); | 226 | |
224 | } | 227 | tmp = swap->event_list; |
225 | if (swap) { | 228 | swap->event_list = e->event_list; |
226 | swappy = list_entry(swap, struct rt_event, list); | ||
227 | tmp = swappy->event_list; | ||
228 | swappy->event_list = e->event_list; | ||
229 | e->event_list = tmp; | 229 | e->event_list = tmp; |
230 | VTRACE("Swapping with event 0x%p", swappy); | ||
231 | } | 230 | } |
232 | 231 | ||
232 | /* Disable the event_list */ | ||
233 | hrtimer_try_to_cancel(&e->event_list->timer); | 233 | hrtimer_try_to_cancel(&e->event_list->timer); |
234 | list_del_init(&e->event_list->list); | 234 | list_del_init(&e->event_list->list); |
235 | e->_event_group = NULL; | ||
236 | |||
237 | raw_spin_unlock(&group->queue_lock); | ||
238 | } | 235 | } |
236 | list_del_init(&e->list); | ||
237 | raw_spin_unlock(&group->queue_lock); | ||
238 | e->_event_group = NULL; | ||
239 | } | 239 | } |
240 | 240 | ||
241 | struct kmem_cache *event_list_cache; | 241 | struct kmem_cache *event_list_cache; |
@@ -261,6 +261,7 @@ void init_event(struct rt_event *e, int prio, fire_event_t function, | |||
261 | e->prio = prio; | 261 | e->prio = prio; |
262 | e->function = function; | 262 | e->function = function; |
263 | e->event_list = el; | 263 | e->event_list = el; |
264 | e->_event_group = NULL; | ||
264 | INIT_LIST_HEAD(&e->list); | 265 | INIT_LIST_HEAD(&e->list); |
265 | } | 266 | } |
266 | 267 | ||
diff --git a/litmus/sched_mc_ce.c b/litmus/sched_mc_ce.c index 5125df9572ba..ffcc25873581 100644 --- a/litmus/sched_mc_ce.c +++ b/litmus/sched_mc_ce.c | |||
@@ -577,7 +577,7 @@ static int cancel_all_timers(void) | |||
577 | cancel_res = hrtimer_cancel(&ce_data->timer); | 577 | cancel_res = hrtimer_cancel(&ce_data->timer); |
578 | atomic_set(&ce_data->timer_info.state, | 578 | atomic_set(&ce_data->timer_info.state, |
579 | HRTIMER_START_ON_INACTIVE); | 579 | HRTIMER_START_ON_INACTIVE); |
580 | ret = ret || cancel_res; | 580 | ret = ret || cancel_res; |
581 | #endif | 581 | #endif |
582 | } | 582 | } |
583 | return ret; | 583 | return ret; |