오늘은 깨우는 부분과 리스트 사용법 중심으로 과제를 수행함.
매 틱 발동하는 함수를 찾았음 -> void thread_tick(void)
해당함수 에 코드 두 줄 추가.
//thread.c
struct list_elem *front_elem = list_front(&sleep_list);
struct thread *front_thread = list_entry(front_elem, struct thread, wake_time);
//
두 번째 줄에서 코드에러.
- 여기서 LIST_ELEM은 리스트의 요소(list_elem 타입의 포인터)이고, STRUCT는 요소가 포함된 구조체 타입이며, MEMBER는 LIST_ELEM이 가리키는 구조체 내의 멤버입니다.
- 주어진 코드에서 front_elem이 struct list_elem 타입의 포인터이고, 이 포인터가 struct thread 구조체의 elem 멤버를 가리키고 있는 경우, wake_time이 아니라 elem을 사용해야 합니다.
이라고함. 따라서 수정된 코드는 :
struct thread *front_thread = list_entry(front_elem, struct thread, elem);
//timer.c
void timer_sleep(int64_t ticks)
{
enum intr_level old_level;
// int64_t start = timer_ticks();
// ASSERT(intr_get_level() == INTR_ON);
// while (timer_elapsed(start) < ticks)
// thread_yield();
int64_t start = timer_ticks();
struct thread *curr = thread_current();
// 기상시간 정해주기
curr->wake_time = start + ticks;
// 인터럽트 잠시 끄기
old_level = intr_disable();
// 일단 리스트 뒤에 넣어주자.
list_push_back(&sleep_list, &curr->elem);
// 순서대로 넣을수도
// list_insert_ordered(&sleep_list, &curr->elem, , );
// 작업이 끝난 후, 이전 인터럽트 상태로 복구
intr_set_level(old_level);
// 이제 재우자
thread_block();
ASSERT(intr_get_level() == INTR_ON);
// while을 지울거임.
// while (timer_elapsed(start) < ticks)
// thread_yield();
}
//thread.c
void thread_tick(void)
{
struct thread *t = thread_current();
// 슬립 리스트의 1번침대에서 자고있는 놈의 기상시간이 현재틱과 같다면 깨우기
if (list_front(&sleep_list))
/* Update statistics. */
if (t == idle_thread)
idle_ticks++;
#ifdef USERPROG
else if (t->pml4 != NULL)
user_ticks++;
#endif
else
kernel_ticks++;
/* Enforce preemption. */
if (++thread_ticks >= TIME_SLICE)
intr_yield_on_return();
}
//timer.c
static void
timer_interrupt(struct intr_frame *args UNUSED)
{
ticks++;
thread_tick();
enum intr_level old_level;
// 일단 인터럽트 꺼
old_level = intr_disable();
// 슬립 리스트의 1번침대에서 자고있는 놈의 기상시간이 현재틱과 같다면 깨우기
if (!list_empty(&sleep_list))
{
struct list_elem *front_elem = list_begin(&sleep_list);
struct thread *front_thread = list_entry(front_elem, struct thread, elem);
// 깰 시간이 됐다면
if (ticks >= front_thread->wake_time)
{
// 맨앞에서 자고있는 스레드 깨우기
thread_unblock(front_thread);
// 깨우고 슬립 리스트에서 지우기.
list_pop_front(&sleep_list);
}
}
// 작업이 끝난 후, 이전 인터럽트 상태로 복구
intr_set_level(old_level);
}
매 틱 발동하는 함수를 찾음.
따라서 리스트 헤더 파일에 있는 함수를 사용해보려 함.
그런데 리스트 헤더에 정의된 함수 대부분은 정의되지 않은 함수. -> what?
스레드끼리 자원을 공유하고 싶다면
변수를 static으로 선언해야한다.