pintos os 코드정리
/* Pintos main program. */
// main
int main (void) NO_RETURN;
/* Pintos main program. */
int
main (void) {
uint64_t mem_end;
char **argv;
/* Clear BSS and get machine's RAM size. */
bss_init ();
/* Break command line into arguments and parse options. */
argv = read_command_line ();
argv = parse_options (argv);
/* Initialize ourselves as a thread so we can use locks,
then enable console locking. */
thread_init ();
console_init ();
/* Initialize memory system. */
mem_end = palloc_init ();
malloc_init ();
paging_init (mem_end);
#ifdef USERPROG
tss_init ();
gdt_init ();
#endif
/* Initialize interrupt handlers. */
intr_init ();
timer_init ();
kbd_init ();
input_init ();
#ifdef USERPROG
exception_init ();
syscall_init ();
#endif
/* Start thread scheduler and enable interrupts. */
thread_start ();
serial_init_queue ();
timer_calibrate ();
#ifdef FILESYS
/* Initialize file system. */
disk_init ();
filesys_init (format_filesys);
#endif
#ifdef VM
vm_init ();
#endif
printf ("Boot complete.\n");
/* Run actions specified on kernel command line. */
run_actions (argv);
/* Finish up. */
if (power_off_when_done)
power_off ();
thread_exit ();
}
/* timer.c */
/* Timer interrupt handler. */
static void
timer_interrupt (struct intr_frame *args UNUSED) {
ticks++;
thread_tick ();
/* 매 tick akek sleep queue 에서 깨어날 thead가 는지 홧인하여, 깨우는 함수를 호출하도록 함*/
if(get_next_tick_to_awake() <= ticks){
thread_awake(ticks);
}
}
// include/threads/thread.h
/* 깨어나야 할 tick을 저장 할 변수 추가*/
int64_t wakeup_tick;
//스레드를 ticks시각까지 재우는 함수.
void thread_sleep(int64_t ticks);
//푹 자고 있는 스레드 중에 깨어날 시각이 ticks시각이 지난 애들을 모조리 깨우는 함수
void thread_awake(int64_t ticks);
// 가장 먼저 일어나야할 스레드가 일어날 시각을 반환함
int64_t get_next_tick_to_awake(void);
// 가장 먼저 일어날 스레드가 일어날 시각을 업데이트함
void update_next_tick_to_awake(int64_t ticks);
// threads/thread.c
static struct list sleep_list; /* 잠자는 애들을 모아둘 공간을 마련함 */
static int64_t next_tick_to_awake; /* 가장 먼저 일어날 애가 일어날 시각을 저장할 변수 */
thread_init (void) {
ASSERT (intr_get_level () == INTR_OFF);
/* Reload the temporal gdt for the kernel
* This gdt does not include the user context.
* The kernel will rebuild the gdt with user context, in gdt_init (). */
struct desc_ptr gdt_ds = {
.size = sizeof (gdt) - 1,
.address = (uint64_t) gdt
};
lgdt (&gdt_ds);
/* Init the globla thread context */
lock_init (&tid_lock);
list_init (&ready_list);
list_init (&destruction_req);
list_init (&sleep_list); /* sleep list 이걸 추가하였음 */
/* Set up a thread structure for the running thread. */
initial_thread = running_thread ();
init_thread (initial_thread, "main", PRI_DEFAULT);
initial_thread->status = THREAD_RUNNING;
initial_thread->tid = allocate_tid ();
}
// 가장 먼저 일어나야할 thread가 일어날 시간을 반환함
void update_next_tick_to_awake(int64_t ticks){
/* next_tick_to_awake 가 깨워야 할 스레드의 깨어날 tick 값 중 가장 작은 tick을 갖도록 업데이트 */
next_tick_to_awake = (next_tick_to_awake > ticks) ? ticks : next_tick_to_awake;
}
// 가장 먼저 일어나야할 스레드가 일어날 시각을 반환함
int64_t get_next_tick_to_awake(void){
return next_tick_to_awake;
}
// 스레드를 ticks 시각 까지 재우는 함수
void thread_sleep(int64_t ticks){
struct thread *cur;
// 인터럽트를 금지하고 이전 인터럽트 레벨을 저장함
enum intr_level old_level;
old_level = intr_disable();
cur = thread_current();
ASSERT(cur != idle_thread); // idle 스레드는 sleep 되지 않아야 함
// awake 함수가 실헹되어야 할 tick 값을 update
update_next_tick_to_awake(cur -> wakeup_tick = ticks);
/* 현재 스레드를 슬립 큐에 삽입한 후에 스케줄한다. */
list_push_back(&sleep_list, &cur->elem);
// 이 스레드를 블락하고 다시 스케쥴될 때 까지 블락 상태로 대기
thread_block();
/* 인터럽트를 다시 받아들이도록 수정 */
intr_set_level(old_level);
}
/* 자고 있는 스레드 중에 깨어날 시각이 tick 시각이 지난 애들을 모조리 깨우는 함수 */
void thread_awake(int64_t wakeup_tick){
next_tick_to_awake = INT64_MAX;
struct list_elem *e;
e = list_begin(&sleep_list);
while(e != list_end(&sleep_list)){
struct thread * t = list_entry(e, struct thread, elem);
if(wakeup_tick >= t->wakeup_tick) {
e = list_remove(&t->elem);
thread_unblock(t);
} else {
e = list_next(e);
update_next_tick_to_awake(t->wakeup_tick);
}
}
}
// devices/timer.c
/* Suspends execution for approximately TICKS timer ticks. */
void
timer_sleep (int64_t ticks) {
int64_t start = timer_ticks ();
ASSERT (intr_get_level () == INTR_ON); /* INTR_ON means Interrupts enabled. */
while (timer_elapsed (start) < ticks)
thread_yield (); // <= 다음 thread에게 실행권한 넘기는건가..?
// thread_sleep(start + ticks);
}
Author And Source
이 문제에 관하여(pintos os 코드정리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jungbumwoo/pintos-os-코드정리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)