'Kernel'에 해당되는 글 2건

  1. 2011.05.31 Linux kernel 3.0-rc1 릴리즈
  2. 2011.05.23 time_after() 구조 및 처리방식



2.8을 건너 뛰고.. 리눅스 3.0-rc1을 릴리즈 했다고 LWN에 기사가 떳습니다.

3.0으로 넘어가면서 기존 2.6 버전 올라가는 수준의 패치만 있을뿐

big change는 절대로 없으며 단지 20주년을 기념하는 넘버링이라고 하네요 -_-..

ABI 와 API역시 변화가 없기 때문에... 다행이도...

리눅스 커널 기반으로 뭔가를  개발 하시던 개발자 분들은 긴장할 필요는 없겠네요 ^^;


그래도.. 이렇게 큰 변화없이 버전만 올라가는게 아쉽기는 하네요 ~ ^^;;

2.8, 3.0 ... 은 우리에게 어떤 모습으로 다가올까? 내심 기대하고 있었는데

그나저나 리눅스관련 서적을 다루는 출판사들이 좀 난감 하겠네요 ㅋㅋ

책 내용은 거의 변경된것도 없이.. 3.0 단어만 바꿔서 출판하는건지 ㅎ


'개발&컴퓨터시스템 > Linux Kernel' 카테고리의 다른 글

time_after() 구조 및 처리방식  (0) 2011.05.23
Posted by kabangkle

Linux kernel 에서는 unsigned long 타입의 변수 a와 b 사이에서
a가 b 보다 큰지 검사를 하는 매크로함수로 time_after() 라는 것을 제공한다.

여기서 그냥 "if ( a > b)" 이렇게 검사하면 되는거 아니야 ? 라고 할지 모르겠지만
timer_after()함수의 특성은 a가 overflow되어 값이 b보다 작아지는 경우에도
정상동작을 한다는것이다. 즉. 커널에서 jiffies 변수의 overflow를 고려하여 만든 함수이다.



프로토타입


int time_after(unsigned long a, unsigned long b)
리턴값 ( 1 : a 가 b 보다 크다 , 0 : a 가 b 보다 크지 않다. )



코드설명

time_after() 함수의 코드는 다음과 같다.
#define typecheck(type,x) \
({ type __dummy; \
typeof(x) __dummy2; \
(void)(&__dummy == &__dummy2); \
1; \
})

#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) - (long)(a) < 0))

여기서 typecheck는 항상 1이기 때문에 무시하면 결국 아래와 같은 형태가 된다.
((long)(b) - (long)(a) < 0))

결국 unsigned 형인 a와 b를 signed 형으로 casting 하여 b - a 의 결과가 0보다 작은지 비교하는 것이다.
이렇게 signed 로 casting 된 변수는 밑에 case 1,2,3의 예제와 같이 처리되어 overflow상황에서도
정상동작을 하게 되는것이다. (case2 이 overflow에 대한 예제)


case 1
          b        a
|----------------------------------------|----------------------------------------|
0x00000000                             0x7FFFFFFF 0x8FFFFFFF                            0xFFFFFFFF
0                                            2147483648 -2147483648                                           
-1

"b - a = 음수"
결과가 음수 이기 때문에 a는 b 보다 크다.

case 2 (a가 overflow되어 b보다 작아진 경우)
        a                                                                                                 b
|----------------------------------------|----------------------------------------|
0x00000000                             0x7FFFFFFF 0x8FFFFFFF                            0xFFFFFFFF
0                                            2147483648 -2147483648                                            -1

a가 overflow 되어 b보다 작아진 경우다.
이 경우 time_after()함수처리에 의해서 signed 형으로 casting 되면 "음수b - 양수a" 의 형태가 된다.
즉 "음수b - 양수a" 의 결과는 음수가된다.
결과가 음수 이기 때문에 a는 b 보다 크다.

case 3
                                                        b        a
|----------------------------------------|----------------------------------------|
0x00000000                             0x7FFFFFFF 0x8FFFFFFF                            0xFFFFFFFF
0                                            2147483648 -2147483648                                            -1

그러나 만약에 a와 b가 양수에서 음수로 변경되는 지점을 기준으로 양쪽에 존재하면?
"양수b - (음수a)" 의 계산결는 항상 양수가 되고 잘못된 결과를 리턴하는 것이 아니냐? 라는 의문을 가지게 된다.
그러나 이 지점에서의 "양수b - (음수a)" 결과는 2147483648 보다 큰값을 가지게 되며
결국 이로 인하여 부호가 변경되어 결과값은 음수가된다.
결과가 음수 이기 때문에 a는 b 보다 크다.


주의사항


b 와 a의 gap이 2147483648 이상 벌어지게 되면 의도하지 않은 +,- 부호 변화에 의해서 잘못된 결과를 리턴하게 된다.
이는 HZ가 1000인 linux box 에서 jiffies로 치면 대략 24.5일 정도가 소요되며 time_after() 및 관련 함수를 이용시
비교하는 변수 두개가 2147483648 이상 차이가 나지 않는 다는 전제 하에서 사용이 가능하다.

참고로 time_after64()를 사용하게 되면 292,471,208년 이상 gap벌어져야 잘못된 결과를 리턴한다. time_after64일 경우
마음 편하게 사용하자~


'개발&컴퓨터시스템 > Linux Kernel' 카테고리의 다른 글

Linux kernel 3.0-rc1 릴리즈  (0) 2011.05.31
Posted by kabangkle