jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. mlfqs 변경점
    1. 간단 요약
    2. 새로 추가된 개념과 데이터
      1. 전역
      2. 스레드 별
    3. 흐름
      1. 부팅/초기화
      2. 스레드 생성 시
      3. 매 타이머 틱
      4. nice 변경 시 (thread_set_nice)
      5. 값 가져오기
  2. 여담

mlfqs 변경점

mlfqs 넣으니… 그리 많이 변하지는 않았다

우선순위 만들고 기부 로직 만드는게 더 빡세다 emoji

간단 요약

mlfqs 도입하며 변경점

기존 도네이션 로직 if문으로 전부 차단

  • 변수 추가

    • 시스템 전역 변수 load_avg 추가

    • 구조체를 통해 스레드별 nice, recent_cpu 추가

    • priority 이를 통해서 재계산

  • 주기적 재계산

    • 매 틱마다 recent_cpu++

    • 매 4틱마다 우선순위 재계산 + 필요 시 ready_list 정렬 삽입 + 필요 시 선점

    • 매 1초마다 load_avgrecent_cpu 일괄 갱신, 우선순위 재계산 + 필요 시 ready_list 정렬 삽입 + 필요 시 선점


새로 추가된 개념과 데이터

전역

  • load_avg

    • 시스템 전체 부하의 이동 평균

    • 1초마다 공식(두렵다): load_avg = (59/60)*load_avg + (1/60)*ready_threads
      emoji

    • ready_threads: idle 제외 ready 스레드 + 현재 스레드가 idle 아니면 1

스레드 별

  • nice

    • 매너 온도. 기본 값 0, 부모로부터 상속 (범위: -20 ~ +20)
  • recent_cpu

    • 최근 사용 CPU 양

    • 매 틱: 실행 중이고 idle이 아니면 +1

    • 매 1초: recent_cpu = (2*load_avg)/(2*load_avg+1) * recent_cpu + nice

  • 우선순위(priority)

    • 매 4틱, 매 1초:
      priority = PRI_MAX - recent_cpu/4 - (nice * 2)
      (하한 PRI_MIN, 상한 PRI_MAX로 클램프)


부동 소수점과 정수 섞어서 쓰기에 세심한 정리를 요한다
무친 공식;;🥵🥵🥵



흐름

부팅/초기화

  • thread_init()에서 준비/모든 리스트 초기화, load_avg=0

  • thread_start()에서 idle 스레드 생성 -> 인터럽트 on

스레드 생성 시

  • 부모의 nice, recent_cpu 상속

  • MLFQS가 켜져 있을 경우 우선순위 공식으로 재계산해 세팅

  • 준비 큐에 우선순위 내림차순 삽입

매 타이머 틱

  • 위에 적힌 것들 한다

  • 타임슬라이스 소진 시 선점

nice 변경 시 (thread_set_nice)

  • 현재 스레드의 nice 설정
    -> 그 자리에서 우선순위 재계산
    -> 최우선순위가 아니게 되면 즉시 양보

값 가져오기

  • thread_get_load_avg()load_avg * 100반올림 결과로 반환

  • thread_get_recent_cpu()는 현재 스레드의 recent_cpu * 100 반올림 결과



여담

수정할 곳이 별로 없기에

전역함수 따로 안뺐다가 지옥 봤다…

다들 똑같은 로직 2번 쓰이면 바로 전역 함수 만들자