首页 文章

Linux内核中的级别代码位置很好

提问于
浏览
0

我已经阅读了这个有关好的关卡如何工作的页面:http://oakbytes.wordpress.com/2012/06/06/linux-scheduler-cfs-and-nice/

有没有人知道内核代码库中的文件,其中实现了公式“1024 /(1.25) ^(nice)”来分配进程的权重?

1 回答

  • 1

    虽然问题中引用的计算未按原样使用(内核仅使用整数数学,但很少或没有例外), nice 系统调用is implemented here . 经过一些完整性和安全性检查后,它最终调用set_user_nice(),它使用宏将用户指定的nice值转换为内核优先级值 .

    void set_user_nice(struct task_struct *p, long nice)
    {
            int old_prio, delta, queued;
            unsigned long flags;
            struct rq *rq;
    
            if (task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE)
                    return;
            /*
             * We have to be careful, if called from sys_setpriority(),
             * the task might be in the middle of scheduling on another CPU.
             */
            rq = task_rq_lock(p, &flags);
            /*
             * The RT priorities are set via sched_setscheduler(), but we still
             * allow the 'normal' nice value to be set - but as expected
             * it wont have any effect on scheduling until the task is
             * SCHED_DEADLINE, SCHED_FIFO or SCHED_RR:
             */
             if (task_has_dl_policy(p) || task_has_rt_policy(p)) {
                    p->static_prio = NICE_TO_PRIO(nice);
                    goto out_unlock;
             }
             queued = task_on_rq_queued(p);
             if (queued)
                     dequeue_task(rq, p, 0);
    
             p->static_prio = NICE_TO_PRIO(nice);
             set_load_weight(p);
             old_prio = p->prio;
             p->prio = effective_prio(p);
             delta = p->prio - old_prio;
    
             if (queued) {
                     enqueue_task(rq, p, 0);
                     /*
                      * If the task increased its priority or is running and
                      * lowered its priority, then reschedule its CPU:
                      */
                     if (delta < 0 || (delta > 0 && task_running(rq, p)))
                             resched_curr(rq);
             }
    out_unlock:
             task_rq_unlock(rq, p, &flags);
    }
    EXPORT_SYMBOL(set_user_nice);
    

    宏是defined here

    #define MAX_NICE        19
    #define MIN_NICE        -20
    #define NICE_WIDTH      (MAX_NICE - MIN_NICE + 1)
    
    /*
     * Priority of a process goes from 0..MAX_PRIO-1, valid RT
     * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
     * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
     * values are inverted: lower p->prio value means higher priority.
     *
     * The MAX_USER_RT_PRIO value allows the actual maximum
     * RT priority to be separate from the value exported to
     * user-space.  This allows kernel threads to set their
     * priority to a value higher than any user task. Note:
     * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
     */
    
    #define MAX_USER_RT_PRIO        100
    #define MAX_RT_PRIO             MAX_USER_RT_PRIO
    
    #define MAX_PRIO                (MAX_RT_PRIO + NICE_WIDTH)
    #define DEFAULT_PRIO            (MAX_RT_PRIO + NICE_WIDTH / 2)
    
    /*
     * Convert user-nice values [ -20 ... 0 ... 19 ]
     * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
     * and back.
     */
    #define NICE_TO_PRIO(nice)      ((nice) + DEFAULT_PRIO)
    #define PRIO_TO_NICE(prio)      ((prio) - DEFAULT_PRIO)
    
    /*
     * 'User priority' is the nice value converted to something we
     * can work with better when scaling various scheduler parameters,
     * it's a [ 0 ... 39 ] range.
     */
    #define USER_PRIO(p)            ((p)-MAX_RT_PRIO)
    #define TASK_USER_PRIO(p)       USER_PRIO((p)->static_prio)
    #define MAX_USER_PRIO           (USER_PRIO(MAX_PRIO))
    

    有关设计的说明,请参见this document .

相关问题