- tick이 가장 작은 단위의 시간임.
- tick은 곧 interrupt임. HW interrupt임. 즉 tick이 너무 작으면 overhead 걸림.
- 2.4 시절에는 CPU가 대략 수백 MHz였는데 그 때는 tick이 10ms정도였음.
- 2.6 시절에는 CPU 속도가 GHz 단위가 되어 1ms 정도로 하면 overhead가 걸려서 결국 4ms 정도로 하였음.
- 3.x 대는 적어도 2GHz이므로 1ms를 사용함.
- Interrupt가 발생할 경우는 무조건 해당 waiting queue의 process를 runqueue에 올림. tick time과는 관계없음.
- jiffies는 timer interrupt 발생 시마다 1씩 증가하는 전역 변수임.
- jiffies는 32비트이고, jiffies_64를 추가함. 64bit os는 jiffies_64를 추가함.
- jiffies_64는 하위 호환이 되며, 하위 32bit가 jiffies임.
- 참고로 tasklet으로 update 됨.
- HZ(매크로) - 초당 발생하는 tick 개수.
- jiffies = HZ * s
- kernel timer
- 일정 tick 이후에 특정 프로그램 실행해달라고 요청함.
- RTC
- 오늘의 시간을 관리하는 것은 wall time! struct timespec에 있음.
- apps에서는 sleep()이나 usleep()들을 부르는데 그러면 state가 변경됨(wait queue로 감). 그게 싫어서 잠깐만 자게 하려면 for문 돌려야 함!!! kernel에서는 test code 아니면 sleep 쓸 일은 없다!!! 상용 프로그램에 넣으면 안됨!
- 실행 지연이라고 함은 state 변경 없이 작은 지연을 말하며, delay 계열의 함수를 사용하며 for문의 효과를 낼 수 있다. delay는 길게 잡으면 안된다.
- scheduler가 delay를 길게 잡는 경우 특정 max 값과 비교해서 그 것보다 많으면 허용하지 않고 다른 process로 스케쥴 함.
- timer
- 사용법 struct timer_list timer1; timer_init(&timer1); timer1.expires = jiffies + HZ*3; timer1.data = 10; timer1.function = my_func; add_timer(&timer1);
- timer를 쓰는 경우는 process 중에 특정 시점에서 fork() 하여 모체 process와 별개로 일정 시간 후에 다른 program을 실행할 때 주로 사용한다.
- timer도 일종의 interrupt이므로 sleepable 함수를 콜백 함수에 넣으면 안됨.
- 예를 들어 kmalloc()나 kfifo_alloc()같은거(GFP_KERNEL) 쓰면 안됨. 그럴 땐 GFP_ATOMIC flag를 사용하면 됨. ㅋㅋ
- cf. do_irq는 일반적인 irq 처리 루틴임.
- add timer는 linked list로 구현하지 않고 vector 방식으로 구현함. 매 시간 전체 자료구조를 뒤질 수 없자낭 ㅋㅋ
jiffies
댓글 없음:
댓글 쓰기