aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/sched.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 1582d764523..876828cc95a 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -245,6 +245,14 @@ static void spu_add_to_rq(struct spu_context *ctx)
245 spin_unlock(&spu_prio->runq_lock); 245 spin_unlock(&spu_prio->runq_lock);
246} 246}
247 247
248static void __spu_del_from_rq(struct spu_context *ctx, int prio)
249{
250 if (!list_empty(&ctx->rq))
251 list_del_init(&ctx->rq);
252 if (list_empty(&spu_prio->runq[prio]))
253 clear_bit(ctx->prio, spu_prio->bitmap);
254}
255
248/** 256/**
249 * spu_del_from_rq - remove a context from the runqueue 257 * spu_del_from_rq - remove a context from the runqueue
250 * @ctx: context to remove 258 * @ctx: context to remove
@@ -252,33 +260,10 @@ static void spu_add_to_rq(struct spu_context *ctx)
252static void spu_del_from_rq(struct spu_context *ctx) 260static void spu_del_from_rq(struct spu_context *ctx)
253{ 261{
254 spin_lock(&spu_prio->runq_lock); 262 spin_lock(&spu_prio->runq_lock);
255 list_del_init(&ctx->rq); 263 __spu_del_from_rq(ctx, ctx->prio);
256 if (list_empty(&spu_prio->runq[ctx->prio]))
257 clear_bit(ctx->prio, spu_prio->bitmap);
258 spin_unlock(&spu_prio->runq_lock); 264 spin_unlock(&spu_prio->runq_lock);
259} 265}
260 266
261/**
262 * spu_grab_context - remove one context from the runqueue
263 * @prio: priority of the context to be removed
264 *
265 * This function removes one context from the runqueue for priority @prio.
266 * If there is more than one context with the given priority the first
267 * task on the runqueue will be taken.
268 *
269 * Returns the spu_context it just removed.
270 *
271 * Must be called with spu_prio->runq_lock held.
272 */
273static struct spu_context *spu_grab_context(int prio)
274{
275 struct list_head *rq = &spu_prio->runq[prio];
276
277 if (list_empty(rq))
278 return NULL;
279 return list_entry(rq->next, struct spu_context, rq);
280}
281
282static void spu_prio_wait(struct spu_context *ctx) 267static void spu_prio_wait(struct spu_context *ctx)
283{ 268{
284 DEFINE_WAIT(wait); 269 DEFINE_WAIT(wait);
@@ -309,9 +294,14 @@ static void spu_reschedule(struct spu *spu)
309 spin_lock(&spu_prio->runq_lock); 294 spin_lock(&spu_prio->runq_lock);
310 best = sched_find_first_bit(spu_prio->bitmap); 295 best = sched_find_first_bit(spu_prio->bitmap);
311 if (best < MAX_PRIO) { 296 if (best < MAX_PRIO) {
312 struct spu_context *ctx = spu_grab_context(best); 297 struct list_head *rq = &spu_prio->runq[best];
313 if (ctx) 298 struct spu_context *ctx;
314 wake_up(&ctx->stop_wq); 299
300 BUG_ON(list_empty(rq));
301
302 ctx = list_entry(rq->next, struct spu_context, rq);
303 __spu_del_from_rq(ctx, best);
304 wake_up(&ctx->stop_wq);
315 } 305 }
316 spin_unlock(&spu_prio->runq_lock); 306 spin_unlock(&spu_prio->runq_lock);
317} 307}