时间子系统6_高分辨率定时器框架初始化

//	高分辨率定时器框架初始化
//	调用路径:start_kernel->hrtimers_init
//	函数任务:
//		1.创建cpu时钟基础
//		2.注册监听cpu状态变化
//		3.注册高分辨率模式下的定时器软中断
//	注:
//		1.高分辨率定时器框架的通用部分总是编译进内核
//		2.高分辨率定时器框架初始为未激活状态,由低分辨率定时器软中断中切换到高分辨率
1.1 void __init hrtimers_init(void)
{
	//通知clockevent设备管理,创建cpu时钟基础
	hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
			  (void *)(long)smp_processor_id());
	//注册监听cpu 状态信息
	register_cpu_notifier(&hrtimers_nb);
	//高分辨率定时功能通过预处理编译进内核
#ifdef CONFIG_HIGH_RES_TIMERS
	//注册高分辨率模式下的定时器软中断
	open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);
#endif
}
//	cpu状态监听控制块
2.1 static struct notifier_block __cpuinitdata hrtimers_nb = {
	.notifier_call = hrtimer_cpu_notify,
};

//	处理cpu状态变化
//	函数任务:
//		1.cpu up,初始化cpu的时钟基础
//		2.针对热插拔cpu
//			2.1 cpu dying、frozen,选择cpu,接管do_timer
//			2.2 cpu dead、frozen
//				2.2.1 通知clockevent设备管理,cpu dead
//				2.2.2 迁移dead cpu上的hrtimer到本cpu
3.1 static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
					unsigned long action, void *hcpu)
{
	int scpu = (long)hcpu;

	switch (action)
	{
		//cpu up,初始化此cpu的时钟基础
	case CPU_UP_PREPARE:
	case CPU_UP_PREPARE_FROZEN:
		init_hrtimers_cpu(scpu);
		break;
		//下列情况只针对热插拔cpu
#ifdef CONFIG_HOTPLUG_CPU
	case CPU_DYING:
	case CPU_DYING_FROZEN:
		//选择cpu接管do_timer
		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
		break;
	case CPU_DEAD:
	case CPU_DEAD_FROZEN:
		//通知clockevent设备管理,cpu dead
		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
		//迁移cpu上的定时任务到本cpu
		migrate_hrtimers(scpu);
		break;
#endif
	default:
		break;
	}
	return NOTIFY_OK;
}

//	初始化cpu的时钟基础
//	函数任务:
//		1.初始化REALTIME、MONOTOMIC两个时钟基础
//		2.更新时钟基础到期时间为KTIME_MAX,即没有hrtimer会到期
//		3.更新高分辨率定时器未激活状态
//	调用路径:init_hrtimers_cpu->init_hrtimers_cpu
4.1 static void __cpuinit init_hrtimers_cpu(int cpu)
{
	//per cpu时钟基础设备,用于维护该cpu的hrtimer
	struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
	int i;

	raw_spin_lock_init(&cpu_base->lock);
	//初始化cpu时钟基础
	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++)
		cpu_base->clock_base[i].cpu_base = cpu_base;
	hrtimer_init_hres(cpu_base);
}
4.2 static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base)
{
	//下一次事件到期的绝对时间,KTIME_MAX表示没有hrtimer会到期
	base->expires_next.tv64 = KTIME_MAX;
	//高分辨率未激活状态
	base->hres_active = 0;
}

//	cpu时钟基础数据结构
//		提供两种时钟基础
//			CLOCK_MONOTOMIC,系统启动时从0开始,不会跳变,始终单调的运行
//			CLOCK_REALTIME,系统的实际时间,当系统时间改变时,会发生跳变
5.1 struct hrtimer_cpu_base {
	raw_spinlock_t			lock;
	struct hrtimer_clock_base	clock_base[HRTIMER_MAX_CLOCK_BASES];//当前cpu的时钟基础
#ifdef CONFIG_HIGH_RES_TIMERS
	ktime_t				expires_next;	//下一次事件到期的绝对时间
	int				hres_active;		//高分辨率状态
	int				hang_detected;		//最近一次hrtimer检测到挂起
	unsigned long			nr_events;	//中断事件总数
	unsigned long			nr_retries;	//有效的中断事件总数
	unsigned long			nr_hangs;	//中断挂起的次数
	ktime_t				max_hang_time;	//中断处理程序hrtimer_interrupt可花费的最大时间
#endif
}; 

//	时钟基础数据结构
//		hrtimer组织成红黑树的形式
5.2 struct hrtimer_clock_base {
	struct hrtimer_cpu_base	*cpu_base;
	clockid_t		index;			//用于区分CLOCK_MONOTONIC,CLOCK_REALTIME
	struct rb_root		active;		//所有活跃的hrtimer组织在红黑树中,active指向其树根
	struct rb_node		*first;		//第一个到期的hrtimer
	ktime_t			resolution;		//时钟基础的分辨率,纳秒为单位
	ktime_t			(*get_time)(void);	//读取该时钟基础的时间
	ktime_t			softirq_time;	//在软中断中开始运行hrtimer的时间
#ifdef CONFIG_HIGH_RES_TIMERS
	ktime_t			offset;			//时钟相对于单调时钟的偏移
#endif
};
时间: 2024-08-03 23:54:52

时间子系统6_高分辨率定时器框架初始化的相关文章

时间子系统7_高分辨率定时器处理

// 高分辨率下的定时器软中断 // 当增加一个hrtimer到rbtree中后,会raise高分辨率定时器软中断 // 函数任务: // 1.关中断下,运行所有hrtimer // 注: // 在hrtimers_init中,open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq); 1.1 static void run_hrtimer_softirq(struct softirq_action *h) { //遍历运行所有到期的hrtimer h

时间子系统3_低分辨率定时框架初始化

// 低分辨率定时器框架初始化 // 调用路径:start_kernel->init_timers // 函数任务: // 1.创建当前cpu的定时器框架数据结构 // 2.监听cpu状态信息 // 3.注册低分辨率软中断 1.1 void __init init_timers(void) { //创建当前cpu的定时器框架数据结构 int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, (void *)(l

时间子系统4_低分辨率定时器处理

// 触发低分辨率定时器软中断 // 调用路径:update_process_times->run_local_timers // 注: // 1.update_process_times以HZ频率被调用,因此低分辨率定时器的分辨率为HZ // 2.当未激活高分辨率定时器框架时,高分辨率定时器在时钟中断被运行,因此高分辨率定时器的分辨率也HZ 1.1 void run_local_timers(void) { //如果高分辨率定时器框架未激活,则在周期时钟中断中运行高分辨率率定时器 hrtime

Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()【转】

  转自:http://blog.csdn.net/droidphone/article/details/8104433 我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子系统,在时间子系统中提供了一些用于延时或调度的API,例如msleep,hrtimer_nanosleep等等,这些API基于低分辨率定时器或高精度定时器来实现,本章的内容就是讨论这些方便.好用的API是如何利用定时器系统来完成所需的功能的. /*************************

时间子系统5_低分辨率切换高分辨率

// 切换低分辨率动态时钟模式.或高分辨率模式 // 调用路径:run_timer_softirq->hrtimer_run_pending // 函数任务: // 1.如果高分辨率定时器框架已经激活,则直接返回 // 2.切换到高分辨率模式的条件: // 2.1 没有开启低分辨率动态时钟 // 2.2 有高分辨率的clocksource // 2.3 clockevent设备支持单触发模式 // 3.切换到低分辨率动态时钟的条件: // 3.1 启动时,没有激活高分辨率率定时框架 // 3.2

Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)【转】

转自:http://blog.csdn.net/droidphone/article/details/8112948 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 数据结构 低分辨率下的动态时钟 1  切换至动态时钟模式 2  低分辨率动态时钟下的事件中断处理函数 3  动态时钟停止周期tick时钟事件 3  动态时钟重新开启周期tick时钟事件 高精度模式下的动态时钟 动态时钟对中断的影响   在前面章节的讨论中,我们一直基于一个假设:Linux中的时钟事件都是由

时间子系统9_timekeeper初始化

//Timekeeping // Timekeeping子系统负责更新xtime, 调整误差, 及提供get/settimeofday接口. //Times in Kernel //kernel的time基本类型: // 1) system time // A monotonically increasing value that represents the amount of time the system has been running. // 单调增长的系统运行时间, 可以通过time

时间段配置-quartz定时器框架时间配置

问题描述 quartz定时器框架时间配置 我想配置一个任务,触发时间是2014-02-25的每天13:00:00到2014-08-12的每天14:30:00,但中间的法定节日,如五一等(假设五一放假三天)节日不触发,这个如何配置

时间子系统10_hpet时钟初始化

// 时钟mult :mult/2^shift = ns/cyc // 参考:http://www.bluezd.info/archives/reg_clock_event_device_1 // x86平台初始化 // 注:arch/x86/kernel/x86_init.c 1.1 struct x86_init_ops x86_init __initdata = { ... //时钟初始化 .timers = { .setup_percpu_clockev = setup_boot_API