Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
$B;~9o$H;~4V$N4IM}!"%W%m%;%9$N%9%1%8%e!<%j%s%0(B
[go: Go Back, main page]

$B;~9o$H;~4V$N4IM}!"%W%m%;%9$N%9%1%8%e!<%j%s%0(B

					2014$BG/(B01$B7n(B23$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II

                                       $BC^GHBg3X(B $B%7%9%F%`>pJs9)3X8&5f2J(B 
                                       $B%3%s%T%e!<%?%5%$%(%s%9@l96(B, $BEE;R!&>pJs9)3X7O(B
                                       $B?7>k(B $BLw(B
                                       <yas@cs.tsukuba.ac.jp>

$B$3$N%Z!<%8$O!" http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2013/2014-01-23
$B$"$k$$$O!" http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/

$B"#:#F|$NBg;v$JOC(B

$B;~9o$H;~4V$N4IM}(B $B%W%m%;%9$N%9%1%8%e!<%j%s%0$N4XO"(B
  • $B2r=|$5$l$k$^$G(B 3. $B$K$b$I$C$F7+$jJV$9!#(B

    $B"!;~4V@Z$l=hM}$N(BAPI

    int  select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
         		struct timeval *timeout);
    int  poll(struct pollfd *fds, nfds_t nfds, int timeout);
    
    $B%M%C%H%o!<%/!&%W%m%0%i%`$G$h$/;H$&!#J#?t$NF~NO$r4F;k$9$k!#;XDj$5$l$?;~(B $B4V!"F~NO$,$J$1$l$P!"%7%9%F%`!&%3!<%k$+$iI|5"$9$k!#(B

    $B$J$K$b$7$J$$;~4V@Z$l!#(B

    unsigned int sleep(unsigned int seconds);
    int usleep(useconds_t usec)
    int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
    

    $B"#;~9o!&;~4V4XO"$N%O!<%I%&%'%"(B

    $B%3%s%T%e!<%?$K$h$C$F0c$&!#$3$3$G$O!"(BPC/AT $B$NOC!#(B

    $B"!4pK\E*$J%b%G%k(B

    $B%O!<%I%&%'%"$O!"4JC1!#H/?64o$H%+%&%s%H%@%&%s$9$k%+%&%s%?$r;H$&!#(B

    $B?^(B?$B!!H/?64o!

    $B?^(B? $B%?%$%^4XO"$N%O!<%I%&%'%"$N4pK\%b%G%k(B

    $B%+%&%s%H%@%&%s$G$O$J$/%+%&%s%H%"%C%W$9$k$b$N$b$"$k!#(B

    $B"!(BPIT (Programmable Interval Timer)

    $B8E$$%?%$%^!&%G%P%$%9!#(B

    $B"!(BCMOS RTC (Real Time Clock)

    $BEE8;%*%U;~$K$b!"%P%C%F%j$GF0:n$7$F$$$k!#(BBIOS $BMQ$N@_Dj$rJ];}$9$k%a%b%j$N(B $B0lIt!#(B $BEv;~!"(BCMOS $B$O!"!VDc>CHqEENO!WMQ$H$7$F$@$1;H$o$l$F$$$?!#(B $B:#$O!"IaDL!#(B $B!!(B

    2$B$D$N5!G=$,$"$k!#(B

    TOD (Time of Day) clock
    $B;~9o$r!"(Byear/month/day hour:minute:second $B$H$$$&7A<0$G;}$D!#(B $BIC0J2<$OFI$a$J$$!#(B
    $BDj4|E*$J3d9~$_MQ(B
    2Hz $B$+$i(B 8192Hz $B$NHO0O$G!"(B2 $B$NQQ>h$N<~4|$G3d9~$_$r5/$3$;$k!#(B
    $B@)Ls(B

    $B$=$NB>$N3d9~$_(B

    $B"!(BLocal APIC (Advanced Programmable Interrupt Controller) Timers

    Local APIC $B$O!"3d9~$_$N%k!<%F%#%s%0$K;H$o$l$k!#(B $B%^%k%A%W%m%;%C%5$G$b!"(BCPU $BKh$KFHN)!#(B Pentium $B0J9_$G$O!"(BCPU $B$KFbB"!#(B

    $B"!(BACPI (Advanced Configuration and Power Interface)

    $B%A%C%W%;%C%H!&%?%$%^$H$b8F$P$l$k!#(B

    $B"!(BTSC (Time Stamp Counter)

    Pentium $B0J9_$GMxMQ2DG=!#(B

    $B"!(BHPET(High Precision Event Timer)

    $B?7$7$$L\$N(B PC $B$GEk:\$5$l$F$$$k!#(B

    $B"#(Bjiffies$B$H(BHZ

    jiffies $B$O!"(BLinux $B$G!"%b%N%H%K%C%/;~9o$rDs6!$9$kJQ?t!#C10L$O!"(Btick$B!#(B $BMxMQNc(B $B linux-3.12.6/kernel/timer.c 55: u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; linux-3.12.6/include/linux/jiffies.h 76: extern u64 __jiffy_data jiffies_64; 77: extern unsigned long volatile __jiffy_data jiffies;

    $B"!(Btick_periodic()

    tick_periodic() $B$O!"%O!<%I%&%'%"$+$iFHN)$7$?(Btick $B$4$H$N=hM}$r9T$&4X?t(B $B$G$"$k!#(B
    linux-3.12.6/kernel/time/tick-common.c
      63:	static void tick_periodic(int cpu)
      64:	{
      65:	        if (tick_do_timer_cpu == cpu) {
    ...
      71:	                do_timer(1);
    ...
      73:	        }
      74:	
      75:	        update_process_times(user_mode(get_irq_regs()));
    ...
      77:	}
    

    $B"!(Bdo_timer()

    linux-3.12.6/kernel/timer.c
      55:	u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
    
    linux-3.12.6/kernel/time/timekeeping.c
    1583:	void do_timer(unsigned long ticks)
    1584:	{
    1585:	        jiffies_64 += ticks;
    1586:	        update_wall_time();
    ...
    1588:	}
    

    $B"#%+%l%s%@!<;~9o$N

    $B"!(Bstruct timekeeper/xtime

    struct timekeeper $B$O!"A4BN$G%+%l%s%@!<;~9o$r7W;;$9$k$?$a$N9=B$BN!#
  • u64 xtime_sec: $BIC(B
  • u64 xtime_nsec: $B%J%NIC(B
  • u32 shift: $B%J%NICItJ,$N%7%U%H!#(B $Bxtime_nsec >> shift $B$G%J%NIC$rI=$9!#(B
    linux-3.12.6/include/linux/timekeeper_internal.h
      14:	struct timekeeper {
    ...
      20:	        u32                     shift;
    ...
      32:	        /* Current CLOCK_REALTIME time in seconds */
      33:	        u64                     xtime_sec;
      34:	        /* Clock shifted nano seconds */
      35:	        u64                     xtime_nsec;
    ...
      72:	};
    
      74:	static inline struct timespec tk_xtime(struct timekeeper *tk)
      75:	{
      76:	        struct timespec ts;
      77:	
      78:	        ts.tv_sec = tk->xtime_sec;
      79:	        ts.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
      80:	        return ts;
      81:	}
    

    $B"!(Bgettimeofday()$B%7%9%F%`!&%3!<%k(B

    linux-3.12.6/kernel/time.c
     101:	SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
     102:	                struct timezone __user *, tz)
     103:	{
     104:	        if (likely(tv != NULL)) {
     105:	                struct timeval ktv;
     106:	                do_gettimeofday(&ktv);
     107:	                if (copy_to_user(tv, &ktv, sizeof(ktv)))
     108:	                        return -EFAULT;
     109:	        }
     110:	        if (unlikely(tz != NULL)) {
     111:	                if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
     112:	                        return -EFAULT;
     113:	        }
     114:	        return 0;
     115:	}
    
    linux-3.12.6/kernel/time/timekeeping.c
     478:	void do_gettimeofday(struct timeval *tv)
     479:	{
     480:	        struct timespec now;
     481:	
     482:	        getnstimeofday(&now);
     483:	        tv->tv_sec = now.tv_sec;
     484:	        tv->tv_usec = now.tv_nsec/1000;
     485:	}
    
     331:	void getnstimeofday(struct timespec *ts)
     332:	{
     333:	        WARN_ON(__getnstimeofday(ts));
     334:	}
    
     298:	int __getnstimeofday(struct timespec *ts)
     299:	{
     300:	        struct timekeeper *tk = &timekeeper;
     301:	        unsigned long seq;
     302:	        s64 nsecs = 0;
    ...
     307:	                ts->tv_sec = tk->xtime_sec;
     308:	                nsecs = timekeeping_get_ns(tk);
     312:	        ts->tv_nsec = 0;
     313:	        timespec_add_ns(ts, nsecs);
    ...
     321:	        return 0;
     322:	}
    

    $B"!(Bupdate_wall_time()

    update_wall_time() $B$O!"(B do_timer() $B$+$i8F$P$l!"3]$1;~7W$N;~9o(B xtime $B$r99?7$9$k!#(B

    $B"#;~4V@Z$l=hM}(B($B%?%$%^(B)

    Linux $B%+!<%M%k$K$O!"$"$k;~4V$,7P2a$7$?$i!"4X?t$r
  • struct timer_list: tick $BC10L(B
  • struct hrtimer: $B%J%NICC10L(B

    $B"!(Bstruct timer_list

    linux-3.12.6/include/linux/timer.h
      12:	struct timer_list {
    ...
      17:	        struct list_head entry;
      18:	        unsigned long expires;
      19:	        struct tvec_base *base;
      20:	
      21:	        void (*function)(unsigned long);
      22:	        unsigned long data;
    ...
      34:	};
    

    jiffies $B$,A}2C$7$F(B expires $B$KC#$9$l$P!"(B(*function)(data) $B$r8F$V!#(B

    $B

    add_timer(), add_timer_on()
    $B%?%$%^$NEPO?!#(B_on() $B$O!"(BCPU $B$4$H!#(B
    mod_timer()
    $B%?%$%^$N5/F0;~9o$NJQ99(B
    del_timer(), del_timer_sync(), try_to_del_timer_sync()
    $B%?%$%^$N%-%c%s%;%k!#(B del_timer_sync() $B$O!"$b$74{$K $BMxMQNc!#(B
    {
        struct timer_list my_timer;           // $B9=B$BN$N@k8@(B
        init_timer(&my_timer);$B!!!!!!!!!!!!!!!!(B// $B=i4|2=(B
        my_timer.expires = jiffies + delay;   // $B$I$N$/$i$$BT$A$?$$$+(B
        my_timer.data = (unsigned long)data;  // $BEO$7$?$$%G!<%?(B
        my_timer.function = my_timer_func;    // $B4X?t(B
        add_timer(&my_timer);                 // $BEPO?(B
    }
    
    void my_timer_func(unsigned long data) {
        ...
    }
    
    • add_timer() $B$K$h$j!"(Bdelay tick $B8e$K(B my_timer_func() $B$,8F$P$l$k!#(B
    • $B$3$N;~!"$=$N4X?t$K$O(B data $B$,EO$5$l$k!#(B

    $B"!(BHigh-resolution kernel timers

    struct timer_list$B$N(BAPI$B$G$O!"(Btick$BC10L$@$,!"(Bstruct hrtimer $B$N(B API $B$G$O!"(B $B%J%NICC10L$G;XDj$G$-$k!#$?$@$7!"e$N@:EY$O$J$$!#(B

    $B

    hrtimer_init()
    struct hrtimer $B9=B$BN$N=i4|2=!#(B
    hrtimer_start()
    $B%?%$%^$N3+;O!#%b%N%H%K%C%/;~9o(B(CLOCK_MONOTONIC)$B$+!"%+%l%s%@;~9o(B (CLOCK_REALTIME)$B$+A*$Y$k!#0z?t$O!"@dBP;XDj(B(HRTIMER_MODE_ABS, absolute) $B$+8=:_$+$i$NAjBP(B(HRTIMER_MODE_REL, relative)$B$+;XDj$G$-$k!#(B
    hrtimer_cancel()
    $B%?%$%^$N%-%c%s%;%k!#(B
    schedule_hrtimeout()
    $B;XDj$7$?;~4V$@$18=:_ ktime_get()
    $B%b%N%H%K%C%/;~9o$N ktime_get_real()
    $B%+%l%s%@;~9o$N $BMxMQNc(B1: $B:#$+$i(B($BAjBPE*$K(B) t_nano $BIC8e$K4X?t(B my_timer_handler() $B$r(B1$BEY$@$18F$S$?$$!#(B
        struct hrtimer my_timer;
        hrtimer_init(&my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        my_timer.function = my_timer_handler;
        ...
        hrtimer_start(&my_timer,  ktime_set(0, t_nano), HRTIMER_MODE_REL);
        ...
    
    enum hrtimer_restart my_timer_handler(struct hrtimer *timer)
    {
            ...
            return HRTIMER_NORESTART;
    }
    
    • $B%O%s%I%i$G(B HRTIMER_RESTART $B$r(B return $B$9$k$H!"%?%$%^$,:F@_Dj$5$l$k!#(B
    • HRTIMER_MODE_REL $B$O!"8=:_;~9o$+$i$NAjBPE*$J;~9o$N0UL#!#(B

    $B"#

    $B%G%P%$%9%I%i%$%P$G$O!"CY$$%G%P%$%9$K9g$o$;$k$?$a$K$7$P$i$/BT$C$F$+$i=h(B $BM}$r$7$?$$$3$H$,B?$$!#F@$K3d$j9~$_$N8eH>It(B(bottom-half)$B$G!#(B

    $BNc(B: Ethernet $B$N%I%i%$%P$G%b!<%I$rJQ99$7$F(B 2 $B%^%$%/%mIC$@$1BT$D!#(B

    $BMM!9$JJ}K!$,$"$k!#(B

    • Busy loop
    • $B%9%1%8%e!<%i$r8F$V(B($B%9%j!<%W$9$k(B)$B!#(B

    $B"!6u%k!<%W(B(busy loop)

    $BBT$D$?$a$NC1=c$JJ}K!$O!"6u%k!<%W$r2s$k$3$H!#(B

    $BNc(B1: 10 tick ($B%$%s%?!<%P%k!&%?%$%^$K$h$k3d$j9~$_(B)$B$rBT$D!#(B

    unsigned long timeout = jiffies + 10; // 10 ticks
    while (time_before(jiffies,timeout))
        continue;
    
    $BNc(B2: 2$BICBT$D(B
    unsigned long delay = jiffies + 2*HZ; // 2$BIC(B
    while (time_before(jiffies,timeout))
        continue;
    

    $B"!(Btime_befefore()

    jiffies $B$O!"(B32 $B%S%C%H$J$N$G!"%*!<%P%U%m!<$9$k2DG=@-$,$"$k!#(B $B unsigned long timeout = jiffies + 10; // 10 ticks while (jiffies<timeout) continue; $B0z$-;;$7$F(B 0 $B$HHf3S$9$k$H!"%*!<%P%U%m!<$NLdBj$,2r7h$G$-$k!#(B
    unsigned long timeout = jiffies + 10; // 10 ticks
    while (jiffies-timeout<0)
        continue;
    
    $B linux-3.12.6/include/linux/jiffies.h 101: #define time_after(a,b) \ 102: (typecheck(unsigned long, a) && \ 103: typecheck(unsigned long, b) && \ 104: ((long)((b) - (a)) < 0)) 105: #define time_before(a,b) time_after(b,a) 106: 107: #define time_after_eq(a,b) \ 108: (typecheck(unsigned long, a) && \ 109: typecheck(unsigned long, b) && \ 110: ((long)((a) - (b)) >= 0)) 111: #define time_before_eq(a,b) time_after_eq(b,a)

    $B"!(Bcond_resched()

    $B6u%k!<%W$O!"(BCPU $B$,L5BL$K$J$k$N$GNI$/$J$$!#$=$NBe$o$j$K unsigned long delay = jiffies + 2*HZ; // 2$BIC(B while (time_before(jiffies,timeout)) cond_resched(); $BB>$Kr7o(B)$B;~$K$O!"%9%1%8%e!<%i$r8F$s(B $B$G!"$B"!>.$5$JCY1d(B tick $BC10L(B (10$B%_%jIC(B-1$B%_%jIC(B) $B$G$OBg$-$9$.$k>l9g!">.$5$JCY1d$r void ndelay(unsigned long nsecs) void udelay(unsigned long usecs) void mdelay(unsigned long msecs) udelay() $B$O!"$"$k2s?t$N%k!<%W$G

    udelay() $B$G(B1$B%_%jIC0J>eBT$C$F$O$$$1$J$$!#(B $B%k!<%W$N%$%s%G%C%/%9$,%*!<%P%U%m!<$9$k2DG=@-$,$"$k!#(B

    $B"!(Bschedule_timeout()

    set_current_state( TASK_INTERRUPTIBLE ); // signal $B$G5/$-$k2DG=@-$,$"$k(B
    schedule_timeout( s * HZ );
    
    $Bstruct timer_list $B$,;H$o$l$F$$$k!#(B

    $B"#%9%1%8%e!<%j%s%0$NL\I8(B

    $BI|=,(B($B%*%Z%l!<%F%#%s%0%7%9%F%`(B I$B$NHO0O(B)
    • CPU $B;HMQN($r>e$2$k!#(B
    • $B%9%k!<%W%C%H(B($BC10L;~4VJU$j$N;E;vNL(B)$B$r>e$2$k!#(B
    • $B%?!<%s%"%i%&%s%I;~4V(B($B%W%m%;%9$r@8@.$7$F$+$i40N;$9$k$^$G(B)$B$rC;$/$9$k!#(B
    • $B%l%G%#!&%-%e!<$G$NBT$A;~4V$rC;$/$9$k!#(B
    • $B1~Ez;~4V$rC;$/$9$k!#(B
    • $B%W%m%;%9$K8xJ?$J(B CPU $B;~4V$r3d$jEv$F$k!#(B
    • ($B $BA4It$OF1;~$K$O@.$jN)$?$J$$!#(B

      $B"!%9%1%8%e!<%j%s%0!&%"%k%4%j%:%`(B

      • FCFS (Firt-Come, First-Served), FIFO (First-In First-Out)
      • $B:GC;%8%g%VM%@h(B(Shortest Job First)
      • $BM%@hEY%9%1%8%e!<%j%s%0!#522n>uBV(B(starvation)$B$r5/$3$9!#(B aging $B$GM%@hEY$r>e$2$k!#(B
      • Round-Robin$B!#;~4V9o$_(B(time slice)$B$4$H$K@Z$jBX$($k!#(B

      $B"!M%@h=g0L<0%9%1%8%e!<%j%s%0(B(OS$B0lHL(B)

      • $B%W%m%;%9$4$H$KM%@hEY$r3d$jEv$F$k!#(B
      • OS $B$O!" $B%W%m%;%9$NM%@hEY$O!"MxMQ$7$?(BCPU$B;q8;$dF~=PNO$N%Q%?%s$GF0E*$KJQ99$9$k!#(B

      $B"!%l%G%#!&%-%e!<(B(OS$B0lHL(B)

      $B%l%G%#!&%-%e!<$O!"%l%G%#>uBV$N%W%m%;%9$N%j%9%H!#M%@hEY$N=g$KJB$s$G$$$l(B $B$P!"(BCPU $B$O%j%9%H$N@hF,$+$iMWAG$r$B"#%W%m%;%9!&%9%1%8%e!<%j%s%04XO"$N(BAPI

      $B"!(BUnix$B$K$*$1$k%W%m%;%9$K4X$9$k%7%9%F%`!&%3!<%k(B

      • nice(), getpriority(), setpriority(): nice$BCM(B($BM%@hEY(B)$B$NA`:n!#CM$,>.$5$$J}$,M%@hEY$,9b$$!#(B $B0lHL%f!<%6$O!"CM$rBg$-$/$9$k$3$H$@$1$G$-$k!#(B $BCM$NHO0O$O!"(B-20$B$+$i(B19$B$,IaDL!#(B
      • sched_getscheduler(), sched_setscheduler(): POSIX $B(B)$B!#(B
      • sched_get_priority_max()$B!"(Bsched_get_priority_min(): $B3F%]%j%7!<$G$NM%@hEY$N:GBg$H:G>.$rI=$9@0?tCM!#%7%9%F%`$K$h$C$F@0?tCM$,(B $B0[$J$k!#?t;z$,Bg$-$$J}$,!"M%@hEY$,9b$$!#(Bmin < max $B$K$J$C$F(B $B$$$k!#(B
      $BCm0U(B: Linux $B$=$N$b$N$O!"/$7CY$l$F$b0UL#$,$"$k!J%=%U%H%j%"%k%?%$%`!K$K$O!";H$($k$3$H$,$"$k!#(B

      $B"!(Bps -l$B%3%^%s%I(B

      ps -l $B$N7k2L$N$&$A!" $BI=<((B $B@bL@(B NI Nice$B!#M%@hEY$rI=$9CM!#(B
      $ ps -l [$B
      F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
      0 S  1000 28765 28759  0  80   0 -  1363 wait   pts/0    00:00:00 bash
      0 T  1000 28825 28765  0  80   0 -  1270 signal pts/0    00:00:00 man
      0 T  1000 28832 28825  0  80   0 -  1183 signal pts/0    00:00:00 less
      0 T  1000 28833 28765  0  80   0 -  7606 signal pts/0    00:00:00 emacs
      0 R  1000 28836 28765  0  80   0 -  1216 -      pts/0    00:00:00 ps
      $ /bin/nice ps -l [$B
      F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
      0 S  1000 28765 28759  0  80   0 -  1363 wait   pts/0    00:00:00 bash
      0 T  1000 28825 28765  0  80   0 -  1270 signal pts/0    00:00:00 man
      0 T  1000 28832 28825  0  80   0 -  1183 signal pts/0    00:00:00 less
      0 T  1000 28833 28765  0  80   0 -  7606 signal pts/0    00:00:00 emacs
      0 R  1000 28837 28765  0  90  10 -  1216 -      pts/0    00:00:00 ps
      $ /bin/nice -19 ps -l [$B
      F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
      0 S  1000 28765 28759  0  80   0 -  1363 wait   pts/0    00:00:00 bash
      0 T  1000 28825 28765  0  80   0 -  1270 signal pts/0    00:00:00 man
      0 T  1000 28832 28825  0  80   0 -  1183 signal pts/0    00:00:00 less
      0 T  1000 28833 28765  0  80   0 -  7606 signal pts/0    00:00:00 emacs
      0 R  1000 28841 28765  0  99  19 -  1216 -      pts/0    00:00:00 ps
      $ []
      
      • ps $B%3%^%s%I$N(B NI $B$K$O!"(Bnice$BCM$,I=<($5$l$k!#(B
      • nice $BCM$rJQ99$7$F%W%m%;%9$r@8@.$9$k$K$O!"(Bnice $B%3%^%s%I$,;H$($k!#%G(B $B%U%)%k%H$G(B 10 $B$K@_Dj$5$l$k!#(B

      $B"!(Bgetpriority-pid.c

         1:	/*
         2:	        getpriority-pid.c -- $BM%@hEY$NI=<((B
         3:	        ~yas/syspro/proc/getpriority-pid.c
         4:	        Created on: 2009/12/14 12:15:11
         5:	*/
         6:	
         7:	#include <stdio.h>              /* stderr, fprintf() */
         8:	#include <sys/time.h>           /* getpriority() */
         9:	#include <sys/resource.h>       /* getpriority() */
        10:	#include <stdlib.h>             /* strtol() */
        11:	#include <limits.h>             /* strtol() */
        12:	
        13:	main( int argc, char *argv[] )
        14:	{
        15:	    int which, who, prio;
        16:	    pid_t pid;
        17:	        if( argc != 2 )
        18:	        {
        19:	            fprintf(stderr,"Usage: %% %s pid\n",argv[0] );
        20:	            exit( 1 );
        21:	        }
        22:	        pid = strtol( argv[1], NULL, 10 );
        23:	        prio = getpriority( PRIO_PROCESS, pid );
        24:	        printf("pid==%d, priority==%d\n", pid, prio);
        25:	}
      
      $ echo $$ [$B
      3788
      $ ./getpriority-pid  [$B
      Usage: % ./getpriority-pid pid
      $ ./getpriority-pid $$ [$B
      pid==3788, priority==0
      $ ./getpriority-pid 0  [$B
      pid==0, priority==0
      $ nice -10 ./getpriority-pid 0  [$B
      pid==0, priority==10
      $ nice -20 ./getpriority-pid 0 [$B
      pid==0, priority==19
      $ []
      
      • $B%7%'%k$N(B PID $B$O!"(B$$ $B$H$$$&JQ?t$G;2>H$G$-$k!#(B
      • PID $B$H$7$F(B 0 $B$r;XDj$9$k$H!"<+J,<+?H(B($B%7%'%k$+$i7Q>5(B)$B$,I=<($5$l$k!#(B
      • nice $B%3%^%s%I$GCM$rBg$-$/$G$-$k!#:GBg(B20$B!#(B ($BFC8"%f!<%6$O!"CM$r>.$5$/$G$-$k!#(B)

      $B"!(Bnice$BCM$NMxMQK!(B

      $BM%@hEY$ND4@0J}K!(B
      • $B ($BBPOCE*$J=hM}$GF~=PNO$GBT$A$,B?$$%W%m%;%9$NM%@hEY$r>e$2$k!#(B)
      nice$BCM$N87L)$J!V0UL#!W$O!"(BUnix $B$N$B"!(BLinux(CFS)$B$G$NDL>o$N%W%m%;%9(B($BHs
      • nice$BCM$,(B1$BA}$($k$H!"AjBPE*$K(B10%$B$@$1(BCPU$B;~4V$N3dEv$F$,>/$J$/$J$k$h$&$K$9$k!#(B
      $BNc(B1: $B
    • $B%W%m%;%9(BA: nice$BCM(B0
    • $B%W%m%;%9(BB: nice$BCM(B1 ($BM%@hEY$,Dc$$(B)
    A$B$N(BCPU$B;~4V(B : B$B$N(BCPU$B;~4V(B == 1 : 0.9

    $B"!(Bps $B%3%^%s%I$G$N

    # ps -o state,uid,pid,ppid,policy,pri,ni,rtprio,time,comm [$B
    S   UID   PID  PPID POL PRI  NI RTPRIO     TIME COMMAND
    S     0 29103 29041 TS   19   0      - 00:00:00 su
    S     0 29110 29103 TS   19   0      - 00:00:00 bash
    T     0 29226 29110 TS   19   0      - 00:00:00 emacs
    T     0 29227 29110 TS   19   0      - 00:00:00 man
    T     0 29234 29227 TS   19   0      - 00:00:00 less
    R     0 29247 29110 TS   19   0      - 00:00:00 ps
    # /bin/nice --10 ps -o state,uid,pid,ppid,policy,pri,ni,rtprio,time,comm [$B
    S   UID   PID  PPID POL PRI  NI RTPRIO     TIME COMMAND
    S     0 29103 29041 TS   19   0      - 00:00:00 su
    S     0 29110 29103 TS   19   0      - 00:00:00 bash
    T     0 29226 29110 TS   19   0      - 00:00:00 emacs
    T     0 29227 29110 TS   19   0      - 00:00:00 man
    T     0 29234 29227 TS   19   0      - 00:00:00 less
    R     0 29248 29110 TS   29 -10      - 00:00:00 ps
    # chrt 50 ps -o state,uid,pid,ppid,policy,pri,ni,rtprio,time,comm [$B
    S   UID   PID  PPID POL PRI  NI RTPRIO     TIME COMMAND
    S     0 29103 29041 TS   19   0      - 00:00:00 su
    S     0 29110 29103 TS   19   0      - 00:00:00 bash
    T     0 29226 29110 TS   19   0      - 00:00:00 emacs
    T     0 29227 29110 TS   19   0      - 00:00:00 man
    T     0 29234 29227 TS   19   0      - 00:00:00 less
    R     0 29249 29110 RR   90   -     50 00:00:00 ps
    # []
    
    • ps $B%3%^%s%I$G(B -o $B$rM?$(!"(Brtprio $B$r;XDj$9$k!#(B
    • "-" $B$NI=<($O!" root ($BFC8"%f!<%6(B) $B$J$i$P!"M%@hEY$r>e$2$F%W%m%0%i%`$r root ($BFC8"%f!<%6(B) $B$J$i$P!"

      $B"!%9%1%8%e!<%j%s%0$r9T$&$?$a$N%O!<%I%&%'%"(B

      $B$d$j$?$$$3$H$NNc(B: $B:#$N%W%m%;%9$r(B 50$B%_%jIC$@$1

      • $BL\3P$^$7;~7W$r;H$&!#$"$k;~4V$,$?$C$?$i3d$j9~$_$rH/@8$5$;$k%O!<%I%&%'(B $B%"$rMQ$$$k!#(B $BNc(B: 50$B%_%jIC8e$K%;%C%H$7$F!"%W%m%;%9$r $BDj4|E*$J3d$j9~$_$r;H$&!#(B $BNc(B: 10$B%_%jIC4V3V$G!"3d$j9~$_$r3]$1$k$h$&$K$7$+$1$k!#%W%m%;%9$N Unix $B$G$O!"Dj4|E*$J3d$j9~$_(B(10$B%_%jIC$+$i(B1$B%_%jIC$K(B1$B2s(B)$B$r;H$&J}K!$,$h$/;H$o$l$k!#(B 1$B2s$N3d$j9~$_$r(B tick $B$H$$$&!#(B

        $B"#(BLinux task$B9=B$BN$H(Bnice$BCM(B

        Linux $B$N%W%m%;%9$O!"(Btask $B9=B$BN$GI=8=$5$l$F$$$k!#(B

        $B"!(Btask_struct$B9=B$BN(B

        linux-3.12.6/include/linux/sched.h
        
        1023:	struct task_struct {
        1024:	        volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
        ...
        1039:	        int prio, static_prio, normal_prio;
        1040:	        unsigned int rt_priority;
        1041:	        const struct sched_class *sched_class;
        1042:	        struct sched_entity se;
        1043:	        struct sched_rt_entity rt;
        ...
        1066:	        unsigned int policy;
        ...
        1414:	};
        
         966:	struct sched_entity {
        ...
         968:	        struct rb_node          run_node;
        ...
         970:	        unsigned int            on_rq;
        ...
         974:	        u64                     vruntime;
        ...
         995:	};
        
        struct task_struct $B$NCf$K!"(Bprio $BEy$N%U%#!<%k%I$d(Bstruct sched_entity $B$,(B $B$"$k!#(B

        $B"!(Bpolicy

        Linux $B$G$O!"%9%1%8%e!<%j%s%0$N%]%j%7!<$,Bg$-$/(B2$Bo$N;~J,3d$H linux-3.12.6/include/uapi/linux/sched.h 36: #define SCHED_NORMAL 0 37: #define SCHED_FIFO 1 38: #define SCHED_RR 2 39: #define SCHED_BATCH 3 40: /* SCHED_ISO: reserved but not implemented yet */ 41: #define SCHED_IDLE 5
        SCHED_NORMAL
        $BEAE}E*$J%W%m%;%9!#;~J,3d(B(time sharing)
        SCHED_BATCH
        $B%Q%C%A8~$1!#0lEY(BCPU$B$r3d$jEv$F$?$i2# SCHED_IDLE
        nice 19 $B$h$j$bDc$$M%@hEY!#(B
        SCHED_FIFO (first in first out)
        $B SCHED_RR (round robin)
        $B

        $B"!(Bprio$B$H(Bstatic_prio

        static_prio
        nice$BCM$rJ];}$9$k!#$?$@$7!"H(B)$B!#(B
        • nice$BCM$NHO0O(B -20..19 $B$r(B 0..39 $B$K$9$k$?$a$K(B 20
        • $B
          prio
          $B%9%1%8%e!<%j%s%0$KMQ$$$kM%@hEY$rJ];}$9$k!#(B
        prio $B$r8+$k$H!"DL>o$N%W%m%;%9$+e$J$i!"DL>o$N%W%m%;%9!#DL>o$N%W%m%;%9$N(B prio $B$O!"(B100$B$+$i(B140$B!#(B

        $B"!(Bgetpriority()$B%7%9%F%`!&%3!<%k(B

        linux-3.12.6/kernel/sys.c
        
         227:	/*
         228:	 * Ugh. To avoid negative return values, "getpriority()" will
         229:	 * not return the normal nice-value, but a negated value that
         230:	 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
         231:	 * to stay compatible.
         232:	 */
         233:	SYSCALL_DEFINE2(getpriority, int, which, int, who)
         234:	{
         235:	        struct task_struct *g, *p;
         236:	        struct user_struct *user;
         237:	        const struct cred *cred = current_cred();
         238:	        long niceval, retval = -ESRCH;
         239:	        struct pid *pgrp;
         240:	        kuid_t uid;
         241:	
         242:	        if (which > PRIO_USER || which < PRIO_PROCESS)
         243:	                return -EINVAL;
        ...
         247:	        switch (which) {
         248:	                case PRIO_PROCESS:
         249:	                        if (who)
         250:	                                p = find_task_by_vpid(who);
         251:	                        else
         252:	                                p = current;
         253:	                        if (p) {
         254:	                                niceval = 20 - task_nice(p);
         255:	                                if (niceval > retval)
         256:	                                        retval = niceval;
         257:	                        }
         258:	                        break;
         259:	                case PRIO_PGRP:
        ...
         259:	                case PRIO_PGRP:
        ...
         270:	                case PRIO_USER:
        ...
         289:	        }
        ...
         294:	        return retval;
         295:	}
        
        linux-3.12.6/include/linux/sched/rt.h
          17:	#define MAX_USER_RT_PRIO        100
          18:	#define MAX_RT_PRIO             MAX_USER_RT_PRIO
          19:	
          20:	#define MAX_PRIO                (MAX_RT_PRIO + 40)
          21:	#define DEFAULT_PRIO            (MAX_RT_PRIO + 20)
        
        linux-3.12.6/kernel/sched/sched.h
          28:	#define NICE_TO_PRIO(nice)      (MAX_RT_PRIO + (nice) + 20)
          29:	#define PRIO_TO_NICE(prio)      ((prio) - MAX_RT_PRIO - 20)
          30:	#define TASK_NICE(p)            PRIO_TO_NICE((p)->static_prio)
        
        linux-3.12.6/kernel/sched/core.c
        3200:	int task_nice(const struct task_struct *p)
        3201:	{
        3202:	        return TASK_NICE(p);
        3203:	}
        
        • getpriority() $B$O!"(Bwhich $B$H(B who $B$N(B 2$B0z?t!#(B
        • which $B$,(B PRIO_PROCESS $B$J$i!"(Bwho $B$O!"(Bpid$B!#(B
        • who $B$,(B 0 $B$J$i!"<+J,<+?H(B(current)$B!#(B
        • who $B$,(B 0 $B0J30$J$i(B find_task_by_vpid()$B$G%W%m%;%9$rC5$9!#(B
        • $B%W%m%;%9$,8+$D$+$l$P!"(Btask_nice() $B$G(B task_struct $B$N(B static_prio $B$NCM$rJV$9!#(B $B$3$N;~!"(B $B%2%?$r$O$+$;$?J,(B $B%2%?$r$O$+$;$?J,$r0z$/!#(B
        • $B$5$i$K!"%7%9%F%`!&%3!<%k$,Ii$NCM$rJV$9$H%(%i!<$N0UL#$K$J$k$N$G!"$=(B $B$l$rHr$1$k$?$a$K@5$NCM$KCV49$($k!#6qBNE*$K$O!"(B-20,-19,-18,...17,18,19 $B$r(B 40,39,38,...,3,2,1 $B$KJQ49$9$k!#(B
        • $B@5$NCM$KCV49$($i$l$?CM$O!"%f!<%66u4V$N%i%$%V%i%j$G85$K$b$I$5$l$k!#(B

        glibc-2.5/sysdeps/unix/sysv/linux/getpriority.c
          28:   #define PZERO 20
        ...
          35:   int
          36:   getpriority (enum __priority_which which, id_t who)
          37:   {
          38:     int res;
          39:
          40:     res = INLINE_SYSCALL (getpriority, 2, (int) which, who);
          41:     if (res >= 0)
          42:       res = PZERO - res;
          43:     return res;
          44:   }
        

        $B"!(Bse.load.weight

        struct task_struct $B$N(B static_prio $B$O!"(Bstruct task_struct $B$N(B se.load.weight $B$NCM$r7h$a$k$?$a$K;H$o$l$k!#(B
        linux-3.12.6/kernel/sched/sched.h
         912:	/*
         913:	 * Nice levels are multiplicative, with a gentle 10% change for every
         914:	 * nice level changed. I.e. when a CPU-bound task goes from nice 0 to
         915:	 * nice 1, it will get ~10% less CPU time than another CPU-bound task
         916:	 * that remained on nice 0.
         917:	 *
         918:	 * The "10% effect" is relative and cumulative: from _any_ nice level,
         919:	 * if you go up 1 level, it's -10% CPU usage, if you go down 1 level
         920:	 * it's +10% CPU usage. (to achieve that we use a multiplier of 1.25.
         921:	 * If a task goes up by ~10% and another task goes down by ~10% then
         922:	 * the relative distance between them is ~25%.)
         923:	 */
         924:	static const int prio_to_weight[40] = {
         925:	 /* -20 */     88761,     71755,     56483,     46273,     36291,
         926:	 /* -15 */     29154,     23254,     18705,     14949,     11916,
         927:	 /* -10 */      9548,      7620,      6100,      4904,      3906,
         928:	 /*  -5 */      3121,      2501,      1991,      1586,      1277,
         929:	 /*   0 */      1024,       820,       655,       526,       423,
         930:	 /*   5 */       335,       272,       215,       172,       137,
         931:	 /*  10 */       110,        87,        70,        56,        45,
         932:	 /*  15 */        36,        29,        23,        18,        15,
         933:	};
        
        linux-3.12.6/kernel/sched/core.c
         749:	static void set_load_weight(struct task_struct *p)
         750:	{
         751:	        int prio = p->static_prio - MAX_RT_PRIO;
         752:	        struct load_weight *load = &p->se.load;
        ...
         763:	        load->weight = scale_load(prio_to_weight[prio]);
         764:	        load->inv_weight = prio_to_wmult[prio];
         765:	}
        
        linux-3.12.6/kernel/sched/sched.h
          64:	# define scale_load(w)          (w)
        
        • struct task_struct $B$NM%@hEY(B static_prio $B$O!"(Bstruct task_struct $B$N(B struct sched_entity se $B$N(B se.load.weight $B$H$=$N5U?t(Bse.load.inv_weight$B!!(B $B$KH?1G$5$l$k!#(B
        • se.load.{weight,inv_weight} $B$NCM$O!"8e$K!"(Bvruntime $B$N7W;;(B $B$N=E$_$E$1$K;H$o$l$k!#(B

        $B"#%9%1%8%e!<%i$H%l%G%#!&%-%e!<(B

        $B"!(Bsched_class

        $B%*%V%8%'%/%H;X8~$N%/%i%9$HF1$80UL#!#(B $B%9%1%8%e!<%i$N$?$a$N sched_class$B$N $BL>A0(B $B@bL@(B enqueue_task $B%W%m%;%9$, dequeue_task $B%W%m%;%9$, yield_task CPU$B$r>y$k!#(Bdequeue$B$7$F(Benqueue check_preempt_curr $B pick_next_task $B set_curr_task $B%9%1%8%e!<%j%s%0!&%/%i%9$,JQ99$5$l$?(B task_tick $B%?%$%^3d9~$_(B(tick)$B$N;~$K8F$P$l$k(B task_new $B?7$7$$%W%m%;%9$,@8@.$5$l$?(B

        $B"!(Bsched_class$B;H$$J}(B

        $B%W%m%;%9$N%/%i%9$K1~$8$F(B enqueue$B!"(B dequeue $B$NA`:n$r@Z$jBX$($k!#(B
        linux-3.12.6/kernel/sched/core.c
        
         767:	static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
         768:	{
         769:	        update_rq_clock(rq);
         770:	        sched_info_queued(p);
         771:	        p->sched_class->enqueue_task(rq, p, flags);
         772:	}
         773:	
         774:	static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
         775:	{
         776:	        update_rq_clock(rq);
         777:	        sched_info_dequeued(p);
         778:	        p->sched_class->dequeue_task(rq, p, flags);
         779:	}
        
        • $B%W%m%;%9$N%/%i%9$K1~$8$F(B struct task_struct $B$N(B sched_class $B$NCM$,0c$&!#(B
        • $B%W%m%;%9$N%/%i%9$K1~$8$F!"(Benqueue_task(), dequeue_task() $B$OJL$N4X(B $B?t$,8F$P$l$k!#(B

        $B"!(BLinux$B$N

        fair_sched_class
        $B8xJ?$rL\;X$9!#(Btask_struct $B$N(B policy $B$,(B SCHED_NORMAL $B$N;~$K;H$o$l$k!#(B
        rt_sched_class
        $B

        $B"!%9%1%8%e!<%i!&%/%i%9$N@_Dj(B

        linux-3.12.6/kernel/sched/core.c
        3253:	static void
        3254:	__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
        3255:	{
        3256:	        p->policy = policy;
        3257:	        p->rt_priority = prio;
        3258:	        p->normal_prio = normal_prio(p);
        3259:	        /* we are holding p->pi_lock already */
        3260:	        p->prio = rt_mutex_getprio(p);
        3261:	        if (rt_prio(p->prio))
        3262:	                p->sched_class = &rt_sched_class;
        3263:	        else
        3264:	                p->sched_class = &fair_sched_class;
        3265:	        set_load_weight(p);
        3266:	}
        
        linux-3.12.6/include/linux/sched/rt.h
          23:	static inline int rt_prio(int prio)
          24:	{
          25:	        if (unlikely(prio < MAX_RT_PRIO))
          26:	                return 1;
          27:	        return 0;
          28:	}
        
        • task_struct $B$N(B sched_class $B$O!"(B p->prio $B$NCM$K1~$8$F(B &rt_sched_class $B$+(B &fair_sched_class $B$N$I$A$i$+$r;X$9!#(B
        • if $BJ8$NCf$KF~$C$F$$$k(B likely() $B$d(B unlikely() $B$OL5;k$7$FNI$$!#(B ($BJ,4tM=B,$K$h$k:GE,2=$K;H$o$l$k!#(B)

        $B"!(BCFS(Completely Fair Scheduler)

        CFS $B$O!"(BLinux $B$N%9%1%8%e!<%i$N8GM-L>;l!#(B fair $B$rL\;X$7$F$O$$$k$,!"(Bcomplete $B$K(B fair $B$+$H8@$o$l$k$HITL@!#(B

        Linux CFS $B$O!"

      • $B3F%W%m%;%9$N(B se.vruntime ($B%J%NICC10L(B) $B$,>CHq$7$?(BCPU$B;~4V$r$b$D!#(B
      • $B%W%m%;%9$O!"(Bse.vruntime $B$,>.$5$$=g$K%=!<%H$5$l$?%j%9%H$K$D$J$,$l$k!#(B
      • $B%9%1%8%e!<%i$O!"(Bse.vruntime $B$,:G$b>.$5$$%W%m%;%9(B($B%j%9%H$N0lHV:8(B) $B$r $B%9%1%8%e!<%i$O!" $B$"$kDxEY!".$5$/$J$k!#$=$&$J$k$H!"%j%9%H$r:n$jD>$9!#8=:_ $B:n$jD>$7$?%j%9%H$+$i(B se.vruntime $B$,:G$b>.$5$$%W%m%;%9(B($B%j%9%H$N0lHV(B $B:8(B) $B$r $B$?$@$7!"$"$^$j7c$7$/@Z$jBX$($k$H!"%-%c%C%7%e$,8z$+$J$/$J$k$N$G!"$"(B $B$k(B granularity $B$O!"

        $B"!(Brunqueues($B%j%9%HE*$J8+J}(B)

        Linux $B$K$*$1$k(B ready queue $B$N(B1$B

        runqueue$B!

        $B?^(B? runqueue$B$N9=B$(B

        linux-3.12.6/kernel/sched/sched.h
         402:	struct rq {
        ...
         428:	        struct cfs_rq cfs;
         429:	        struct rt_rq rt;
        ...
         526:	};
        
         249:	struct cfs_rq {
        ...
         259:	        struct rb_root tasks_timeline;
         260:	        struct rb_node *rb_leftmost;
        ...
         327:	};
        
        linux-3.12.6/kernel/sched/core.c
         113:	DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
        
        • (CPU$B$4$H$K(B) runqueue $B$,$"$k!#(B
        • runqueue $B$K$O!"(BCFS(Completely Fair Scheduler))$B$N$?$a$N9=B$BN(B cfs_rq (cfs run queue)$B$,$"$k!#(B
        • cfs_rq $B$K$O!"(Btasks_timeline $B$,$"$k!#(B
        • tasks_timeline $B$O!"%W%m%;%9(B(task_struct) $B$N(B se (struct sched_entity) $B$rDL$8$F!"%W%m%;%9$N%j%9%H$r;}$C$F$$$k!#(B

        $B"!@V9uLZ(B(red-black tree (rbtree))

        $B@V9uLZ(B(red-black tree) $B$O!"J?9UFsJ,C5:wLZ(B(self-balancing binary search tree)$B$N0l

        $BFsJ,C5:wLZ$H$O!"
      • $B3F@a$K%-!<$,$"$k!#(B
      • $B:8$NItJ,LZ$O!":,$h$j$b>.$5$$%-!<$@$1$r$b$D!#(B
      • $B1&$NItJ,LZ$O!":,$h$j$bBg$-$$%-!<$@$1$r$b$D!#(B
      $BJ?9ULZ(B(balanced tree)$B!"$^$?$O!"9b$5J?9ULZ(B(height-balanced tree)$B$O!"G$0U(B $B$N@a$G:81&$N9b$5$N:9$,0lDj0J2

      Linux $B$G$O!"@V9uLZ$r%=!<%H$5$l$?MWAG$,JB$V%j%9%H$r$B"!(BLinux red-black tree$B$N4pK\A`:n(B $B7?Dj5A$G!"3FMWAG$K
    • struct rb_node node (rb_right, rb_left, rb_parent_color)
    • $B%-!<$K$J$k%U%#!<%k%I(B
    $B8!:w(B
    1. $B8=:_$N%N!<%I$H%-!<$rHf3S(B
    2. $BEy$7$$$J$i8+$D$+$C$?(B
    3. $B%-!<$,>.$5$$$J$i:8$N;^$X(B
    4. $B%-!<$,Bg$-$$$J$i1&$N;^$X(B
    5. $B;^$,$J$1$l$P%-!<$OB8:_$7$J$$(B
    $BA^F~(B
    1. $B$^$:8!:w$9$k!#8=:_$N%N!<%I$HA^F~$7$?$$%G!<%?$N%-!<$rHf3S$9$k!#(B
    2. $B%-!<$,>.$5$$$J$i:8$N;^$r!V?F!W$K$7$F8!:w$rB3$1$k!#(B
    3. $B%-!<$,Bg$-$$$J$i1&$N;^$r!V?F!W$K$7$F8!:w$rB3$1$k!#(B
    4. $B%-!<$,Ey$7$$$J$i%(%i!<(B($B%(%i!<$K$;$:!"=EJ#$r5v$9$3$H$b$"$k(B)
    5. $B;R6!$,$$$J$$!V?F!W$,8+$D$+$k!#(B
    6. $B!V?F!W$+$iA^F~$7$?$$%G!<%?$X$N%j%s%/$r:n@.$9$k(B(rb_link_node())
    7. $BJ?9U$K$J$k$h$&$K$9$k(B(rebalancing, recoloring, rb_insert_color())

    $B"!(Brunqueues(red-black tree)

    $B%l%G%#!&%-%e!<$O!"

    runqueue$B!

    $B?^(B? runqueue$B$N9=B$(B(red-black tree)

    $B"!(B__enqueue_entity()

    __enqueue_entity()$B$O!"(BCFS $B$GLZ9=B$$KMWAG$r(B1$B8DDI2C$9$k4X?t$G$"$k!#(B
    linux-3.12.6/kernel/sched/fair.c
    
     505:	static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
     506:	{
     507:	        struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
     508:	        struct rb_node *parent = NULL;
     509:	        struct sched_entity *entry;
     510:	        int leftmost = 1;
     511:	
     512:	        /*
     513:	         * Find the right place in the rbtree:
     514:	         */
     515:	        while (*link) {
     516:	                parent = *link;
     517:	                entry = rb_entry(parent, struct sched_entity, run_node);
     518:	                /*
     519:	                 * We dont care about collisions. Nodes with
     520:	                 * the same key stay together.
     521:	                 */
     522:	                if (entity_before(se, entry)) {
     523:	                        link = &parent->rb_left;
     524:	                } else {
     525:	                        link = &parent->rb_right;
     526:	                        leftmost = 0;
     527:	                }
     528:	        }
     529:	
     530:	        /*
     531:	         * Maintain a cache of leftmost tree entries (it is frequently
     532:	         * used):
     533:	         */
     534:	        if (leftmost)
     535:	                cfs_rq->rb_leftmost = &se->run_node;
     536:	
     537:	        rb_link_node(&se->run_node, parent, link);
     538:	        rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
     539:	}
    
     470:	static inline int entity_before(struct sched_entity *a,
     471:	                                struct sched_entity *b)
     472:	{
     473:	        return (s64)(a->vruntime - b->vruntime) < 0;
     474:	}
    
    • $BJ?9UFsJ,C5:wLZ$N0l $B%-!<$O!"(Bvruntime$B!#(Bvruntime $B$,>.$5$$$[$I:8$KMh$k!#(B
    • vruntime $B$,8=:_$N%N!<%I$h$j>.$5$1$l$P!":8(B(&parent->rb_left), $BBg$-$1$l$P1&(B(&parent->rb_right) $B$K?J$`!#(B
    • $B0lHV:8$J$i!"%-%c%C%7%e$H$7$F(B cfs_rq->rb_leftmost $B$K$bJ]B8!#(B
    • $B:G8e$K(B rb_insert_color() $B$r8F$S=P$7$F!"%P%i%s%9$r2sI|$9$k!#(B

    $B"!(Btick$B$4$H$N;E;v(B

    scheduler_tick() $B$O!"(Btick $B$4$H$KDj4|E*$K8F$S=P$5$l$k!#(B 1 tick $B$O!"(B10 $B%_%jIC!"(B4$B%_%jIC!"(B1 $B%_%jICEy$,0lHLE*!#(B
    linux-3.12.6/kernel/sched/core.c
    2154:	void scheduler_tick(void)
    2155:	{
    2156:	        int cpu = smp_processor_id();
    2157:	        struct rq *rq = cpu_rq(cpu);
    2158:	        struct task_struct *curr = rq->curr;
    ...
    2164:	        curr->sched_class->task_tick(rq, curr, 0);
    ...
    2175:	}
    
    • sched_class $B%/%i%9$N(B task_tick() $B$r8F$S=P$9!#(B

    $B"!(BCFS$B$N(Bentity_tick()

    linux-3.12.6/kernel/sched/fair.c
    
    5898:	static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
    5899:	{
    5900:	        struct cfs_rq *cfs_rq;
    5901:	        struct sched_entity *se = &curr->se;
    5902:	
    5903:	        for_each_sched_entity(se) {
    5904:	                cfs_rq = cfs_rq_of(se);
    5905:	                entity_tick(cfs_rq, se, queued);
    5906:	        }
    ...
    5912:	}
    
    2022:	static void
    2023:	entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
    2024:	{
    ...
    2028:	        update_curr(cfs_rq);
    ...
    2054:	        if (cfs_rq->nr_running > 1)
    2055:	                check_preempt_tick(cfs_rq, curr);
    2056:	}
    
     724:	static void update_curr(struct cfs_rq *cfs_rq)
     725:	{
     726:	        struct sched_entity *curr = cfs_rq->curr;
     727:	        u64 now = rq_clock_task(rq_of(cfs_rq));
     728:	        unsigned long delta_exec;
    ...
     738:	        delta_exec = (unsigned long)(now - curr->exec_start);
    ...
     742:	        __update_curr(cfs_rq, curr, delta_exec);
     743:	        curr->exec_start = now;
    ...
     754:	}
    
     707:	static inline void
     708:	__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
     709:	              unsigned long delta_exec)
     710:	{
     711:	        unsigned long delta_exec_weighted;
    ...
     718:	        delta_exec_weighted = calc_delta_fair(delta_exec, curr);
     719:	
     720:	        curr->vruntime += delta_exec_weighted;
    ...
     722:	}
    
    • task_tick_fair() $B$O!"(Btick $B$4$H$KDj4|E*$K8F$S=P$5$l$k!#(B
    • task_tick_fair() $B$O!"(Bentity_tick() $B$r8F$V!#(B
    • entity_tick() $B$O!"(Bupdate_curr() $B$r8F$V!#(B
    • update_curr() $B$O!"$^$:!"8=:_$N;~9o$r(B struct cfs_rq $B$+$iF@$F$$$k!#(B
    • $B $B$3$l$r!"0z?t$K(B __update_curr() $B$r8F$S=P$7$F$$$k!#(B
    • __update_curr() $B$O!"(Bdelta_exec$B!!$r$5$^$6$^$JMWAG$K2C$($F$$$k!#(B
    • curr ($B8=:_

      $B"#2]Bj(B4 $B;~9o$H;~4V$N4IM}!"%W%m%;%9$N%9%1%8%e!<%j%s%0(B

      $B!zLdBj(B(401) PIT

      PIT (Programmable Interval Timer)$B$G$O!"(B $BH/?64o$N<~GH?t$O!"(B1193182Hz $B$G$"$k!#(B $B:F@_DjMQ$N%l%8%9%?$r(B 11931 $B$K@_Dj$7$?$i!"(B $B2?IC$K(B1$B2s!"3d$j9~$_$,H/@8$9$k$+!#(B

      $B!zLdBj(B(402) $B%b%N%H%K%C%/;~9o$NMxMQ(B

      $B%+!<%M%k$NCf$G!"%+%l%s%@;~9o$G$O$J$/$F%b%N%H%K%C%/;~9o$,;H$o$l$F$$$k>l(B $B=j$,$"$k!#$=$NM}M3$r4JC1$K@bL@$7$J$5$$!#$=$N>l=j$r%+%l%s%@;~9o$r;H$&$h(B $B$&$K$9$k$H!"!V$"$kA`:n$r$7$?>l9g!W$K!V$"$kITET9g!W$,@8$8$k!#$3$N$3$H$r!"(B $BNc$r;H$C$F@bL@$7$J$5$$!#(B

      $B!zLdBj(B(403) struct timer_list$B$NMxMQ(B

      $B4X?t(Bf()$B$r void h(int a,int b, int c) { .... } $B$3$l$r struct timer_list my_timer; int my_arg_a,my_arg_b,my_arg_c; void f(unsigned long data) { init_timer( /*$B6uMs(B(a)*/ ); my_timer.expires = /*$B6uMs(B(b)*/; my_timer.data = 0; my_timer.function = /*$B6uMs(B(c)*/; /*$B6uMs(B(d)*/; } void my_timer_func(unsigned long data) { h( my_arg_a,my_arg_b,my_arg_c ); }

      $B!zLdBj(B(404) nice$BCM(B

      $BNc(B1: $B
    • $B%W%m%;%9(BA: nice$BCM(B0 ($BI8=`(B)
    • $B%W%m%;%9(BB: nice$BCM(B1 ($BM%@hEY$,Dc$$(B)
    19$BIC4Vl9g!"%W%m%;%9(BA$B$H%W%m%;%9(BB$B$O!"$=$l$>$l2?IC$:$D(B CPU$B;~4V$,3d$jEv$F$i$l$k$H4|BT$5$l$k$+!#(B

    $B!zLdBj(B(405) $BFsJ,C5:wLZ$K$h$k%l%G%#!&%-%e!<$N

    $B0J2<$N?^$O!"(B4$B$D$NMWAG$r;}$D%j%9%H$rI=$7$F$$$k!#3FMWAG$K$O!"%-!<$,$"$j!"(B $BM%@hEY$rI=$7$F$$$k$b$N$H$9$k!#(B

    head$B!

    $B?^(B? 4$B$D$NMWAG$r;}$D%j%9%H9=B$(B

    $B$3$N%j%9%H$rI=8=$7$?FsJ,C5:wLZ$r#1$D:n$j!"@a$H;^!JLp0u!K$rMQ$$$F?^<($7(B $B$J$5$$!#$?$@$7!"LZ$O%P%i%s%9$r$7$F$$$J$/$F$bNI$$$b$N$H$9$k!#(B

    $BCm0U(B: $B@5$7$$FsJ,C5:wLZ$O!"J#?tB8:_$9$k!#(B


    Last updated: 2014/01/31 17:11:00
    Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>