티스토리 뷰
Table of Content
1. Intro
2. 쉬운 API
3. 어려운 API
4. 어려운 API 와 쉬운 API?
5. CPU 소모성 API
6. CPU 소모가 없는 API
7. msleep()
8. msleep_interruptible()
9. ssleep()
10. schedule_timeout_interrupt()
11. schedule_timeout_uninterrupt()
12. schedule_timeout()
13. ndelay(), udelay(), mdelay()
1. Intro
커널에서 시간 지연 함수는 여러가지가 있습니다.
굳이 분류를 하자면 쉬운 API, 어려운 API, CPU 소모성 API, CPU 소모가 없는 API 정도로 나눌 수 있습니다.
2. 쉬운 API
쉬운 API는 크게 보면 아래와 같습니다.
#include <linux/delay.h>
#include <linux/timer.h>
msleep()
ssleep()
이 API들은 함수명대로 micro second, milli second, 1 second 을 뜻합니다.
그냥 사용하시면 됩니다.
3. 어려운 API
어려운 API 는 크게 보면 아래와 같습니다.
#include <linux/delay.h>
#include <linux/timer.h>
msleep_interruptible()
schedule_timeout_interruptible();
schedule_timerout_uninterruptible();
schedule_timeout();
이것도 그냥 사용하면 됩니다.
4. 어려운 API 와 쉬운 API ?
어려운 API 와 쉬운 API 의 차이점은 무엇일까요?
가장 기본이 되는 지연 함수는 schedule_timeout() 입니다.
관계를 살펴보면
ssleep()
-----------------------------------------
msleep()
-----------------------------------------
schedule_timeout_interruptible(), schedule_timeout_uninterruptible
-----------------------------------------
schedule_timeout()
입니다. 위에 그림만으로는 잘 설명이 안될 수도 있는데, 커널 소스를 살펴보면 관계를 확실히 확인 할 수 있습니다.
ssleep() 는 msleep() 를 호출합니다.
msleep() 는 schedule_timeout_uninterrupt() 를 호출합니다.
schedule_timeout_uninterrupt() 는 schedule_timeout() 을 호출합니다.
결국 최종으로 호출되는 것은 schedule_timeout() 인데 시간 지연이라는게 인터럽트를 허용할 수도, 아닐수도 있고 또한 사용상의 편의상 ssleep() 나 msleep() 같은 front-end 를 만들어 쓴다고 생각하면 됩니다.
8. CPU 소모성 API
지정한 지연시간까지 loop 를 돌면서 cpu 시간을 소모하는 형태의 API 입니다.
ndelay();
udelay();
mdelay();
위와 같이 delay 라는 이름이 붙은 API 들이 CPU 소모성 API 이며 아래와 같이 구현할 경우에도 CPU 소모성 API 입니다.
while(time_before(jiffies, j1))
{
cpu_relax();
}
9. CPU 소모가 없는 API
CPU 점유가 없이 시간 지연을 구현하려면 현재 자기자신한테 할당된 프로세스 시간을 반납하고 대기하는 방식을 사용하면 됩니다.
schedule_timeout_interruptible()
schedule_timeout_uninterruptible()
등이 그런 계통입니다.
7. msleep()
header : asm/delay.h
void msleep(unsigned int msecs);
unsigned long msleep_interruptible(unsigned int msecs);
=> 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다.
example
#include <asm/delay.h> static void example_msleep(void) { msleep(1000); } |
8. msleep_interruptible()
header : asm/delay.h
unsigned long msleep_interruptible(unsigned int msecs);
=> 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 있습니다.
example)
#include <asm/delay.h> static void example_msleep(void) { msleep_interruptible(1000); } |
9. ssleep()
header : asm/delay.h
void ssleep(unsigned int seconds);
=> 초단위로 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다.
example)
#include <linux/sched.h> static void example_ssleep(void) { ssleep(2); } |
10. schedule_timeout_interruptible()
header : linux/sched.h
void schedule_timeout_interruptible(unsigned long timeout);
=> timeout 시간만큼 지연해 줍니다.
example)
#include <linux/sched.h> static void example_ssleep(void) { schedule_timeout_interruptible(1 * HZ); /* 1 초간 지연 */ } |
11. schedule_timeout_uninterruptible()
header : linux/sched.h
void schedule_timeout_uninterruptible(unsigned long timeout);
=> timeout 시간만큼 지연해 줍니다. 지연시간도중에는 인터럽트를 받을 수 없습니다.
example)
#include <linux/sched.h> static void example_ssleep(void) { schedule_timeout_uninterruptible(1 * HZ); /* 1 초간 지연 */ } |
12. schedule_timeout()
header : linux/sched.h
void schedule_timeout(unsigned long timeout);
=> timeout 시간만큼 지연해 줍니다. 가장 기본이 되는 함수입니다. 그렇기 때문에 직접 호출하여 사용하지는 않습니다.
example)
#include <linux/sched.h> static void __sched schedule_timeout_interruptible(void long timeout) { __set_current_state(TASK_INTERRUPTIBLE); return schedule_timeout(timeout); } |
13. ndelay, udelay, mdelay
header : linux/delay.h
#define ndelay(n);
#define udelay(n);
#define mdelay(n);
busy wait 방식이어서 cpu 로드가 많은 편입니다. 하지만 간단하게 쓸 수 있는 장점이 있습니다.
example)
#include <linux/delay.h> void delay_test(void long timeout) { ndelay(1000); udelay(1000); mdelay(1000); } |
'Computer > Linux/Unix' 카테고리의 다른 글
디바이스 트리 작성법 (4편) (1) | 2020.02.09 |
---|---|
디바이스 트리 작성법 (2편) (0) | 2020.02.09 |
디바이스와 드라이버의 의미 (0) | 2015.04.10 |
쉘 스크립트의 처음 #!/bin/bash 에 대하여. (0) | 2015.04.06 |
[Kernel Macro] container_of 매크로 (0) | 2015.03.26 |