본문 바로가기

Programming/Linux_Kernel

linux kernel time resolution & hrtimer




원문 : http://makingdream.tistory.com/20


HZ 와 Jiffies

시스템 타이머들은 프로그램 가능한 주파수 대역에서 프로세서에 끼어(interrupt, pop)든다.  주파수 즉, 초당 타이머 틱들의 수는 커널 변수인 HZ에 포함되어 있다. HZ값은 협상(trade-off)하여 선택된다. 핑거 타이머에서 결과값이 큰 HZ는 좀더 좋은 스케줄링 해결책이다. 그러나, HZ 값들이 커질수록 많은 부하가 발생하며 인터럽트 문맥교환 시간은 더 많은 사이클들이 소모되기 때문에 높은 파워 소비가 발생한다.  

HZ값은 아키텍처에 의존한다. x86 시스템들의 2.4 커널에서는, HZ 값이 기본적으로 100으로 설정된다. 2.6 커널에서는 1000으로 변경된다. 그러나, 2.6.13 커널에서는 250으로 낮아진다. ARM 기반 플랫폼의 2.6 커널에서는 HZ가 100으로 설정된다. 현재의 커널은 빌드시 환경설정 메뉴를 통하여 사용자가 HZ값을 선택할 수 있다. 이 옵션의 기본 설정은 리눅스 배포판에 의존한다. 커널 2.6.21부터는 티클없는 커널(CONFIG_NO_HZ)을 지원한다고 소개 되었다.

Jiffies는 시간들의 개수를 담아두고 있고, 시스템 타이머는 부팅될 때 기동된다. 커널은 jiffies 변수를 매초당 HZ 회수만큼 증가시킨다. HZ값이 100인 커널에서, Jiffy는 10미리초 주기이고, 반면에 HZ가 1000으로 설정된 커널에서는 jiffy가 1미리초 이다.



즉, 우리가 쓰는 android phone 에서 time resolution 은 10ms 이다.

따라서 이 이하의 시간을 맞추려면 hrtimer 를 사용해야 한다.


원문 : http://elinux.org/High_Resolution_Timers

Currently, timers in Linux are only supported at a resolution of 1 jiffy. The length of a jiffy is dependent on the value of HZ in the Linux kernel, and is 1 millisecond on i386 and some other platforms, and 10 milliseconds on most embedded platforms.

Higher resolution timers are needed to allow the system to wake up and process data at more accurate intervals.


hrtimer 의 resolution 확인 가능


hrtimer 예제

원문 : https://gist.github.com/maggocnx/5946907


#include 
#include 
#include 
#include 
 
unsigned long timer_interval_ns = 1e6;
static struct hrtimer hr_timer;
 
enum hrtimer_restart timer_callback( struct hrtimer *timer_for_restart )
{
  	ktime_t currtime , interval;
  	currtime  = ktime_get();
  	interval = ktime_set(0,timer_interval_ns); 
  	hrtimer_forward(timer_for_restart, currtime , interval);
	// set_pin_value(PIO_G,9,(cnt++ & 1)); //Toggle LED 
	return HRTIMER_RESTART;
}
 
static int __init timer_init(void) {
	ktime = ktime_set( 0, timer_interval_ns );
	hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
	hr_timer.function = &timer_callback;
 	hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );
	return 0;
}
 
static void __exit timer_exit(void) {
	int ret;
  	ret = hrtimer_cancel( &hr_timer );
  	if (ret) printk("The timer was still in use...\n");
  	printk("HR Timer module uninstalling\n");
	
}
 
module_init(timer_init);
module_exit(timer_exit);