>> p->mach is a pointer back to a machine structure. I'm assuming this
>> only gets set when a process is being run. I suppose this test is here
>> in case another CPU took over running the process.
>
> Though, this can't be the case, because m->readied isn't locked when
> we come in here, and if we're running MP, wouldn't it be possible
> (though unlikely) that another CPU takes the process between the
> assignment and the test? Especially if running heavily threaded
> applications on MP systems?
/* cooperative scheduling until the clock ticks */
if((p=m->readied) && p->mach==0 && p->state==Ready
&& runq[Nrq-1].head == nil && runq[Nrq-2].head == nil){
The tests are:
p=m->readied
some process p was last readied on this cpu (Mach)
p->mach == 0
p is not running on any cpu right now
p->state == Ready
p is still Ready (waiting to run)
runq[Nrq-1].head == nil && runq[Nrq-2].head == nil
there are no real-time processes waiting to run
If all those succeed, then the code tries to choose
p to run next. But it might not -- the next thing that
happens is
p = dequeueproc(rq, p);
which can return nil if p has already been grabbed
or even if there is contention for the runq lock.
All the accesses in the if condition are just fine --
they happen without a lock but dequeueproc double-checks
that p is okay to schedule.
If dequeueproc returns nil, then runproc won't pick
the readied p after all -- it will fall into the regular
scheduling loop to find a process.
Russ