운영체제(구현) - 핀토스-1(Alarm clock)

연도·2024년 5월 31일
0
post-thumbnail

몇 초만에 프로세스를 깨우는 시스템 호출

스레드를 sleep하거나, wakeup하는 함수들로 알람 시계를 만든다.

상태 주기

원래 상태

바꿔야 하는 상태

구현해야 할 것

thread_init()

sleep 큐 데이터 구조를 초기화하는 코드 추가.

구현 전 힌트(x)

코드

threads/thread.h
int64_t wakeup_ticks;       // 일어날 시각 추가(각 스레드 마다 존재)
void thread_sleep (int64_t ticks);
void thread_wakeup (int64_t global_ticks);
bool cmp_thread_ticks(const struct list_elem *a, const struct list_elem *b, void *aux);

threads/thread.c
static struct list ready_list;
static struct list sleep_list;

thread_init(void)
{
list_init(&sleep_list);
}

timer_sleep()

sleep 큐에 스레드를 삽입하는 함수 호출

구현 전 힌트(x)

코드

devices/timer.c

timer_sleep(int64_t ticks)
{
	int64_t start = timer-ticks(); // 현재 시각
	ASSERT(intr_get_level() == INTR_ON); // 인터럽트 레벨 검사 

	thread_sleep(start + ticks); // 현재 시각 + 잠들시간
}

timer_interrupt()

매 틱 마다 일부 스레드가 절전 대기열에서 깨어나야하는지 확인하고 wake up 함수 호출

구현 전 힌트

  • sleep list와 global tick 확인. 깨울 스레드를 찾으세요. 필요한 경우 ready_list로 이동하세요.

코드

devices/timer.c

timer_interrupt(struct intr_frame *args UNSED)
{
	ticks++; 
  thread_tick (); // 스레드의 우선순위를 관리, 다음 실행할 스레드를 선택하는 역할.
  thread_wakeup(ticks); // 일어날 시간이 된 스레드 > ready_list로 이동시키는 함수 호출
}

thread_sleep

스레드 상태를 차단됨으로 설정하고 절전 대기열에 삽입한 후 대기하는 함수. 스레드를 블록처리 함으로써 재우는 함수.

구현 전 힌트

  • 현재 스레드가 idle 스레드가 아닌 경우 호출자 스레드의 상태를 blocked로 변경.
  • 스레드 목록을 작성할 때 인터럽트를 비활성화.
  • 깨어나려면 local tick를 저장하고, 필요한 경우 global tick를 업데이트

코드

threads/thread.c

thread_sleep(int64_t ticks)
    {
        struct thread *curr;
        enum intr_level old_level;

		// 1. 인터럽트 비활성화
        old_level = intr_disable(); 

		// 2. 현재 스레드 가져오기
        curr = thread_current();     

		// 3. 스레드 검사(현재 스레드가 idle이 아닐때만)
        ASSERT(curr != idle_thread); 

		// 4. 일어날 시각 설정
        curr->wakeup_ticks = ticks;

		// 5. sleep_list에 스레드 추가   
        list_insert_ordered(&sleep_list, &curr->elem, cmp_thread_ticks, NULL); // sleep_list에 추가

		// 6. 스레드 블록(재우기) - 블록 처리
		thread_block(); // 

		// 7. 인터럽트 복원
        intr_set_level(old_level); 
    }

thread_wakeup

절전 대기열에서 깨어날 스레드를 찾아 절전 모드를 해제하는 함수. 잠든 상태인 스레드를 깨우는 함수

구현 전 힌트(x)

코드

threads/thread.c

thread_wakeup(int64_t current_ticks)
    {
        enum intr_level old_level;

		// 1. 인터럽트 비활성화
        old_level = intr_disable(); 

        struct list_elem *curr_elem = list_begin(&sleep_list);

		// 2. 'sleep_list' 순회
        while (curr_elem != list_end(&sleep_list))
        {
            struct thread *curr_thread = list_entry(curr_elem, struct thread, elem); // 현재 검사중인 elem의 스레드

			// 3. 스레드 깨우기
            if (current_ticks >= curr_thread->wakeup_ticks)
            {	
				// 4. 순회 계속(sleep_list에서 제거, curr_elem에는 다음 elem이 담김)
                curr_elem = list_remove(curr_elem); 

				// 3. 스레드 깨우기(ready_list로 이동)
				thread_unblock(curr_thread);       
            }
            else
                break;
        }

		// 5. 인터럽트 복원
        intr_set_level(old_level); // 인터럽트 상태를 원래 상태로 변경
    }

출처 : 카이스트, 한양대 핀토스

0개의 댓글