테스트PASS 한잔해~~
/* Suspends execution for approximately TICKS timer ticks. */
void timer_sleep(int64_t ticks) // ticks 경과 후 깰 시간 (5분)
{
int64_t start = timer_ticks(); // OS 부팅 후 경과 시간(12시)
ASSERT(intr_get_level() == INTR_ON);
// Busy Waiting 상태
// while (timer_elapsed (start) < ticks)
// thread_yield ();
// ✅ thread_sleep 활용으로 수정
if (timer_elapsed(start) < ticks)
{
thread_sleep(start + ticks); // 12시 + 5분을 넘김
}
}
void thread_sleep(int64_t ticks)
{
// 🚨 ticks => 일어나야할 시간
/* if the current thread is not idle thread,
change the state of the caller thread to BLOCKED,
store the local tick to wake up,
update the global tick if necessary,
and call schedule() */
/* When you manipulate thread list, disable interrupt! */
struct thread *curr = thread_current(); // 재울 현재 스레드
enum intr_level old_level; // 인터럽트
old_level = intr_disable();
// 1. 스레드 상태 BLOCK 변경
// curr->status = THREAD_BLOCKED;
// 2. 스레드의 wakeup_tick에 parameter로 받아온 ticks 저장
// 3. Sleep Queue의 tail에 push
if (curr != idle_thread)
{
curr->wakeup_tick = ticks;
list_push_back(&sleep_list, &curr->elem);
set_global_tick(ticks); // 더 작은 tick인지 검사
}
thread_block();
// 5. 인터럽트 다시 활성화
intr_set_level(old_level);
}
static void
timer_interrupt(struct intr_frame *args UNUSED)
{
ticks++; // OS 부팅이후 지난 시간(전체 시간)
// 매 time tick 마다 타임 인터럽트 호출
thread_tick(); // update the cpu usage for running process
if (get_global_tick() <= ticks) // 현재 시간이 global tick보다 크다면 깨울 프로세스 발생
{
thread_wakeup(ticks); // 프로세스 깨우는 함수 call
}
}
void thread_wakeup(int64_t ticks) // timer inturrput가 발생한 시각(12시 5분)
{
struct list_elem *curr = list_begin(&sleep_list); // sleep 리스트의 첫 원소
struct thread *curr_thread; // 쓰레드 저장용 변수
// 1. 리스트 순회
while (curr != list_end(&sleep_list))
{
curr_thread = list_entry(curr, struct thread, elem); // list elem thread 확인
if (curr_thread->wakeup_tick <= ticks)
{
curr = list_remove(curr); // sleep queue 에서 제거
thread_unblock(curr_thread); // thread unblock
}
else // else, local tick이 global tick 보다 작은 상황, 깨울 프로세스가 없음
{
set_global_tick(curr_thread->wakeup_tick);
curr = list_next(curr); // 다음 요소 local tick 검사하러 이동
}
}
}
Kernel PANIC at ../../threads/thread.c:280 in thread_current(): assertion `t->status == THREAD_RUNNING' failed.
건들지도 않은 현재 스레드 확인 함수에서 에러발생 다시 태초마을로...
perl -I../.. ../../tests/threads/alarm-single.ck tests/threads/alarm-single tests/threads/alarm-single.result
FAIL tests/threads/alarm-single
Kernel panic in run: PANIC at ../../threads/thread.c:282 in thread_current(): assertion `t->status == THREAD_RUNNING' failed.
Call stack: 0x800421339c 0x8004206ed7 0x8004206cf0 0x8004207146 0x800420d04e 0x8004216d25 0x80042169ea 0x80042167d8 0x8004206636 0x8004206783 0x8004206120
Translation of call stack:
0x000000800421339c: debug_panic (lib/kernel/debug.c:32)
0x0000008004206ed7: thread_current (threads/thread.c:284)
0x0000008004206cf0: thread_block (threads/thread.c:235)
0x0000008004207146: thread_sleep (threads/thread.c:370)
0x000000800420d04e: timer_sleep (devices/timer.c:108)
0x0000008004216d25: test_sleep (tests/threads/alarm-wait.c:101)
0x00000080042169ea: test_alarm_single (tests/threads/alarm-wait.c:19)
0x00000080042167d8: run_test (tests/threads/tests.c:57)
0x0000008004206636: run_task (threads/init.c:262)
0x0000008004206783: run_actions (threads/init.c:310)
0x0000008004206120: main (threads/init.c:124)
thread_sleep 함수에서 global tick 갱신 안했음
thread_wakeup 함수에서 curr 선언만 하고 초기화 안했음...