먼저 크리티컬 섹션의 의미에 대해서 이야기해보죠...
"일반적으로" 크리티컬 섹션이란 어떤 태스크가 "특정한 코드 영역"이나 "특정한 데이터 영역"을 크리티컬 섹션으로 묶으면
다른 태스크나 ISR이 그 "특정한 코드 영역"을 수행하지 못하게 하거나 그 "특정한 데이터 영역"을 접근 못하게 하는 메커니즘입니다.
ISR도 "대기하지 않는" Pend함수를 통해서 세마포어 같은 것을 얻을려고 시도 할수 있고 세마포어를 얻고, 못얻고에 따라서 다르게 동작하니까 ISR도 해당됩니다.
왜 "일반적으로"란 말을 붙였냐 하면 제 생각에는 진정한 크리티컬 섹션의 의미는 이보다 좀더 축소 되어야 한다고 생각하기 때문이에요 그건 좀 있다가...
(물론 그 생각은 바뀝니다^^)
근데 사실 "특정한 코드 영역"을 보호하기 위한건 속으로 계속 들어가다 보면 결국 "특정한 데이터 영역"을 보호하기 위해서에요.
데이터를 보호하는거야 당연히 이해가 되겠죠?^^
그럼 "특정한 코드 영역"을 다른 태스크나 ISR이 수행하는 경우는 어떤경우냐?
제가 생각나는 경우는 함수를 호출 할때 뿐입니다.
근데 그 함수가 비재진입 함수는 당연할테고 재진입함수라도 "특정한 데이터 영역"을 접근하는 경우라면 문제가 되기때문에 결국 "특정한 데이터 영역"을 보호하기 위해서
근본적으로 그 데이터를 접근하는 "특정한 코드 영역"을 크리티컬 섹션으로 묶어야 된다는 말이죠.
고로 크리티컬 섹션이란 인터럽트를 비활성화 해도되고, 스케줄러를 락해도 되고, 세마포어를 써도 되고... 방법은 다양합니다.
결국 크리티컬 섹션을 쓰는 이유는 공유자원을 보호하기 위함이죠.
XX씨가 말한게 틀린게 아니였어요.
"크리티컬 섹션을 보호한다"라는 말도 쓰이더군요...
근데 저는 "크리티컬 섹션을 보호한다"라는 말은 좀 이상해요.
"크리티컬 섹션" 자체가 보호 대상은 아닌거 같거든요.
XX씨가 발견한, 원서에서의 크리티컬 섹션에 대한 설명중 번역서에서는 빠트린
"크리티컬 섹션을 실행하기 전에 '일반적으로' 인터럽트를 비활성화 한다"
uC/OS 책에서 "일반적으로"란 말을 쓴걸 보면 크리티컬 섹션을 꼭 인터럽트를 비활성화 시키는 영역으로 보지는 않고 있다는 거죠.
그럼 문제는 어디서 부터 시작되었느냐?
저는 크리티컬 섹션을 아무생각없이 "무조건 그 영역에 들어있는 코드는 중단없이 모조리 수행되어야 한다"라고 생각했던거죠.
그 코드가 중단이 되지 말아야 하는 이유가 공유자원을 보호하기 위함인데 공유자원을 보호하는거 외에 또 다른 이유에 있어서 Task뿐만 아니라 ISR에 의해서도
중단되지 않을려면 인터럽트를 비활성화 하는 방법밖에 없다고 생각한거죠.
그 방법밖에 없다는 생각이 틀린건 아닌데 공유자원의 보호때문이 아니라 다른경우는 지금 생각으론 없다고 결론을 지었습니다.
만약 그 공유자원 보호때문이 아니라 다른 경우에 있어서 코드 실행이 중단되지 말아야 하는 경우가 있다면 "크리티컬 섹션"을 인터럽트 비활성화 영역이라고
의미를 축소해도 되겠지만... 이제는 그렇게 생각안하기로 했습니다^^
Embedded Systems Dictionary (CMP Books)에 보면...
Critical section :
A seauence of instructions that must be executed in sequence and without interruption to guarantee correct operation of the software.
If the instructions are interrupted, a race condition might occur.
위 문장의 첫번째 문장만 보면 단순히 코드가 중단되지 않아야 하는것만 생각이 들수 있겠지만
아래의 문장까지 읽어보면 중단되지 않아야 하는 이유가 공유자원을 보호하기 위함이라는거죠.
이제 결론을 짓겠습니다.
동의 하시는지 의견 부탁드려요.
태스크가 특정 공유자원에 접근하기 위해서 그 공유자원을 접근하는 코드를
인터럽트를 비활성화 영역에 두든,
스케줄링을 잠그든,
세마포어를 사용하든 어떤 식으로든지 크리티컬 섹션을 통해서 접근하면 된다.
첫째, 인터럽트를 비활성화를 하면 어떠한 Task도 어떠한 ISR도 수행이 되지 않기 때문에 보호가 되고
둘째, 스케줄링을 잠그면 어떠한 Task도 수행이 되지 않아서 보호가 되지만 ISR은 수행이 된다. 이 경우 ISR에서 그 공유자원을 접근하지 않으면 문제가 되지 않는다.
셋째, 세마포어를 사용하면 그 세마포어를 원하는 Task는 수행될수 없지만 그 외 다른 Task나 ISR은 코드를 중단 시킬수있다. 이경우 해당 Task나 ISR에서 그 공유자원을
접근하지 않으면 문제가 되지 않는다.(하기야 세마포어를 원하는 Task로 한정지었으니 다른 Task가 무식하게 Pend도 안하고 공유자원에 접근하려고 하는 짓을 안하는 이상
다른 Task는 신경 쓸 필요도 없네요^^)
결국!!!
크리티컬 섹션을 "코드 실행(실직적인 실행)이 중단되지 않아야 하는 영역"이란 단순한 메커니즘으로 생각 했던게 실수였어요...