OS/Pintos Project

[Pintos Project][Getting Start] Need to reading about the "Interrupt" document.

Binceline 2014. 4. 12. 20:40

Pintos Project를 시작하기 전에 반드시 알아야 하는 것이 있다. 

interrupt에 대한 것인데, 문서를 보자면 다음과 같다.

간단하게 동기화 하는 방법은 바로 interrupt를 disable하는 것이다. 이 방법은 임시로 cpu가 interrupt에 응답하는 것을 막는다.

만약 interrupt가 Off되면,  모든 스레드들은 실행 중에 있는 스레드를 선점하려 하지 않는다. 스레드 선점은 timer interrupt에 의해 주어지는 것이기 때문이다. 만약 interrupt가 On이면, 그들은 일반적인 스레드로 변할 것이다. 그리고 실행되는 스레드는 아마 아무때나 다른 스레드들에 의해 선점될 것이다. (CPU 점유를 말하는 것 같음) 이는 2개의 C 구문 사이 또는 하나의 execution 내에서 발생할 수 있다.

Pintos는 선점형 kernel 방식이다. 커널 스레드가 아무때나 선점될 수 있다. 

즉 이 말은 다음과 같이 할 수 있다는 것이다. 이 코드는 pintos에서 OS가 시작된 후부터의 시간을 구하는 timer_ticks() 함수 내용이다. 

int64_t timer_ticks (void) { enum intr_level old_level = intr_disable (); t = ticks; //ticks는 static 전역 변수이다. intr_set_level (old_level); return t; }

// old_level에 현재 상태를 저장하고 disable상태로 변경 -> 다른 스레드들이 cpu를 선점하려 하지 않음

// 그래서 lock을 따로 걸 필요 없이 ticks 값을 저장할 수 있음

// 그 후 다시 old_level(예전상태. 이걸 enable상태로 하지 않는 이유는 뭔가 작업 중이기 때문에 disable 상태였을 수도 있기 때문이다.)로 변경

// 시간값 반환

전통적으로 유닉스 시스템들은 비 선점형 방식이고, 비 선점 방식에서의 커널 스레드는 오직 스케쥴러의 system call에 의해서만 선점이 이루어진다(User program은 선점/비선점 모두 아무 때나 선점될 수 있음). 너도 알겠지만, 선점형 커널은 더 명시적인 동기화가 필요하다. 

다음은 interrupt를 disable/enable시키기 위한 Type과 함수들이다. threads/interrupt.h에 정의되어 있다.

Type: enum intr_level

One of INTR_OFF or INTR_ON, denoting that interrupts are disabled or enabled, respectively.

Function: enum intr_level intr_get_level (void)
Returns the current interrupt state.

Function: enum intr_level intr_set_level (enum intr_level level)
Turns interrupts on or off according to level. Returns the previous interrupt state.

Function: enum intr_level intr_enable (void)
Turns interrupts on. Returns the previous interrupt state.

Function: enum intr_level intr_disable (void)
Turns interrupts off. Returns the previous interrupt state.

A.3.1 Disabling Interrupts

The crudest way to do synchronization is to disable interrupts, that is, to temporarily prevent the CPU from responding to interrupts. If interrupts are off, no other thread will preempt the running thread, because thread preemption is driven by the timer interrupt. If interrupts are on, as they normally are, then the running thread may be preempted by another at any time, whether between two C statements or even within the execution of one.

Incidentally, this means that Pintos is a "preemptible kernel," that is, kernel threads can be preempted at any time. Traditional Unix systems are "nonpreemptible," that is, kernel threads can only be preempted at points where they explicitly call into the scheduler. (User programs can be preempted at any time in both models.) As you might imagine, preemptible kernels require more explicit synchronization.

You should have little need to set the interrupt state directly. Most of the time you should use the other synchronization primitives described in the following sections. The main reason to disable interrupts is to synchronize kernel threads with external interrupt handlers, which cannot sleep and thus cannot use most other forms of synchronization (see section A.4.3 External Interrupt Handling).

Some external interrupts cannot be postponed, even by disabling interrupts. These interrupts, callednon-maskable interrupts (NMIs), are supposed to be used only in emergencies, e.g. when the computer is on fire. Pintos does not handle non-maskable interrupts.

Types and functions for disabling and enabling interrupts are in threads/interrupt.h.

Type: enum intr_level
One of INTR_OFF or INTR_ON, denoting that interrupts are disabled or enabled, respectively.

Function: enum intr_level intr_get_level (void)
Returns the current interrupt state.

Function: enum intr_level intr_set_level (enum intr_level level)
Turns interrupts on or off according to level. Returns the previous interrupt state.

Function: enum intr_level intr_enable (void)
Turns interrupts on. Returns the previous interrupt state.

Function: enum intr_level intr_disable (void)
Turns interrupts off. Returns the previous interrupt state.


반응형