[PintOS] Alarm Clock

JunHyeok Kim·2024년 5월 11일
0

구현목표

Busy wait 상태의 next tick 을 기다리는 쓰레드를 단순히 sleep 상태로 변경하여 Kernel ticksidle ticks 변화를 확인합니다.

Busy wait


현재 위와 같이 yield가 지속적으로 일어나 CPU를 낭비하고 있다.

sleep


따라서, 위와 같이 ticks 만큼 sleep 상태에 놓음으로써 간단하게 해결할 수 있습니다.

sleep_list


따라서, sleep_list 구조체를 하나 선언한 뒤, thread_wakeup() 과 thread_sleep()을 통해 ready_list와 sleep_list를 관리해주면 됩니다!

성공 결과


위와 같이 550 idle ticks를 확인할 수 있다.

추가할 함수

  1. thread_sleep() : The function that sets thread state to blocked and wait after insert it to sleep queue.
  2. thread_wakeup() : The function that find the thread to wake up from sleep queue and wake up it.
  3. set_global_ticks() : The function that save the minimum value of tick that threads have.
  4. get_global_ticks() : The function that return the minimum value of tick.

1) thread_sleep()

void
thread_sleep(int64_t howLong) {

	struct thread *curr;

	enum intr_level old_level;
	ASSERT(!intr_context());
	// 1) intr disable
	old_level = intr_disable(); 

	curr = thread_current();
	ASSERT(curr != idle_thread);

	curr->local_ticks = howLong;
//	list_push_back(&sleep_list, &curr->elem);
	list_insert_ordered(&sleep_list, &curr->elem, ticks_less ,&curr->local_ticks);
	set_global_ticks(); 

	thread_block();	// hread_block() 과 do_schedule 뭘 써야하지?

	// 2) intr able 
	intr_set_level(old_level);
}

2) thread_wakeup()

void
thread_wakeup(int64_t ticks) { // OS ticks from timer! 

	struct list_elem *e = list_begin (&sleep_list);
	struct thread *cur;
	struct list_elem *next;
	ASSERT (intr_context ());
	
	// ticks와 동일한 시간에 깨어나야 하는 쓰레드가 여러개 있을 수 있으니까 반복문으로 체크합니다.
  	while (!list_empty(&sleep_list)) // incr 'e' inside of the loop by doing e = list_next;
	{
		e = list_begin(&sleep_list);
        cur = list_entry (e, struct thread, elem); // iterate the sleep list !
		
		// Time to wake up
		if (cur->local_ticks > ticks) break;
		// e == &cur->elem
		list_remove(e);  // e 갱신, //fix
		// next = list_pop_front(&sleep_list);
		thread_unblock(cur); // 이미 만들어진 함수에서 다 처리
		// list_push_back(&ready_list, next);
    }
	set_global_ticks();
}

3) set_global_ticks()

void set_global_ticks() {
	struct thread *tmp = list_min(&sleep_list,ticks_less,NULL);
	global_ticks = MIN(tmp->local_ticks,global_ticks);
}

4) get_global_ticks()

int64_t get_global_ticks(void) {
	return global_ticks;
}

수정한 함수

static void timer_interrupt()

static void
timer_interrupt (struct intr_frame *args UNUSED) {
	ticks++;
	thread_tick ();

	int64_t next = get_global_ticks();
	if (next <= ticks) { 
		thread_wakeup(ticks);
	}
	/*
		code to add : 
		check sleep list and the global tick.
		find any threads to wake up,
		move them to the ready list if needed
		update the global tick.
	*/
}

내장함수 정리

-> 천천히 할 예정입니다...

0개의 댓글