jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 변경 코드
    1. synch.c
    2. thread.h
    3. thread.c를 위한 부동소수점 매크로
    4. thread.c

흐름을 정리한 이유?

간단하다

⌜다 끝냈으니까⌟

정글 pintos 프로젝트 1 완(完)


변경 코드

의외로 많이 안건드렸다

사실상 thread.c에서 다 해결봄

synch.c

기존에 있던 lock_acquire 함수에서

우선순위 양보하고 뭐하고 하는 거 전부

if (thread_mlfqs != true) {
    ...
}

로 묶어서 처리했다

이게 끝이다

다음


thread.h

thread.c의 헤더 파일이다

새로 쓰는 변수들만 선언해줬다

전역에 하나

구조체에 하나 x 3

struct thread {
    ...
    int recent_cpu;           // 최근 cpu
    int nice;                 // 매너온도
    struct list_elem allelem; // 모든 스레드 순환용 리스트
    ...
}
extern int load_avg;          // 1분 부하 평균

그럼 끝이다

다음


thread.c를 위한 부동소수점 매크로

부동소수점 계산이 필요하기에 관련 함수는 따로 빼주었다

이건 그냥 단순 계산만이라 로직이고 뭐고 없다

그냥 알아서 해라

맨 밑에 가면 필요 계산 있음

각자 입맛에 맞춰 매크로 제작하면 된다

다음


thread.c

크게 바꾼건 없고

조금 살만 붙여준 느낌으로 건드렸다

thread_init에다가

thread.h에서 만든 것들 초기화하고 세팅하는 거 넣어주고

init_thread도 초기화 넣어준다

/* 걍 전부 초기화 */
void
thread_init (void) {
    ...
    list_init (&all_list); // 순회 리스트 초기화
    load_avg = 0;          // 부하 평균 초기화

/* ------ initial_thread 등으로 초기 스레드 설정 ------ */
/*                   .   .   .                        */
/* -------------------------------------------------- */
    // 초기 스레드 리스트에 삽입
	list_push_back(&all_list, &initial_thread->allelem);

    // mlfqs on일 때에 설정 값들
	if (thread_mlfqs) {
		initial_thread->nice = 0;                       // nice 값 초기화
		initial_thread->recent_cpu = 0;                 // 최근 cpu 초기화
		int p = PRI_MAX - (initial_thread->nice * 2);   // 우선순위 계산
		if (p < PRI_MIN) p = PRI_MIN;                   // 최솟값 이하일시 올려줌
		if (p > PRI_MAX) p = PRI_MAX;                   // 최댓값 이상일시 내려줌
		initial_thread->priority = p;                   // 우선순위 설정
	}
}

/* 스레드 하나만 초기화 */
static void
init_thread (struct thread *t, const char *name, int priority) {
    ...
	t->nice = 0;       // nice 초기화
	t->recent_cpu = 0; // recent_cpu 초기화
    ...
}



thread_create에다가도 그 값들 세팅하는 거 넣어주고

// 걍 thread_create에 위에랑 똑같은 거 넣어줌 ㅇㅇ



thread_exit로 스레드 제거할때 리스트 에서 빼는 거 넣어주고

void
thread_exit (void) {
    ...
    intr_disable();
	list_remove(&thread_current()->allelem); // <- 이거 한줄만 추가해줌
	do_schedule (THREAD_DYING);
	NOT_REACHED ();
}



thread_set_priority mlfqs일때는 작동 안하게 하고…

void
thread_set_priority (int new_priority) {
    if (thread_mlfqs != true) {
        /* 기존 코드 */
    }
}

흠… 좀 한게 많은 거 같기도 하고…

아무튼, 여기까지가 기존 꺼 좀 수정하는 거고 이 다음부턴 기능 추가다

뭐 많이 안한다

아님말고


thread_tick에다가 1틱일때, 4틱일때, 1초일때 일어나는 일 넣어준다

void
thread_tick (void) {
    ...
    if (thread_mlfqs == true) {
        /* 현스레드가 idle_thread 아닐경우 recent_cpu++
         * 매 틱마다 해줌
         */

        /* 4틱일때
         * 모든 스레드 돌며
         * 우선순위 재계산
         * 현재 스레드 ready일때 우선순위 반영 재삽입
         * 스레드 다 돌고 우선순위 반영하여 기부
         */

        /* 1초일때
         * 모든 스레드 돌며
         * 우선순위 재계산
         * 현재 스레드 ready일때 우선순위 반영 재삽입
         * 스레드 다 돌고 우선순위 반영하여 기부
         */
    }
}

근데 여기 좀 개같이 짜놔서 다듬어야 한다

따로 함수 안 빼서 개더러움;;🤢🤢🤮🤮



그리고 이제부턴 nice, load_avg, recent_cpu 등등 관련 함수 건드려서 완성해주면 끝이다

/* 현재 스레드의 nice 값을 반환. */
int
thread_get_nice (void) {
	return thread_current()->nice;
}

/* 시스템 load average * 100 값을 반환. */
int
thread_get_load_avg (void) {
	struct thread *t = thread_current();
	int return_avg = FP_TO_INT_NEAR(FP_MUL_INT(load_avg, 100));
	return return_avg;
}

/* 현재 스레드의 recent_cpu * 100 값을 반환. */
int
thread_get_recent_cpu (void) {
	struct thread *t = thread_current();
	int return_cpu = FP_TO_INT_NEAR(FP_MUL_INT(t->recent_cpu, 100));
	return return_cpu;
}

/* 현재 스레드의 nice 값을 NICE로 설정. */
void
thread_set_nice (int nice UNUSED) {
	enum intr_level old = intr_disable();
    struct thread *t = thread_current();

    /* 최소, 최대 클램핑 */
	if (nice < -20) nice = -20; 
  	if (nice >  20) nice =  20; 	
    t->nice = nice;

    /* 우선순위 계산 */
	int new_priority
	= PRI_MAX
	- FP_TO_INT_ZERO(FP_DIV_INT(t->recent_cpu, 4))
	- (t->nice * 2);

    /* 최소, 최대 클램핑 */
	if (new_priority < PRI_MIN) new_priority = PRI_MIN;
	if (new_priority > PRI_MAX) new_priority = PRI_MAX;

    /* 우선순위 설정 */
	t->priority = new_priority;

	intr_set_level(old);

    /* 계산후 경우에 따라 즉시 양보 */
	if (!list_empty(&ready_list)) {
		struct thread *top = list_entry(list_front(&ready_list), struct thread, elem);
			if (top->priority > thread_current()->priority)
				thread_yield();
	}
}

이렇게 해주면 된다

기능은 간단한데 코드로 보니 좀 길어졌다

특히 thread_set_nice

아무튼, 이정도만 해주면

이제 mlfqs 클리어~

물론, 깔끔하지 못한 동작일 확률이 높으니
더 좋고 이쁜 코드도 있겠지만…

난 여기깔즤~