태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.
블로그 이미지

haRu™'s Thinks

느리게 걷기, 천천히 생각하기, 그리고 한 발 뒤에서 바라 보기… by haruroh


'Linux Kernel'에 해당되는 글 1건

  1. 2008.01.07 (*(unsigned log *)&jiffies)++의 의미...(do_timer()에서)

(*(unsigned log *)&jiffies)++의 의미...(do_timer()에서)

http://kldp.org/node/21829참조. - 너무 길기에 북마크성 포스트 입니다.
1차적 정리 하면 다음과 같다. 

1. 
jiffies 는 volatile 로 선언해야 한다.
writer는 timer인터럽트 핸들러 함수인 do_timer밖에 
없으므로 원자성을 보장하지 않아도 되지만,
reader입장에서는 언제 do_timer가 jiffies를 수정할지 
모르므로 jiffies변수를 접근할때마다 실제로 메모리에서
읽어와야 합니다.

2. 
그냥 jiffies++ 이렇게 하게 되면,
jiffies가 volatile이기 때문에 jiffies에서 한 번 읽고, 또 jiffies에 한번 써야 한다는
조건이 생깁니다.
movl jiffies, %eax
incl %eax
movl %eax, jiffies 
3.
그런데 어차피 jiffies 의 값을 변화시키는 것은
do_timer 밖에 없으므로
단일 명령으로 컴파일 되면 더 좋겠다는 생각이 든다.

incl _jiffies

4.
그러기 위해 jiffies 의 volatile 속성을 잠시 없애기 위해

(*(unsigned long *)&jiffies)++;

와 같이 한다.

5.
그러나 이건 어디까지나 희망사항일 뿐
4번과 같이 하더라도 컴파일 환경에 따라
2번처럼 될 수도 있다.

6.
do_timer 에 들어오기 전에 이미 인터럽트는 금지된 상태이므로
2번이든 3번이든 원자성과는 아무런 상관없다.
SMP 라 하더라도
어떤 irq에 대한 인터럽트 핸들러는 SMP머신의 여러 CPU중 하나에서만
수행됩니다. (여기에서 "하나"란 "특정한"이 아니고 단지 1개를 뜻합니다)
따라서 원자성같은건 필요가 없죠.

------------------

7. 
extern unsigned long volatile jiffies;

jiffies++;
(*(unsigned long *)&jiffies)++;

semantic 상에서 중요한 차이는 volatile 형한정을 일종의 type
punning (*& hack) 을 통해 제거해 버렸다는 것입니다 - const 나 volatile
같은 형한정어는 lvalue 문맥에서만 유효하기에 형한정어의 의미를 배제하
고 접근하기 위해서는 유사한 트릭을 사용해야만 합니다. 예를 들어,

(*(unsigned long volatile *)&jiffies)++;

는 언어적 규칙

- 동일한 type 으로의 cast 는 무의미하다.
- 이 경우에, 연속적으로 적용된 &, * 는 무의미하다.

에 의해 jiffies++; 와 완전히 동등한 의미가 됩니다 - 물론 추상적인
semantic 단계에서 동등한 의미라고 해서 항상 동일한 코드가 생성된다는
보장은 없습니다만, 분명 다른 코드가 생성되는 경우는 현실적으로 드문 것
이 사실입니다.

결국, 목적 코드로 incl 이 허용되는 이유는 바로 volatile 이 semantic 단
계에서 제거되었기 때문입니다. 어떠한 경우에도 volatile 이 그대로 유지
된다면 gcc 는 변함없이 incl 의 사용을 막을 것입니다.

volatile 이 바로 그것 ("반드시 메모리가 갱신되어야 한다") 을 보장해주
는 것입니다. volatile 은 volatile 로 선언된 대상체의 값이 프로그램 외
부의 어떤 영향에 의해 수정될 수 있거나 혹은 해당 대상체에 접근하는 행
위가 어떤 추가적인 side effect 를 낼 수 있다는 것을 implementation 에
게 알리기 위해 사용됩니다. implementation 이 volatile 대상체에 접근함
으로써 생성되는 구체적인 side effect 를 모두 예측할 수 없다면 C 프로그
램의 abstract semantic (위에서는 증감 연산자의 의미 - 메모리에서 해당
대상체의 값을 읽어서, 하나 증가해서, 다시 해당 대상체로 저장하는 것)
을 그대로 따라 actual implementation 을 구성하도록 요구됩니다.


현제 읽은 부분까지의 핵심 정리입니다. 

http://kldp.org/node/21829#comment-47480 
Comment 0 Trackback 0
Top

prev 1 next