Pintos_project1 - Alarm Clock

2025. 9. 9. 02:07·Develop

정글화장실뷰..

핀토스프로젝트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랑 비교후 양보를 한다.
이 때

  1. 너무 자주 시간을 확인하고,
  2. 컨텍스트 스위칭이 너무 빈번

해지는 문제가 생긴다. 즉 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, &current->elem, list_less_funcc, NULL); // 비교해서 삽입
    thread_block(); // 스레드 멈춤
    intr_set_level(old_level); // 인터럽트 시작
}

여기서 중요한건

  1. 인터럽트를 꺼놓는 것 과
  2. 새로운 sleep_list로 속하게 한다는것이다.

인터럽트를 왜꺼야하나?

공유자원 영역에 접근할 때는 인터럽트가 꺼져있어야한다.
이유는 list에 추가하는 도중에 인터럽트가 발생하면

  1. 자원이 훼손될수도있고,
  2. 리스트가 꼬여 예기치 못한 오류가 발생할 수 도 있다.

sleep_list로 속하는것?

리스트는 일반적으로 해당 리스트에 데이터들을 저장하는 방식으로 이루어진다.

pintos는 반대로 저장될 데이터에 elem 이라는 구조체 멤버를 선언하고,
elem 을 이전, 다음의 포인터로 사용한다.

이렇게 되면 좋은점이

  1. 데이터가 절약된다
    1. 리스트구조체는 prev, next만 있으면 되고,
    2. 데이터에는 elem 만 존재하면된다.
  2. 데이터의 소속을 관리할 수 있다.
    1. 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://poalim.tistory.com/28

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
'Develop' 카테고리의 다른 글
  • Pintos_project2 - argument passing
  • Pintos_project1 - Priority
  • malloc lab-implicit list에 관하여 + 구현
  • Red-Black Tree 개념
sj-leeee
sj-leeee
배운것과 느낀것을 적는 공간입니다.
  • sj-leeee
    sj-leeee 님의 블로그
    sj-leeee
  • 전체
    오늘
    어제
    • 분류 전체보기 (23) N
      • LIFE (5)
      • Develop (17) N
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

    • 깃허브
    • 이전블로그
  • 공지사항

  • 인기 글

  • 태그

    MQ
    LinkedList
    운영체제
    크래프톤정글
    Algorithm
    정글
    krafton
    Jungle
    AWS
    8주차
    rbtree
    git
    node.js
    컴파일
    malloc
    Pintos
    싱글스레드
    heap
    Kafka
    크래프톤
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
sj-leeee
Pintos_project1 - Alarm Clock
상단으로

티스토리툴바