^^ 현재 ARM 중급 스터디에 참여하여 있는 장성민입니다.
저희가 2주간 계속해서 spin lock에 대한 토론을 하고 있는데, 토론을 하면 할 수록 깊은 수렁속으로 빠져드는 느낌입니다.
수선 UP에서는 spin lock이 사라진다고 하는데, 그 말을 도저히 이해할 수 가 없습니다.
spin lock을 쓴다는 것은 보호하고 싶은 데이터 영역이 분명히 존해하는 것인데, UP라는 이유 하나만으로 사라진 다는 것이 이해가 되지 않네요. 토론을 하는 중에 up에서는 preempt disableh 함수로 변경된다는 의견도 있는데, 그건 좀 설득력이 있는 것 같습니다.
하지만 그렇다 할 지라도 interrupt가 발생해서 그 임계영역을 건드리면 또한 문제가 발생 할 수 있을 것 같습니다.
up / smp 그리고 preempt disalbe / preempt enable 등으로 컴파일 된 경우 그리고 process context / interrupt context 등의 여러 환경에서
spin lock이 정확이 어떻게 동작하는지 개념을 좀 알려주시길 부탁드립니다.
댓글 6
-
백창우
2011.04.25 00:59
-
장성민
2011.04.25 08:37
^^ 감사합니다. 아주 속 시원하게 해결되었습니다.
끝에 적어주신 process context냐 interrupt context 냐에 따라서 다른 것이 interrupt disable 이 다르다는 것의 의미는, Interrupt Context 에서 spin lock을 사용하게 되면 컴파일 과정에서 preempt disable 이 interrupt disable로 변경된다고 생각하면 되나요? ^^
-
백창우
2011.04.25 23:17
네. 정확히는 interrupt save이죠.
-
백창우
2011.04.26 01:24
interrupt_save(&flag)는 이전 interrupt 상태를 저장하고, interrupt를 disable한 후 interrupt_restore(&flag)에 의해 이전 interrupt 상태(enable or disable)로 돌리는 것을 의미합니다.
-
이종인
2011.04.26 00:49
interrupt_save 와 동시에 interrupt_disable() 했다가 나중에 그 save한 것을 복구 하면서 interrupt_enable() 하는걸 말씀하시는 건가요???
-
장성민
2011.04.26 21:17
^^ 와.. 아직 제대로 알기에는 제 실력이 많이 부족하다는 것을 느끼게 되네요.. 하지만 하나씩 시야가 밝아지는 기분입니다.
.
UP이 무엇인지 잠깐 고민했네요. 요즘 커널에는 UP/SMP라는 약자가 사용되나보군요.
uni-processor 환경에서는 spin lock이 사라지는게 맞습니다.
대신 preempt disalbe로 대체되죠.
SMP 환경에서 spin lock을 단순화 시키면 다음과 같은 코드로 구성됩니다.
SpinLock (Lock lock)
BEGIN
VAR f;
PreemptionDisable();
f := InterruptSave();
WHILE (lock->count <> 0);
InterruptRestore(f);
END
위 코드에서 가장 중요한 부분은 lock->count가 0이 될때까지 계속 spin을 돈다는 것입니다.
이는 SMP 환경에서 이러한 가정이 숨어있기 때문입니다.
1. spin lock은 매우 짧은 구간만 사용된다.
2. SMP 환경에서 mutex나 smaphore에 의해 task가 wait 되어 context switch가 발생되는것 보다,
spin lock으로 lock이 풀릴때까지 busy wait하는 것이 훨씬 경제적이다.
3. spin lock을 푸는것은(즉, lock->count를 0으로 만드는것은) lock을 잡은 다른 processor에서 동작하는 task에서
critical section이 끝나는 순간 바로 푼다.
1, 2, 3번의 가정에 의해 SMP 환경에서는 spin lock이 사용되는 것입니다.
그러면 uni-processor 환경에서는 왜 spin lock이 없어지냐 하면, 바로 3번 가정이 사라지기 때문입니다.
uni-processor 환경에서 spin lock을 쓰게 되면 spin lock을 풀수 있는 다른 processor가 없어,
영원히 spin을 돌면서 busy wait하게 되어 있습니다.
uni-processor 환경에서는 preemt disable만 사용해도 critical section을 지켜줄수 있는데,
이는 preempt disable이 하는 역활이 다음과 같기 때문입니다.
PreemptionDisable()
BEGIN
schedLock++;
END
DoScheduling()
BEGIN
IF (schedLock <> 0)
BEGIN
RETURN;
END
newTask := TaskSelect();
IF (currentTask <> newTask)
BEGIN
ContextSwitch(currentTask, newTask);
END
END
spin lock과 preemption disable의 기본 구조는 이렇고, process context냐 interrupt context냐에 대한 차이는,
interrupt context는 최대한 빨리 처리되어야 된다는 가정이 붙고,
사용하는 stack도 다르고, ISR과의 경쟁을 막을수 있는것은 interrupt disable 밖에 없다는것에 의해,
몇가지 필드와 처리 방식이 약간 달라질뿐 기본적인 구조와 기능은 위에서 설명한것과 동일하다 보시면 됩니다.