2013-01-21 2 views
4

구조체를 업데이트하고 인터럽트를 비활성화하는 함수가 있습니다.휘발성이 필요합니까?

bool readBuffer() 
{ 
    __disable_irq(); 

    rb->reader += 1; // Just an example 

    __enable_irq(); 

    return true; 
} 

인터럽트가 비활성화되어 있기 때문에 구조의 값을 업데이트하는 동안 다른 인터럽트가 우선 적용되지 않습니다.

하지만 독자 변수를 volatile으로 표시해야합니까? 이론적으로 다른 인터럽트는 함수에 들어가는 동안 선제 할 수 있기 때문에 실제로는 __disable_irq() 전에 호출됩니다. 그리고 내 함수가 다시 시작될 때 rb->reader의 캐시 된 값이 올바르지 않습니다. 또는 컴파일러 (GCC)가 해당 라인이 실제로 적중 될 때까지 rb->reader을 캐시하지 않는 코드를 생성합니까?

+3

Linus Torvalds가 작성한 [volatile consider harmful] (http://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt)을 참조하십시오. '__disable_irq()'는 암시적인 메모리 장벽으로 작용합니까? 그렇다면, 당신은'휘발성 '이 필요없고 그것을 사용하면 다칠뿐입니다. – Celada

답변

1

는 명시 적 최적화 장벽 지정하는 것이 더 좋을 것입니다 수 있음 : 다른 경우에 당신은 컴파일러가 rb->reader 변수를 최적화하려면

bool readBuffer() 
{ 
    __disable_irq(); 
    asm volatile ("" ::: "memory"); // Some unexpected memory modification 
    rb->reader += 1; // Just an example 
    __enable_irq(); 
    return true; 
} 

그것은 수익성이 될 것이다, 따라서 과도한 휘발성을 것이다 표시 .

+0

당신이 제안한 것은 최적의 장벽 인 것 같습니다. 메모리 장벽은 약간 다릅니다. 아마도 asm 섹션에서 'lock'명령 앞에 'asm volatile'("lock; addl $ 0, 0 (%% esp)"::: "memory") 접두사를 붙일 수 있습니다. Joshua가 필요로하는 것은 기억 장벽이지만, 여러분이 제안한 것은 컴파일러에게 'asm'이전에 코드 섹션에 의해 채워진 레지스터의 값에 의존하지 말 것을 암시하는 최적화 장벽처럼 보입니다. 이것은 'rb-> reader + = 1'이 __disable_irq() 후에 만 ​​실행된다는 것을 보증하지 않습니다. –

+0

나는 "휘발성"이라면 최적의 장벽이라고 생각한다. 기억의 장이 아니다. 내 용어를 수정 해 주셔서 감사합니다. 그러나 Joshua는 rb-> reader의 가치를 최적화하는 것에 대해 더 걱정하기 때문에 여기서는 최적화 장벽으로 충분하다고 가정합니다. 그 경우 불가능합니다. –