<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-&gt;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 &amp;&amp; ctx-&gt;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 &amp; 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 &amp; 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();                                &lt;--- the ctx is made runnable w/o blocking.<br>
<br>
                do {<br>
                        spufs_wait();                        &lt;--- 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>