aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/event_group.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-09-27 20:15:32 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-09-27 20:36:04 -0400
commit23a00b911b968c6290251913ecc34171836b4d32 (patch)
treef6c8289054d2961902931e89bdc11ccc01bc3a73 /litmus/event_group.c
parentf21e1d0ef90c2e88ae6a563afc31ea601ed968c7 (diff)
parent609c45f71b7a2405230fd2f8436837d6389ec599 (diff)
Merged with ce domains
Diffstat (limited to 'litmus/event_group.c')
-rw-r--r--litmus/event_group.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/litmus/event_group.c b/litmus/event_group.c
index b4521ab370d1..276ba5dd242d 100644
--- a/litmus/event_group.c
+++ b/litmus/event_group.c
@@ -6,7 +6,9 @@
6#include <litmus/event_group.h> 6#include <litmus/event_group.h>
7 7
8#if 1 8#if 1
9#define VTRACE TRACE 9#define VTRACE(fmt, args...) \
10sched_trace_log_message("%d P%d [%s@%s:%d]: " fmt, \
11 TRACE_ARGS, ## args)
10#else 12#else
11#define VTRACE(fmt, args...) 13#define VTRACE(fmt, args...)
12#endif 14#endif
@@ -46,8 +48,8 @@ static enum hrtimer_restart on_timer(struct hrtimer *timer)
46 list_for_each_safe(pos, safe, &list) { 48 list_for_each_safe(pos, safe, &list) {
47 num++; 49 num++;
48 e = list_entry(pos, struct rt_event, list); 50 e = list_entry(pos, struct rt_event, list);
49 TRACE("Dequeueing event with prio %d from 0x%p\n", 51 TRACE("Dequeueing event 0x%p with prio %d from 0x%p\n",
50 e->prio, el); 52 e, e->prio, el);
51 list_del_init(pos); 53 list_del_init(pos);
52 e->function(e); 54 e->function(e);
53 } 55 }
@@ -69,12 +71,14 @@ void insert_event(struct event_list *el, struct rt_event *e)
69 VTRACE("Inserting priority %d 0x%p before %d 0x%p " 71 VTRACE("Inserting priority %d 0x%p before %d 0x%p "
70 "in 0x%p, pos 0x%p\n", e->prio, &e->list, 72 "in 0x%p, pos 0x%p\n", e->prio, &e->list,
71 queued->prio, &queued->list, el, pos); 73 queued->prio, &queued->list, el, pos);
74 BUG_ON(!list_empty(&e->list));
72 list_add_tail(&e->list, pos); 75 list_add_tail(&e->list, pos);
73 return; 76 return;
74 } 77 }
75 } 78 }
76 VTRACE("Inserting priority %d 0x%p at end of 0x%p, last 0x%p\n", 79 VTRACE("Inserting priority %d 0x%p at end of 0x%p, last 0x%p\n",
77 e->prio, &el->list, el, last); 80 e->prio, &el->list, el, last);
81 BUG_ON(!list_empty(&e->list));
78 list_add(&e->list, (last) ? last : pos); 82 list_add(&e->list, (last) ? last : pos);
79} 83}
80 84
@@ -91,12 +95,14 @@ static struct event_list* get_event_list(struct event_group *group,
91 struct list_head* pos; 95 struct list_head* pos;
92 struct event_list *el = NULL, *tmp; 96 struct event_list *el = NULL, *tmp;
93 unsigned int slot = time2slot(fire); 97 unsigned int slot = time2slot(fire);
98 int remaining = 300;
94 99
95 VTRACE("Getting list for %llu\n", fire); 100 VTRACE("Getting list for %llu, event 0x%p\n", fire, e);
96 101
97 /* Initialize pos for the case that the list is empty */ 102 /* Initialize pos for the case that the list is empty */
98 pos = group->event_queue[slot].next; 103 pos = group->event_queue[slot].next;
99 list_for_each(pos, &group->event_queue[slot]) { 104 list_for_each(pos, &group->event_queue[slot]) {
105 BUG_ON(remaining-- < 0);
100 tmp = list_entry(pos, struct event_list, list); 106 tmp = list_entry(pos, struct event_list, list);
101 if (lt_after_eq(fire, tmp->fire_time) && 107 if (lt_after_eq(fire, tmp->fire_time) &&
102 lt_before(fire, tmp->fire_time + group->res)) { 108 lt_before(fire, tmp->fire_time + group->res)) {
@@ -121,10 +127,11 @@ static struct event_list* get_event_list(struct event_group *group,
121 tmp->fire_time = fire; 127 tmp->fire_time = fire;
122 tmp->group = group; 128 tmp->group = group;
123 /* Add to queue */ 129 /* Add to queue */
124 list_add(&tmp->list, pos->prev);
125 el = tmp;
126 VTRACE("Using list for priority %d and time %llu\n", 130 VTRACE("Using list for priority %d and time %llu\n",
127 e->prio, fire); 131 e->prio, fire);
132 BUG_ON(!list_empty(&tmp->list));
133 list_add(&tmp->list, pos->prev);
134 el = tmp;
128 } 135 }
129 return el; 136 return el;
130} 137}
@@ -135,8 +142,8 @@ static struct event_list* get_event_list(struct event_group *group,
135static void reinit_event_list(struct rt_event *e) 142static void reinit_event_list(struct rt_event *e)
136{ 143{
137 struct event_list *el = e->event_list; 144 struct event_list *el = e->event_list;
138 BUG_ON(hrtimer_cancel(&el->timer)); 145 VTRACE("Reinitting 0x%p for event 0x%p\n", el, e);
139 VTRACE("Reinitting 0x%p\n", el); 146 BUG_ON(hrtimer_try_to_cancel(&el->timer) == 1);
140 INIT_LIST_HEAD(&el->events); 147 INIT_LIST_HEAD(&el->events);
141 atomic_set(&el->info.state, HRTIMER_START_ON_INACTIVE); 148 atomic_set(&el->info.state, HRTIMER_START_ON_INACTIVE);
142} 149}
@@ -148,8 +155,8 @@ void add_event(struct event_group *group, struct rt_event *e, lt_t fire)
148{ 155{
149 struct event_list *el; 156 struct event_list *el;
150 157
151 VTRACE("Adding event with priority %d for time %llu\n", 158 VTRACE("Adding event 0x%p with priority %d for time %llu\n",
152 e->prio, fire); 159 e, e->prio, fire);
153 160
154 raw_spin_lock(&group->queue_lock); 161 raw_spin_lock(&group->queue_lock);
155 el = get_event_list(group, e, fire, 0); 162 el = get_event_list(group, e, fire, 0);
@@ -167,7 +174,7 @@ void add_event(struct event_group *group, struct rt_event *e, lt_t fire)
167 174
168 /* Arm timer if we are the owner */ 175 /* Arm timer if we are the owner */
169 if (el == e->event_list) { 176 if (el == e->event_list) {
170 VTRACE("Arming timer for %llu\n", fire); 177 VTRACE("Arming timer on event 0x%p for %llu\n", e, fire);
171 if (group->cpu == smp_processor_id()) { 178 if (group->cpu == smp_processor_id()) {
172 __hrtimer_start_range_ns(&el->timer, 179 __hrtimer_start_range_ns(&el->timer,
173 ns_to_ktime(el->fire_time), 180 ns_to_ktime(el->fire_time),
@@ -185,14 +192,37 @@ void add_event(struct event_group *group, struct rt_event *e, lt_t fire)
185/** 192/**
186 * cancel_event() - Remove event from the group. 193 * cancel_event() - Remove event from the group.
187 */ 194 */
188void cancel_event(struct rt_event *e) 195void cancel_event(struct event_group *group, struct rt_event *e)
189{ 196{
190 struct event_group *group; 197 struct list_head *swap = NULL;
198 struct rt_event *swappy;
199 struct event_list *tmp;
200
191 if (e->list.next != &e->list) { 201 if (e->list.next != &e->list) {
192 group = e->event_list->group;
193 raw_spin_lock(&group->queue_lock); 202 raw_spin_lock(&group->queue_lock);
194 VTRACE("Canceling event with priority %d\n", e->prio); 203 VTRACE("Canceling event 0x%p with priority %d\n", e, e->prio);
195 list_del_init(&e->list); 204
205 /* If somebody else is hooked up to our event list, swap
206 * with their event list and leave our old event list
207 * to execute.
208 */
209 if (!list_empty(&e->list)) {
210 swap = (e->list.next == &e->event_list->events) ?
211 (e->list.prev == &e->event_list->events) ?
212 NULL : e->list.prev : e->list.next;
213 list_del_init(&e->list);
214 }
215 if (swap) {
216 swappy = list_entry(swap, struct rt_event, list);
217 tmp = swappy->event_list;
218 swappy->event_list = e->event_list;
219 e->event_list = tmp;
220 VTRACE("Swapping with event 0x%p", swappy);
221 }
222
223 hrtimer_try_to_cancel(&e->event_list->timer);
224 list_del_init(&e->event_list->list);
225
196 raw_spin_unlock(&group->queue_lock); 226 raw_spin_unlock(&group->queue_lock);
197 } 227 }
198} 228}