
핀토스프로젝트1 - Alarm Clock 구현
Alarm clock이 뭐지?
호출한 스레드를 잠시 정지(block) 시키고 일정시간(ticks) 후에
다시 스레드를 준비상태로 만드는 과정을 이야기한다.
현재 문제점
스레드는 sleep 상태에 들어가면 바쁜대기 상태가 된다.
void timer_sleep (int64_t ticks) {
int64_t start = timer_ticks ();
ASSERT (intr_get_level () == INTR_ON);
while (timer_elapsed (start) < ticks)
thread_yield ();
}
코드를 보면 현재시간을 이용하여 ticks랑 비교후 양보를 한다.
이 때
- 너무 자주 시간을 확인하고,
- 컨텍스트 스위칭이 너무 빈번
해지는 문제가 생긴다. 즉 CPU낭비 이므로
이 코드를 tick 마다 검사하는 코드로 바꾸는 것이 첫번째 목표
구현
구현하는 과정에서 가장 어려웠던 것은
낯선 함수들과 코드들을 이해하는 것이었다.
가이드라인을 참고해서 힌트를 얻고,
해당함수와 관련된 것들을 먼저 이해했다.
timer_sleep - 스레드를 재우는 함수
// 스레드를 ticks만큼의 시간만큼 Block 시키는 함수
void timer_sleep(int64_t ticks)
{
ASSERT(!intr_context()); // 현재 인터럽트 실행중이었으면 안됨.
if (ticks <= 0)
return;
struct thread *current = thread_current(); // 현재 스레드
current->wakeup_tick = timer_ticks() + ticks;
// 현재 시간에다가 tick 추가
enum intr_level old_level = intr_disable(); // 인터럽트 재우고 시작
list_insert_ordered(&sleep_threads, ¤t->elem, list_less_funcc, NULL); // 비교해서 삽입
thread_block(); // 스레드 멈춤
intr_set_level(old_level); // 인터럽트 시작
}
여기서 중요한건
- 인터럽트를 꺼놓는 것 과
- 새로운 sleep_list로 속하게 한다는것이다.
인터럽트를 왜꺼야하나?
공유자원 영역에 접근할 때는 인터럽트가 꺼져있어야한다.
이유는 list에 추가하는 도중에 인터럽트가 발생하면
- 자원이 훼손될수도있고,
- 리스트가 꼬여 예기치 못한 오류가 발생할 수 도 있다.
sleep_list로 속하는것?
리스트는 일반적으로 해당 리스트에 데이터들을 저장하는 방식으로 이루어진다.
pintos는 반대로 저장될 데이터에 elem 이라는 구조체 멤버를 선언하고,elem 을 이전, 다음의 포인터로 사용한다.
이렇게 되면 좋은점이
- 데이터가 절약된다
- 리스트구조체는
prev,next만 있으면 되고, - 데이터에는
elem만 존재하면된다.
- 리스트구조체는
- 데이터의 소속을 관리할 수 있다.
elem이sleep_list에 속해있다면ready_list에는 소속될수 없다.
timer_interrupt - tick증가+스레드깨우기
// tick 인터럽트 (여기선 1초에 100번)
static void timer_interrupt(struct intr_frame *args UNUSED)
{
ticks++; // 전역변수 ticks + 1
wakeup_threads(); // 스레드 깨우기
thread_tick();
}
static void wakeup_threads()
{
if (list_empty(&sleep_threads))
return;
while (!list_empty(&sleep_threads))
{
struct thread *front_th = list_entry(list_front(&sleep_threads), struct thread, elem); // sleep list의 첫번째 스레드를 반환
if (front_th->wakeup_tick > timer_ticks())
break; // 시간이 덜됐다면 break
struct thread *wakeup_th = list_entry(list_pop_front(&sleep_threads), struct thread, elem);
thread_unblock(wakeup_th); // 준비리스트로 신분상승
}
}
여기서는 시간이 다된 스레드들을 준비리스트로 옮기고,
스레드가 자원을 너무 많이 선점했다면 자동으로 양보하게 한다.
thread_unblock 함수는 block 상태였던 스레드를 다시 준비리스트에 소속되게 하는 함수
테스트결과

https://github.com/SJ-Leeee/pintos_project_1_team4/tree/main/seungjun
Reference
https://casys-kaist.github.io/pintos-kaist/project1/alarm_clock.html
'Develop' 카테고리의 다른 글
| Pintos_project2 - argument passing (0) | 2025.09.25 |
|---|---|
| Pintos_project1 - Priority (0) | 2025.09.10 |
| malloc lab-implicit list에 관하여 + 구현 (3) | 2025.08.23 |
| Red-Black Tree 개념 (3) | 2025.08.15 |
| [C언어] 포인터, 주소, malloc.. 등등 (5) | 2025.08.08 |