diff options
Diffstat (limited to 'litmus/dgl.c')
-rw-r--r-- | litmus/dgl.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/litmus/dgl.c b/litmus/dgl.c index e2286b3e9239..cced7c259735 100644 --- a/litmus/dgl.c +++ b/litmus/dgl.c | |||
@@ -28,6 +28,11 @@ | |||
28 | #define req_group(r, i) (container_of(((void*)r) - sizeof(*r)*(i), \ | 28 | #define req_group(r, i) (container_of(((void*)r) - sizeof(*r)*(i), \ |
29 | struct dgl_group_req, requests)) | 29 | struct dgl_group_req, requests)) |
30 | 30 | ||
31 | #define TRACE(fmt, args...) STRACE(fmt, ## args) | ||
32 | #define TRACE_GREQ(greq, fmt, args...) \ | ||
33 | TRACE("(greq-%s/%d) " fmt, (greq->task ? greq->task->comm : "greq"), \ | ||
34 | (greq->task ? greq->task->pid : (int)greq), ## args) | ||
35 | |||
31 | /* Resource id -> word, bit */ | 36 | /* Resource id -> word, bit */ |
32 | static inline void mask_idx(int resource, int *word, int *bit) | 37 | static inline void mask_idx(int resource, int *word, int *bit) |
33 | { | 38 | { |
@@ -35,7 +40,6 @@ static inline void mask_idx(int resource, int *word, int *bit) | |||
35 | *bit = resource % MASK_SIZE; | 40 | *bit = resource % MASK_SIZE; |
36 | } | 41 | } |
37 | 42 | ||
38 | |||
39 | static void print_waiting(struct dgl *dgl, struct dgl_resource *resource) | 43 | static void print_waiting(struct dgl *dgl, struct dgl_resource *resource) |
40 | { | 44 | { |
41 | struct dgl_req *pos; | 45 | struct dgl_req *pos; |
@@ -45,12 +49,14 @@ static void print_waiting(struct dgl *dgl, struct dgl_resource *resource) | |||
45 | TRACE("List for rid %d\n", resource_id(dgl, resource)); | 49 | TRACE("List for rid %d\n", resource_id(dgl, resource)); |
46 | list_for_each_entry(pos, &resource->waiting, list) { | 50 | list_for_each_entry(pos, &resource->waiting, list) { |
47 | greq = pos->greq; | 51 | greq = pos->greq; |
48 | TRACE(" 0x%p with timestamp %llu\n", greq, greq->ts); | 52 | TRACE_GREQ(greq, "with timestamp %llu\n", greq->ts); |
49 | BUG_ON(greq->ts < last); | 53 | BUG_ON(greq->ts < last); |
50 | last = greq->ts; | 54 | last = greq->ts; |
51 | } | 55 | } |
52 | } | 56 | } |
53 | 57 | ||
58 | static void dummy_acquired(int cpu){} | ||
59 | |||
54 | void dgl_init(struct dgl *dgl, unsigned long num_resources, | 60 | void dgl_init(struct dgl *dgl, unsigned long num_resources, |
55 | unsigned long num_replicas) | 61 | unsigned long num_replicas) |
56 | { | 62 | { |
@@ -78,6 +84,7 @@ void dgl_init(struct dgl *dgl, unsigned long num_resources, | |||
78 | dgl->requests = 0; | 84 | dgl->requests = 0; |
79 | dgl->running = 0; | 85 | dgl->running = 0; |
80 | dgl->ts = 0; | 86 | dgl->ts = 0; |
87 | dgl->cpu_acquired = dummy_acquired; | ||
81 | } | 88 | } |
82 | 89 | ||
83 | void dgl_free(struct dgl *dgl) | 90 | void dgl_free(struct dgl *dgl) |
@@ -130,7 +137,7 @@ void set_req(struct dgl *dgl, struct dgl_group_req *greq, | |||
130 | mask_idx(resource, &word, &bit); | 137 | mask_idx(resource, &word, &bit); |
131 | __set_bit(bit, &greq->requested[word]); | 138 | __set_bit(bit, &greq->requested[word]); |
132 | 139 | ||
133 | TRACE("0x%p requesting %d of %d\n", greq, replicas, resource); | 140 | TRACE_GREQ(greq, "requesting %d of %d\n", replicas, resource); |
134 | 141 | ||
135 | req = &greq->requests[resource]; | 142 | req = &greq->requests[resource]; |
136 | req->greq = greq; | 143 | req->greq = greq; |
@@ -153,27 +160,27 @@ static unsigned long try_acquire(struct dgl *dgl, struct dgl_resource *resource, | |||
153 | rid = resource_id(dgl, resource); | 160 | rid = resource_id(dgl, resource); |
154 | greq = req->greq; | 161 | greq = req->greq; |
155 | 162 | ||
156 | TRACE("0x%p greq\n", greq); | 163 | TRACE_GREQ(greq, "try acquire\n"); |
157 | 164 | ||
158 | head = resource->waiting.next == &req->list; | 165 | head = resource->waiting.next == &req->list; |
159 | empty = list_empty(&resource->waiting); | 166 | empty = list_empty(&resource->waiting); |
160 | room = resource->free_replicas >= req->replicas; | 167 | room = resource->free_replicas >= req->replicas; |
161 | 168 | ||
162 | if (! (room && (head || empty)) ) { | 169 | if (! (room && (head || empty)) ) { |
163 | TRACE("0x%p cannot acquire %d replicas, %d free\n", | 170 | TRACE_GREQ(greq, "cannot acquire %d replicas, %d free\n", |
164 | greq, req->replicas, resource->free_replicas, | 171 | req->replicas, resource->free_replicas, |
165 | room, head, empty); | 172 | room, head, empty); |
166 | return 0; | 173 | return 0; |
167 | } | 174 | } |
168 | 175 | ||
169 | resource->free_replicas -= req->replicas; | 176 | resource->free_replicas -= req->replicas; |
170 | 177 | ||
171 | TRACE("0x%p acquired %d replicas of rid %d\n", | 178 | TRACE_GREQ(greq, "0x%p acquired %d replicas of rid %d\n", |
172 | greq, req->replicas, rid); | 179 | req->replicas, rid); |
173 | 180 | ||
174 | mask_idx(rid, &word, &bit); | 181 | mask_idx(rid, &word, &bit); |
175 | 182 | ||
176 | TRACE("0x%p, %lu, 0x%p\n", greq->waiting, greq->waiting[word], | 183 | TRACE_GREQ(greq, "0x%p, %lu, 0x%p\n", greq->waiting, greq->waiting[word], |
177 | &greq->waiting[word]); | 184 | &greq->waiting[word]); |
178 | 185 | ||
179 | clear_bit(bit, &greq->waiting[word]); | 186 | clear_bit(bit, &greq->waiting[word]); |
@@ -186,11 +193,19 @@ static unsigned long try_acquire(struct dgl *dgl, struct dgl_resource *resource, | |||
186 | } | 193 | } |
187 | 194 | ||
188 | if (!waiting) { | 195 | if (!waiting) { |
189 | TRACE("0x%p acquired all resources\n", greq); | 196 | TRACE_GREQ(greq, "acquired all resources on cpu %d\n", greq->cpu); |
190 | BUG_ON(dgl->acquired[greq->cpu]); | 197 | BUG_ON(dgl->acquired[greq->cpu]); |
191 | dgl->acquired[greq->cpu] = greq; | 198 | dgl->acquired[greq->cpu] = greq; |
192 | litmus_reschedule(greq->cpu); | 199 | litmus_reschedule(greq->cpu); |
193 | dgl->running++; | 200 | dgl->running++; |
201 | |||
202 | if (greq->task) { | ||
203 | BUG_ON(tsk_rt(greq->task)->linked_on == NO_CPU); | ||
204 | set_rt_flags(greq->task, RT_F_RUNNING); | ||
205 | sched_trace_task_resume(greq->task); | ||
206 | } | ||
207 | |||
208 | dgl->cpu_acquired(greq->cpu); | ||
194 | } | 209 | } |
195 | 210 | ||
196 | return 1; | 211 | return 1; |
@@ -208,7 +223,7 @@ void add_group_req(struct dgl *dgl, struct dgl_group_req *greq, int cpu) | |||
208 | greq->cpu = cpu; | 223 | greq->cpu = cpu; |
209 | greq->ts = dgl->ts++; | 224 | greq->ts = dgl->ts++; |
210 | 225 | ||
211 | TRACE("0x%p group request added for CPU %d\n", greq, cpu); | 226 | TRACE_GREQ(greq, "group request added for CPU %d\n", cpu); |
212 | BUG_ON(dgl->acquired[cpu] == greq); | 227 | BUG_ON(dgl->acquired[cpu] == greq); |
213 | 228 | ||
214 | ++dgl->requests; | 229 | ++dgl->requests; |
@@ -225,14 +240,14 @@ void add_group_req(struct dgl *dgl, struct dgl_group_req *greq, int cpu) | |||
225 | all_succ &= succ; | 240 | all_succ &= succ; |
226 | 241 | ||
227 | if (!succ) { | 242 | if (!succ) { |
228 | TRACE("0x%p waiting on rid %d\n", greq, i); | 243 | TRACE_GREQ(greq, "waiting on rid %d\n", i); |
229 | list_add_tail(&req->list, &resource->waiting); | 244 | list_add_tail(&req->list, &resource->waiting); |
230 | } | 245 | } |
231 | } | 246 | } |
232 | 247 | ||
233 | /* Grant empty requests */ | 248 | /* Grant empty requests */ |
234 | if (all_succ && !dgl->acquired[cpu]) { | 249 | if (all_succ && !dgl->acquired[cpu]) { |
235 | TRACE("0x%p empty group request acquired cpu %d\n", greq, cpu); | 250 | TRACE_GREQ(greq, "empty group request acquired cpu %d\n", cpu); |
236 | dgl->acquired[cpu] = greq; | 251 | dgl->acquired[cpu] = greq; |
237 | ++dgl->running; | 252 | ++dgl->running; |
238 | } | 253 | } |
@@ -251,12 +266,12 @@ void remove_group_req(struct dgl *dgl, struct dgl_group_req *greq) | |||
251 | struct dgl_req *req, *next; | 266 | struct dgl_req *req, *next; |
252 | struct dgl_resource *resource; | 267 | struct dgl_resource *resource; |
253 | 268 | ||
254 | TRACE("0x%p removing group request for CPU %d\n", greq, greq->cpu); | 269 | TRACE_GREQ(greq, "removing group request for CPU %d\n", greq, greq->cpu); |
255 | 270 | ||
256 | --dgl->requests; | 271 | --dgl->requests; |
257 | 272 | ||
258 | if (dgl->acquired[greq->cpu] == greq) { | 273 | if (dgl->acquired[greq->cpu] == greq) { |
259 | TRACE("0x%p no longer acquired on CPU %d\n", greq, greq->cpu); | 274 | TRACE_GREQ(greq, "no longer acquired on CPU %d\n", greq->cpu); |
260 | dgl->acquired[greq->cpu] = NULL; | 275 | dgl->acquired[greq->cpu] = NULL; |
261 | --dgl->running; | 276 | --dgl->running; |
262 | } | 277 | } |
@@ -275,8 +290,8 @@ void remove_group_req(struct dgl *dgl, struct dgl_group_req *greq) | |||
275 | /* Have resource */ | 290 | /* Have resource */ |
276 | resource->free_replicas += req->replicas; | 291 | resource->free_replicas += req->replicas; |
277 | BUG_ON(resource->free_replicas > dgl->num_replicas); | 292 | BUG_ON(resource->free_replicas > dgl->num_replicas); |
278 | TRACE("0x%p releasing %d of %d replicas, rid %d\n", | 293 | TRACE_GREQ(greq, "releasing %d of %d replicas, rid %d\n", |
279 | greq, req->replicas, resource->free_replicas, i); | 294 | req->replicas, resource->free_replicas, i); |
280 | 295 | ||
281 | if (!list_empty(&resource->waiting)) { | 296 | if (!list_empty(&resource->waiting)) { |
282 | /* Give it to the next guy */ | 297 | /* Give it to the next guy */ |