<html><body>
<p>Hi Christoph,<br>
<br>
See comment below subroutine.<br>
<br>
Thanks, Luke<br>
<br>
<br>
/**<br>
* spu_activate - find a free spu for a context and execute it<br>
* @ctx: spu context to schedule<br>
* @flags: flags (currently ignored)<br>
*<br>
* Tries to find a free spu to run @ctx. If no free spu is availble<br>
* add the context to the runqueue so it gets woken up once an spu<br>
* is available.<br>
*/<br>
int spu_activate(struct spu_context *ctx, unsigned long flags)<br>
{<br>
<br>
if (ctx->spu)<br>
return 0;<br>
<br>
do {<br>
struct spu *spu;<br>
<br>
spu = spu_get_idle(ctx);<br>
/*<br>
* If this is a realtime thread we try to get it running by<br>
* preempting a lower priority thread.<br>
*/<br>
if (!spu && ctx->rt_priority)<br>
spu = find_victim(ctx);<br>
if (spu) {<br>
spu_bind_context(spu, ctx);<br>
return 0;<br>
}<br>
<br>
spu_add_to_rq(ctx);<br>
if (!(flags & SPU_ACTIVATE_NOWAKE))<br>
spu_prio_wait(ctx);<br>
spu_del_from_rq(ctx);<br>
} while (!signal_pending(current));<br>
<br>
return -ERESTARTSYS;<br>
}<br>
<br>
--------------------------<br>
<br>
A couple of points:<br>
<br>
1) If ctx is not fixed priority (ie. SCHED_OTHER) and SPU_ACTIVATE_NOWAKE is specified (spu_run_init)<br>
then you spin waiting for an spu to become idle assuming there is not a signal pending. <br>
<br>
        do {<br>
                ...<br>
                spu_add_to_rq()<br>
                spu_del_from_rq()<br>
        } while (!signal);<br>
        <br>
2) SPU_ACTIVATE_NOWAKE is a bad name as it doesn't describe what the target is doing. In this case<br>
the caller is requesting that ctx be put into the runnable state without blocking. I suggest something like:<br>
<br>
        if (!(flags & SPU_ACTIVATE_NDELAY))<br>
                spu_prio_wait()<br>
<br>
Sorry to belabour this point, but I made it in my earlier comment. Maybe it wasn't clear. <br>
<br>
3) this is actually the big point. The high level flow should be:<br>
<br>
        spufs_run_spu()<br>
        {<br>
                spu_run_init();                                <--- the ctx is made runnable w/o blocking.<br>
<br>
                do {<br>
                        spufs_wait();                        <--- the calling thread blocks here for the first time.<br>
                        ...<br>
                } while ();<br>
        }<br>
<br>
We want to avoid the context switch in spu_run_init(), since we are going to block a few lines of code<br>
later in spufs_run_spu() when it invokes spufs_wait(). We might as well just wait there the first time. <br>
spu_run_init() should just put the ctx on the runqueue and return to the caller w/o blocking.<br>
<br>
Here's the tricky part. spu_run_init() also performs runctl register stuff! I think that these state changes<br>
can be made against the saved state of the ctx and applied later by the scheduler just as it would for<br>
a preempted context, so these changes do not require a major restructuring of the code. The ctx should <br>
be put on the runqueue with its save area updated just like you would have if it were preempted.<br>
<br>
Luke</body></html>