// 源碼樹路徑:kernel/timer.c
/** Hmm.. Changed this, as the GNU make sources (load.c) seems to* imply that avenrun[] is the standard name for this kind of thing.* Nothing else seems to be standardized: the fractional size etc* all seem to differ on different machines.** Requires xtime_lock to access.*/
unsigned long avenrun[3];/** calc_load - given tick count, update the avenrun load estimates.* This is called while holding a write_lock on xtime_lock.*/
static inline void calc_load(unsigned long ticks)
{unsigned long active_tasks; /* fixed-point */static int count = LOAD_FREQ;count -= ticks;if (count < 0) {count += LOAD_FREQ;active_tasks = count_active_tasks();CALC_LOAD(avenrun[0], EXP_1, active_tasks);CALC_LOAD(avenrun[1], EXP_5, active_tasks);CALC_LOAD(avenrun[2], EXP_15, active_tasks);}
}
/* * Nr of active tasks - counted in fixed-point numbers*/
static unsigned long count_active_tasks(void)
{return (nr_running() + nr_uninterruptible()) * FIXED_1;
}
// 源碼樹路徑:kernel/sched.c
/** nr_running, nr_uninterruptible and nr_context_switches:** externally visible scheduler statistics: current number of runnable* threads, current number of uninterruptible-sleeping threads, total* number of context switches performed since bootup.*/
unsigned long nr_running(void)
{unsigned long i, sum = 0;for (i = 0; i < NR_CPUS; i++)sum += cpu_rq(i)->nr_running;return sum;
}unsigned long nr_uninterruptible(void)
{unsigned long i, sum = 0;for_each_cpu(i)sum += cpu_rq(i)->nr_uninterruptible;return sum;
}
// 源碼樹路徑:include/linux/sched.h
/** These are the constant used to fake the fixed-point load-average* counting. Some notes:* - 11 bit fractions expand to 22 bits by the multiplies: this gives* a load-average precision of 10 bits integer + 11 bits fractional* - if you want to count load-averages more often, you need more* precision, or rounding will get you. With 2-second counting freq,* the EXP_n values would be 1981, 2034 and 2043 if still using only* 11 bit fractions.*/
extern unsigned long avenrun[]; /* Load averages */#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */#define CALC_LOAD(load,exp,n) \load *= exp; \load += n*(FIXED_1-exp); \load >>= FSHIFT;