稍后填坑
kernel中,每一次时钟中断会trap到kernel code,这个时间间隔称之为jiffies,每秒钟发生的次数为HZ
如果是4核,分配到每个核就是HZ/4
cat /boot/config-`uname -r` | grep '^CONFIG_HZ=' 输出:
CONFIG_HZ=250
cat /proc/interrupts | grep timer && sleep 1 && cat /proc/interrupts | grep timer 输出:
0: 16 0 0 0 IO-APIC 2-edge timer
LOC: 24690231 20180418 15869859 18248079 Local timer interrupts
0: 16 0 0 0 IO-APIC 2-edge timer
LOC: 24690269 20180590 15869980 18248114 Local timer interrupts
上面休眠了1秒,这4个核的时钟中断次数加起来接近250(上面考虑printf略多)
skynet中timer数据结构:
struct timer {
struct link_list near[TIME_NEAR]; // 256个等级list,一般kernel最关注256个jiffies时间之内的定时器
struct link_list t[4][TIME_LEVEL]; // 大于256jiffies的定时器放这里,见后面详述
struct spinlock lock;
uint32_t time; // 从系统启动后经过的滴答数,即多少个1/100秒
uint32_t starttime; // 系统启动时间(绝对时间,单位为秒)
uint64_t current; // 相对时间(相对于starttime)
uint64_t current_point; // 绝对时间
};
上面的成员t:一共4个等级,64的n次方乘以256之内的放在t[n][TIME_LEVEL],单位0.01秒
64*64*64*64*256就是2^32
比如17000秒的定时器,大于64*256*0.01 小于64*256*0.01,所以放在t[1][TIME_LEVEL]队列