> Another difference is that it correctly counts context switches as voluntary.

Good point.  The patched version calls maybe_resched(), and I'm
adding the line at "<<<".

(This also will let people who haven't looked at that code
complain about the function interface - it doesn't bother me,
macros could come later.)

/* 
 * prioritize: Compute a priority based on the type of scheduler.
 */
static priority_type
prioritize(struct proc *p)
{
        priority_type priority;
        int class = RTP_PRIO_BASE(p->p_rtprio.type);

        if (class == RTP_PRIO_NORMAL) {
                priority = (RTP_PRIO_NORMAL << 8) | (p->p_priority / PPQ);
        }
        else
                priority = (class << 8) | p->p_rtprio.prio;

        return priority;
}

/*
 * curpriority_set: Set the current process priority to that of the process
 * in the call.
 */
void
curpriority_set(struct proc *p)
{
        newcurpriority = prioritize(p);
}

/*
 * curpriority_cmp: Compare the priorities.  Return:
 * <0: p < curpriority
 *  0: p == curpriority
 * >0: p > curpriority
 */

static int
curpriority_cmp(struct proc *p)
{
        priority_type prio = prioritize(p);
        return prio - newcurpriority;
}

/*
 * maybe_resched: Decide if you need to reschedule or not,
 * taking the priorities and schedulers into account.
 *
 * This function needs to be call AFTER chk->p_priority has
 * been updated.
 */
static void
maybe_resched(struct proc *chk)
{
        if (curproc == 0)
                need_resched();
        else if (chk == curproc) {
                /*
                 * If chk is curproc, we may need to preempt if
                 * we're making our priority less favorable.
                 */
                if (curpriority_cmp(chk) > 0) {
                        chk->p_stats->p_ru.ru_nvcsw++; /* <<< Adding */
                        need_resched();
                }
        }
        /*
         * If chk is not the curproc, we want to preempt if chk has
         * a more favorable priority than curproc.
         *
         * We shouldn't preempt the current process because of the
         * priority of a sleeping or stopped process. 
         *
         */
        else if ((chk->p_flag & P_INMEM) &&
                   chk->p_stat == SRUN     &&
                   curpriority_cmp(chk) < 0) {
                need_resched();
        }
}


-- 
Peter Dufault (dufa...@hda.com)   Realtime development, Machine control,
HD Associates, Inc.               Safety critical systems, Agency approval

To Unsubscribe: send mail to majord...@freebsd.org
with "unsubscribe freebsd-current" in the body of the message

Reply via email to