[Krafton Jungle] PintOS 2.0.0
크래프톤 정글 PintOS
 
Loading...
Searching...
No Matches
thread.c File Reference
#include "threads/thread.h"
#include <debug.h>
#include <stddef.h>
#include <random.h>
#include <stdio.h>
#include <string.h>
#include "threads/flags.h"
#include "threads/interrupt.h"
#include "threads/intr-stubs.h"
#include "threads/palloc.h"
#include "threads/synch.h"
#include "threads/vaddr.h"
#include "intrinsic.h"
Include dependency graph for thread.c:

Macros

#define THREAD_MAGIC   0xcd6abf4b
 
#define THREAD_BASIC   0xd42df210
 
#define TIME_SLICE   4 /* # of timer ticks to give each thread. */
 
#define is_thread(t)   ((t) != NULL && (t)->magic == THREAD_MAGIC)
 
#define running_thread()   ((struct thread *) (pg_round_down (rrsp ())))
 

Functions

static void kernel_thread (thread_func *, void *aux)
 
static void idle (void *aux UNUSED)
 
static struct threadnext_thread_to_run (void)
 
static void init_thread (struct thread *, const char *name, int priority)
 
static void do_schedule (int status)
 
static void schedule (void)
 
static tid_t allocate_tid (void)
 
int64_t get_global_ticks (void)
 
void set_global_ticks (int64_t ticks)
 
void thread_awake (int64_t ticks)
 
void thread_sleep (int64_t ticks)
 
bool cmp_priority (const struct list_elem *a, const struct list_elem *b, void *aux UNUSED)
 
void thread_init (void)
 
void thread_start (void)
 
void thread_tick (void)
 
void thread_print_stats (void)
 
tid_t thread_create (const char *name, int priority, thread_func *function, void *aux)
 
void thread_block (void)
 
void thread_unblock (struct thread *t)
 
const char * thread_name (void)
 
struct threadthread_current (void)
 
tid_t thread_tid (void)
 
void thread_exit (void)
 
void thread_yield (void)
 
void thread_set_priority (int new_priority)
 
int thread_get_priority (void)
 
void thread_set_nice (int nice UNUSED)
 
int thread_get_nice (void)
 
int thread_get_load_avg (void)
 
int thread_get_recent_cpu (void)
 
static void idle (void *idle_started_ UNUSED)
 
void do_iret (struct intr_frame *tf)
 
static void thread_launch (struct thread *th)
 

Variables

static struct list ready_list
 
static struct list sleep_list
 
static struct threadidle_thread
 
static struct threadinitial_thread
 
static struct lock tid_lock
 
static struct list destruction_req
 
static int64_t global_ticks = INT64_MAX
 
static long long idle_ticks
 
static long long kernel_ticks
 
static long long user_ticks
 
static unsigned thread_ticks
 
bool thread_mlfqs
 
static uint64_t gdt [3] = { 0, 0x00af9a000000ffff, 0x00cf92000000ffff }
 

Macro Definition Documentation

◆ is_thread

#define is_thread (   t)    ((t) != NULL && (t)->magic == THREAD_MAGIC)

◆ running_thread

#define running_thread ( )    ((struct thread *) (pg_round_down (rrsp ())))

◆ THREAD_BASIC

#define THREAD_BASIC   0xd42df210

◆ THREAD_MAGIC

#define THREAD_MAGIC   0xcd6abf4b

◆ TIME_SLICE

#define TIME_SLICE   4 /* # of timer ticks to give each thread. */

Function Documentation

◆ allocate_tid()

static tid_t allocate_tid ( void  )
static
730 {
731 static tid_t next_tid = 1;
732 tid_t tid;
733
735 tid = next_tid++;
737
738 return tid;
739}
void lock_release(struct lock *)
Definition: synch.c:243
void lock_acquire(struct lock *)
Definition: synch.c:202
static struct lock tid_lock
Definition: thread.c:41
int tid_t
Definition: thread.h:25
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_priority()

bool cmp_priority ( const struct list_elem a,
const struct list_elem b,
void *aux  UNUSED 
)
449 {
450 return list_entry(a, struct thread, elem) -> priority \
451 > list_entry(b, struct thread, elem) -> priority ? \
452 1 : 0;
453}
#define list_entry(LIST_ELEM, STRUCT, MEMBER)
Definition: list.h:103
Definition: thread.h:100
Here is the caller graph for this function:

◆ do_iret()

void do_iret ( struct intr_frame tf)
577 {
578 __asm __volatile(
579 "movq %0, %%rsp\n"
580 "movq 0(%%rsp),%%r15\n"
581 "movq 8(%%rsp),%%r14\n"
582 "movq 16(%%rsp),%%r13\n"
583 "movq 24(%%rsp),%%r12\n"
584 "movq 32(%%rsp),%%r11\n"
585 "movq 40(%%rsp),%%r10\n"
586 "movq 48(%%rsp),%%r9\n"
587 "movq 56(%%rsp),%%r8\n"
588 "movq 64(%%rsp),%%rsi\n"
589 "movq 72(%%rsp),%%rdi\n"
590 "movq 80(%%rsp),%%rbp\n"
591 "movq 88(%%rsp),%%rdx\n"
592 "movq 96(%%rsp),%%rcx\n"
593 "movq 104(%%rsp),%%rbx\n"
594 "movq 112(%%rsp),%%rax\n"
595 "addq $120,%%rsp\n"
596 "movw 8(%%rsp),%%ds\n"
597 "movw (%%rsp),%%es\n"
598 "addq $32, %%rsp\n"
599 "iretq"
600 : : "g" ((uint64_t) tf) : "memory");
601}
__asm __volatile("wrmsr" ::"c"(ecx), "d"(edx), "a"(eax))
unsigned long long int uint64_t
Definition: stdint.h:29
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_schedule()

static void do_schedule ( int  status)
static
678 {
680 ASSERT (thread_current()->status == THREAD_RUNNING);
681 while (!list_empty (&destruction_req)) { // 좀비 스레드 제거
682 struct thread *victim =
684 palloc_free_page(victim);
685 }
687 schedule ();
688}
#define ASSERT(CONDITION)
Definition: debug.h:30
@ INTR_OFF
Definition: interrupt.h:9
enum intr_level intr_get_level(void)
Definition: interrupt.c:115
struct list_elem * list_pop_front(struct list *)
Definition: list.c:251
bool list_empty(struct list *)
Definition: list.c:296
void palloc_free_page(void *)
Definition: palloc.c:333
struct list_elem elem
Definition: thread.h:112
enum thread_status status
Definition: thread.h:103
struct thread * thread_current(void)
Definition: thread.c:301
static void schedule(void)
Definition: thread.c:691
static struct list destruction_req
Definition: thread.c:44
@ THREAD_RUNNING
Definition: thread.h:17
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_global_ticks()

int64_t get_global_ticks ( void  )
390 {
391 return global_ticks;
392}
static int64_t global_ticks
Definition: thread.c:48
Here is the caller graph for this function:

◆ idle() [1/2]

static void idle ( void *aux  UNUSED)
static
Here is the caller graph for this function:

◆ idle() [2/2]

static void idle ( void *idle_started_  UNUSED)
static
492 {
493 struct semaphore *idle_started = idle_started_;
494
496 sema_up (idle_started);
497
498 for (;;) {
499 /* Let someone else run. */
500 intr_disable ();
501 thread_block ();
502
503 /* Re-enable interrupts and wait for the next one.
504
505 The `sti' instruction disables interrupts until the
506 completion of the next instruction, so these two
507 instructions are executed atomically. This atomicity is
508 important; otherwise, an interrupt could be handled
509 between re-enabling interrupts and waiting for the next
510 one to occur, wasting as much as one clock tick worth of
511 time.
512
513 See [IA32-v2a] "HLT", [IA32-v2b] "STI", and [IA32-v3a]
514 7.11.1 "HLT Instruction". */
515 asm volatile ("sti; hlt" : : : "memory");
516 }
517}
enum intr_level intr_disable(void)
Definition: interrupt.c:151
Definition: synch.h:8
void sema_up(struct semaphore *)
Definition: synch.c:114
static struct thread * idle_thread
Definition: thread.c:35
void thread_block(void)
Definition: thread.c:258
Here is the call graph for this function:

◆ init_thread()

static void init_thread ( struct thread t,
const char *  name,
int  priority 
)
static
534 {
535 ASSERT (t != NULL);
536 ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
537 ASSERT (name != NULL);
538
539 memset (t, 0, sizeof *t);
541 strlcpy (t->name, name, sizeof t->name);
542 t->tf.rsp = (uint64_t) t + PGSIZE - sizeof (void *);
543 t->priority = priority;
544 /*------------------------- [P1] Priority Scheduling --------------------------*/
545 t->priority_base = priority; // 초기 priority 상태를 확인한다.
546 t->wait_on_lock = NULL; // 스레드 생성시에는 기다리는 락이 없으니 NULL값으로 설정한다.
547 list_init (&t->donations); // donations 초기화
548 t->magic = THREAD_MAGIC;
549
550/*------------------------- [P2] System Call --------------------------*/
551 t->exit_status = 0;
552 t->running = NULL;
553
554 /* 자식 리스트 및 세마포어 초기화 */
556 sema_init(&t->wait_sema,0);
557 sema_init(&t->fork_sema,0);
558 sema_init(&t->free_sema,0);
559}
void list_init(struct list *)
Definition: list.c:58
#define NULL
Definition: stddef.h:4
size_t strlcpy(char *, const char *, size_t)
Definition: string.c:302
void * memset(void *, int, size_t)
Definition: string.c:258
uintptr_t rsp
Definition: interrupt.h:60
int priority
Definition: thread.h:105
struct lock * wait_on_lock
Definition: thread.h:108
unsigned magic
Definition: thread.h:151
char name[16]
Definition: thread.h:104
struct list donations
Definition: thread.h:114
int priority_base
Definition: thread.h:107
int exit_status
Definition: thread.h:131
struct file * running
Definition: thread.h:130
struct semaphore free_sema
Definition: thread.h:134
struct intr_frame tf
Definition: thread.h:150
struct list child_list
Definition: thread.h:127
struct semaphore fork_sema
Definition: thread.h:133
struct semaphore wait_sema
Definition: thread.h:135
void sema_init(struct semaphore *, unsigned value)
Definition: synch.c:52
#define THREAD_MAGIC
Definition: thread.c:21
@ THREAD_BLOCKED
Definition: thread.h:19
#define PRI_MAX
Definition: thread.h:31
#define PRI_MIN
Definition: thread.h:29
#define PGSIZE
Definition: vaddr.h:20
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kernel_thread()

static void kernel_thread ( thread_func function,
void *  aux 
)
static
521 {
522 ASSERT (function != NULL);
523
524 intr_enable (); /* The scheduler runs with interrupts off. */
525 function (aux); /* Execute the thread function. */
526 thread_exit (); /* If function() returns, kill the thread. */
527}
enum intr_level intr_enable(void)
Definition: interrupt.c:136
void thread_exit(void)
Definition: thread.c:325
Here is the call graph for this function:
Here is the caller graph for this function:

◆ next_thread_to_run()

static struct thread * next_thread_to_run ( void  )
static
567 {
568 if (list_empty (&ready_list)){
569 return idle_thread;
570 }
571 else
572 return list_entry (list_pop_front (&ready_list), struct thread, elem);
573}
static struct list ready_list
Definition: thread.c:29
Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule()

static void schedule ( void  )
static
691 {
692 struct thread *curr = running_thread ();
693 struct thread *next = next_thread_to_run ();
694
696 ASSERT (curr->status != THREAD_RUNNING);
697 ASSERT (is_thread (next)); // 다음 스레드로 컨텍스트 스위칭
698 /* Mark us as running. */
699 next->status = THREAD_RUNNING;
700
701 /* Start new time slice. */
702 thread_ticks = 0;
703
704#ifdef USERPROG
705 /* Activate the new address space. */
707#endif
708
709 if (curr != next) {
710 /* If the thread we switched from is dying, destroy its struct
711 thread. This must happen late so that thread_exit() doesn't
712 pull out the rug under itself.
713 We just queuing the page free reqeust here because the page is
714 currently used bye the stack.
715 The real destruction logic will be called at the beginning of the
716 schedule(). */
717 if (curr && curr->status == THREAD_DYING && curr != initial_thread) {
718 ASSERT (curr != next);
720 }
721
722 /* Before switching the thread, we first save the information
723 * of current running. */
725 }
726}
static int next(int pos)
Definition: intq.c:74
void list_push_back(struct list *, struct list_elem *)
Definition: list.c:202
void process_activate(struct thread *next)
Definition: process.c:379
#define is_thread(t)
Definition: thread.c:81
#define running_thread()
Definition: thread.c:88
static void thread_launch(struct thread *th)
Definition: thread.c:614
static unsigned thread_ticks
Definition: thread.c:57
static struct thread * next_thread_to_run(void)
Definition: thread.c:567
static struct thread * initial_thread
Definition: thread.c:38
@ THREAD_DYING
Definition: thread.h:20
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_global_ticks()

void set_global_ticks ( int64_t  ticks)
397 {
398 if (ticks < global_ticks) {
400 }
401}
static int64_t ticks
Definition: timer.c:22
Here is the caller graph for this function:

◆ thread_awake()

void thread_awake ( int64_t  ticks)
405 {
406 struct list_elem *curr = list_begin(&sleep_list);
407 set_global_ticks(INT64_MAX); // 기존 글로벌 틱으로 비교하면 초기화되지 않음
408 struct thread *curr_thread;
409 while (curr != list_end(&sleep_list)){ // 전체 순회
410 curr_thread = list_entry(curr, struct thread, elem);
411 if (curr_thread -> wakeup_tick <= ticks) {
412 curr = list_remove(curr); // curr을 슬립 리스트에서 뻄
413 thread_unblock(curr_thread); // curr을 레디 상태로 만듦(unblocked)
414 } else {
415 set_global_ticks(curr_thread -> wakeup_tick);
416 // 슬립 리스트에서 현재 깨어나야하는 시간이 ticks 보다 클때, 디음 루틴을 위해 글로벌 틱을 재설정한다.
417 curr = curr -> next;
418 }
419 }
420}
struct list_elem * list_begin(struct list *)
Definition: list.c:68
struct list_elem * list_remove(struct list_elem *)
Definition: list.c:241
struct list_elem * list_end(struct list *)
Definition: list.c:88
#define INT64_MAX
Definition: stdint.h:17
Definition: list.h:87
int64_t wakeup_tick
Definition: thread.h:109
void thread_unblock(struct thread *t)
Definition: thread.c:275
static struct list sleep_list
Definition: thread.c:32
void set_global_ticks(int64_t ticks)
Definition: thread.c:397
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_block()

void thread_block ( void  )
258 {
259 ASSERT (!intr_context ());
262 schedule ();
263}
bool intr_context(void)
Definition: interrupt.c:258
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_create()

tid_t thread_create ( const char *  name,
int  priority,
thread_func function,
void *  aux 
)
197 {
198 struct thread *t;
199 tid_t tid;
200
201 ASSERT (function != NULL);
202
203 /* Allocate thread. */
205 if (t == NULL)
206 return TID_ERROR;
207
208 /* Initialize thread. */
210 tid = t->tid = allocate_tid ();
211
212 /*------------------------- [P2] System Call --------------------------*/
214 if (t->fdt == NULL) {
215 return TID_ERROR;
216 }
217 t->next_fd = 2; // 0 : stdin, 1 : stdout
218 t->fdt[0] = 1; // STDIN_FILENO -> dummy value
219 t->fdt[1] = 2; // STDOUT_FILENO -> dummy value
220
221/*------------------------- [P2] System Call - Thread --------------------------*/
222 /* 현재 스레드의 자식 리스트에 새로 생성한 스레드 추가 */
223 struct thread *curr = thread_current();
225
226 /* Call the kernel_thread if it scheduled.
227 * Note) rdi is 1st argument, and rsi is 2nd argument. */
229 t->tf.R.rdi = (uint64_t) function;
230 t->tf.R.rsi = (uint64_t) aux;
231 t->tf.ds = SEL_KDSEG;
232 t->tf.es = SEL_KDSEG;
233 t->tf.ss = SEL_KDSEG;
234 t->tf.cs = SEL_KCSEG;
235 t->tf.eflags = FLAG_IF;
236
237 /*------------------------- [P1] Priority Scheduling --------------------------*/
238 /* Add to run queue. */
239 thread_unblock (t); // ready_list 에 새로 넣은 스레드
240
241 if (thread_get_priority() < priority) { //1. 현재 실행중인 스레드와 새로 추가하려는 스레드 비교
242 if (intr_context())
244 else
245 thread_yield(); //2. 만약 새로 추가하려는 스레드가 현재 실행중인 스레드보다 우선순위가 높으면 CPU를 선점한다.
246 }
247 return tid;
248}
#define FLAG_IF
Definition: flags.h:6
void intr_yield_on_return(void)
Definition: interrupt.c:269
#define SEL_KDSEG
Definition: loader.h:37
#define SEL_KCSEG
Definition: loader.h:36
@ PAL_ZERO
Definition: palloc.h:10
void * palloc_get_page(enum palloc_flags)
Definition: palloc.c:301
void * palloc_get_multiple(enum palloc_flags, size_t page_cnt)
Definition: palloc.c:263
uint64_t uintptr_t
Definition: stdint.h:36
uint64_t rdi
Definition: interrupt.h:29
uint64_t rsi
Definition: interrupt.h:28
uint16_t ss
Definition: interrupt.h:61
uintptr_t rip
Definition: interrupt.h:55
uint16_t es
Definition: interrupt.h:41
uint16_t ds
Definition: interrupt.h:44
uint16_t cs
Definition: interrupt.h:56
uint64_t eflags
Definition: interrupt.h:59
struct gp_registers R
Definition: interrupt.h:40
struct list_elem child_elem
Definition: thread.h:128
int next_fd
Definition: thread.h:123
tid_t tid
Definition: thread.h:102
struct file ** fdt
Definition: thread.h:122
static void kernel_thread(thread_func *, void *aux)
Definition: thread.c:521
static tid_t allocate_tid(void)
Definition: thread.c:730
int thread_get_priority(void)
Definition: thread.c:441
void thread_yield(void)
Definition: thread.c:343
static void init_thread(struct thread *, const char *name, int priority)
Definition: thread.c:534
#define FDT_PAGES
Definition: thread.h:34
#define TID_ERROR
Definition: thread.h:26
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_current()

struct thread * thread_current ( void  )
301 {
302 struct thread *t = running_thread ();
303
304 /* Make sure T is really a thread.
305 If either of these assertions fire, then your thread may
306 have overflowed its stack. Each thread has less than 4 kB
307 of stack, so a few big automatic arrays or moderate
308 recursion can cause stack overflow. */
309 ASSERT (is_thread (t));
311
312 return t;
313}

◆ thread_exit()

void thread_exit ( void  )
325 {
326 ASSERT (!intr_context ());
327 struct thread *curr = thread_current (); // 현재 스레드의 포인터
328
329#ifdef USERPROG
330 process_exit ();
331#endif
332
333 /* Just set our status to dying and schedule another process.
334 We will be destroyed during the call to schedule_tail(). */
335 intr_disable ();
337 NOT_REACHED ();
338}
#define NOT_REACHED()
Definition: debug.h:34
void process_exit(void)
Definition: process.c:328
static void do_schedule(int status)
Definition: thread.c:678
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_get_load_avg()

int thread_get_load_avg ( void  )
470 {
471 /* TODO: Your implementation goes here */
472 return 0;
473}

◆ thread_get_nice()

int thread_get_nice ( void  )
463 {
464 /* TODO: Your implementation goes here */
465 return 0;
466}

◆ thread_get_priority()

int thread_get_priority ( void  )
441 {
442 return thread_current ()->priority;
443}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_get_recent_cpu()

int thread_get_recent_cpu ( void  )
477 {
478 /* TODO: Your implementation goes here */
479 return 0;
480}

◆ thread_init()

void thread_init ( void  )
110 {
111 printf("thread init\n");
113
114 /* Reload the temporal gdt for the kernel
115 * This gdt does not include the user context.
116 * The kernel will rebuild the gdt with user context, in gdt_init (). */
117 struct desc_ptr gdt_ds = {
118 .size = sizeof (gdt) - 1,
119 .address = (uint64_t) gdt
120 };
121 lgdt (&gdt_ds);
122
123 /*------------------------- [P1] Alarm Clock --------------------------*/
124 /* Init the globla thread context */
127 list_init (&sleep_list); // sleep_list를 초기화 한다.
129
130 /* Set up a thread structure for the running thread. */
135}
struct desc_ptr gdt_ds
Definition: gdt.c:75
uint64_t address
Definition: mmu.h:1
int printf(const char *,...) PRINTF_FORMAT(1
Definition: mmu.h:30
uint16_t size
Definition: mmu.h:31
void lock_init(struct lock *)
Definition: synch.c:186
static uint64_t gdt[3]
Definition: thread.c:94
#define PRI_DEFAULT
Definition: thread.h:30
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_launch()

static void thread_launch ( struct thread th)
static
614 {
615 uint64_t tf_cur = (uint64_t) &running_thread ()->tf;
616 uint64_t tf = (uint64_t) &th->tf;
618
619 /* The main switching logic.
620 * We first restore the whole execution context into the intr_frame
621 * and then switching to the next thread by calling do_iret.
622 * Note that, we SHOULD NOT use any stack from here
623 * until switching is done. */
624 __asm __volatile (
625 /* Store registers that will be used. */
626 "push %%rax\n"
627 "push %%rbx\n"
628 "push %%rcx\n"
629 /* Fetch input once */
630 "movq %0, %%rax\n"
631 "movq %1, %%rcx\n"
632 "movq %%r15, 0(%%rax)\n"
633 "movq %%r14, 8(%%rax)\n"
634 "movq %%r13, 16(%%rax)\n"
635 "movq %%r12, 24(%%rax)\n"
636 "movq %%r11, 32(%%rax)\n"
637 "movq %%r10, 40(%%rax)\n"
638 "movq %%r9, 48(%%rax)\n"
639 "movq %%r8, 56(%%rax)\n"
640 "movq %%rsi, 64(%%rax)\n"
641 "movq %%rdi, 72(%%rax)\n"
642 "movq %%rbp, 80(%%rax)\n"
643 "movq %%rdx, 88(%%rax)\n"
644 "pop %%rbx\n" // Saved rcx
645 "movq %%rbx, 96(%%rax)\n"
646 "pop %%rbx\n" // Saved rbx
647 "movq %%rbx, 104(%%rax)\n"
648 "pop %%rbx\n" // Saved rax
649 "movq %%rbx, 112(%%rax)\n"
650 "addq $120, %%rax\n"
651 "movw %%es, (%%rax)\n"
652 "movw %%ds, 8(%%rax)\n"
653 "addq $32, %%rax\n"
654 "call __next\n" // read the current rip.
655 "__next:\n"
656 "pop %%rbx\n"
657 "addq $(out_iret - __next), %%rbx\n"
658 "movq %%rbx, 0(%%rax)\n" // rip
659 "movw %%cs, 8(%%rax)\n" // cs
660 "pushfq\n"
661 "popq %%rbx\n"
662 "mov %%rbx, 16(%%rax)\n" // eflags
663 "mov %%rsp, 24(%%rax)\n" // rsp
664 "movw %%ss, 32(%%rax)\n"
665 "mov %%rcx, %%rdi\n"
666 "call do_iret\n"
667 "out_iret:\n"
668 : : "g"(tf_cur), "g" (tf) : "memory"
669 );
670}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_name()

const char * thread_name ( void  )
293 {
294 return thread_current ()->name;
295}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_print_stats()

void thread_print_stats ( void  )
176 {
177 printf ("Thread: %lld idle ticks, %lld kernel ticks, %lld user ticks\n",
179}
static long long user_ticks
Definition: thread.c:53
static long long idle_ticks
Definition: thread.c:51
static long long kernel_ticks
Definition: thread.c:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_set_nice()

void thread_set_nice ( int nice  UNUSED)
457 {
458 /* TODO: Your implementation goes here */
459}

◆ thread_set_priority()

void thread_set_priority ( int  new_priority)
426 {
427 thread_current ()->priority_base = new_priority;
429
430 if (thread_get_priority () < list_entry (list_begin (&ready_list), struct thread, elem)->priority) {
431 if (intr_context())
433 else
434 thread_yield ();
435 }
436}
void refresh_priority(void)
Definition: synch.c:304
Here is the call graph for this function:

◆ thread_sleep()

void thread_sleep ( int64_t  ticks)
365 { // ticks : 해당 스레드가 깨어나야 할 절대적인 시간 (eg. 12:05)
366 struct thread *curr = thread_current (); // 현재 스레드의 포인터
367 enum intr_level old_level; // 이전 상태
368
369 ASSERT (!intr_context ());
370
371 old_level = intr_disable (); // 인터럽터를 비활성화 시킨다.
372 if (curr != idle_thread) // 현재 스레드가 유휴 스레드가 아니면 sleep_list의 맨 뒤로 넣는다.
373 {
374 curr -> wakeup_tick = ticks; // 깨워야할 시간으로 새로 받은 인자를 넣는다.
375 list_push_back (&sleep_list, &curr->elem); // 현재 스레드를 레디리스트의 맨 뒤로 삽입한다.
376 // curr -> status = THREAD_BLOCKED;
377
379 }
380
381 /* 스레드의 상태를 BLOCKED로 전환하고 컨텍스트 스위치(schedule())를 수행한다. */
382 thread_block();
383 // do_schedule (THREAD_BLOCKED); (= thread_block)
384 intr_set_level (old_level); // 이후 다시 인터럽터를 활성화한다.
385}
enum intr_level intr_set_level(enum intr_level)
Definition: interrupt.c:130
intr_level
Definition: interrupt.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_start()

void thread_start ( void  )
140 {
141 /* Create the idle thread. */
142 struct semaphore idle_started;
143 sema_init (&idle_started, 0);
144 thread_create ("idle", PRI_MIN, idle, &idle_started);
145
146 /* Start preemptive thread scheduling. */
147 intr_enable ();
148
149 /* Wait for the idle thread to initialize idle_thread. */
150 sema_down (&idle_started);
151}
void sema_down(struct semaphore *)
Definition: synch.c:68
static void idle(void *aux UNUSED)
tid_t thread_create(const char *name, int priority, thread_func *function, void *aux)
Definition: thread.c:197
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_tick()

void thread_tick ( void  )
156 {
157 struct thread *t = thread_current ();
158
159 /* Update statistics. */
160 if (t == idle_thread)
161 idle_ticks++;
162#ifdef USERPROG
163 else if (t->pml4 != NULL)
164 user_ticks++;
165#endif
166 else
167 kernel_ticks++;
168
169 /* Enforce preemption. */
170 if (++thread_ticks >= TIME_SLICE)
172}
uint64_t * pml4
Definition: thread.h:121
#define TIME_SLICE
Definition: thread.c:56
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_tid()

tid_t thread_tid ( void  )
317 {
318 return thread_current ()->tid;
319}
Here is the call graph for this function:

◆ thread_unblock()

void thread_unblock ( struct thread t)
275 {
276 enum intr_level old_level;
277
278 ASSERT (is_thread (t));
279
280 old_level = intr_disable ();
282 /*------------------------- [P1] Priority Scheduling --------------------------*/
283 /* origin code
284 list_push_back (&ready_list, &t->elem);
285 */
286 list_insert_ordered(&ready_list, &t -> elem, cmp_priority, NULL); // 정렬된 상태로 스레드가 삽입되도록 한다.
287 t->status = THREAD_READY;
288 intr_set_level (old_level);
289}
void list_insert_ordered(struct list *, struct list_elem *, list_less_func *, void *aux)
Definition: list.c:419
bool cmp_priority(const struct list_elem *a, const struct list_elem *b, void *aux UNUSED)
Definition: thread.c:449
@ THREAD_READY
Definition: thread.h:18
Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_yield()

void thread_yield ( void  )
343 {
344 struct thread *curr = thread_current (); // 현재 스레드의 포인터
345 enum intr_level old_level;
346
347 ASSERT (!intr_context ());
348
349 old_level = intr_disable (); // 인터럽터를 비활성화한다.
350 if (curr != idle_thread) { // 현재 스레드가 유휴 스레드가 아니면 리스트의 맨 뒤로 넣는다.
351 /*------------------------- [P1] Alarm Clock --------------------------*/
352 /* origin code
353 list_push_back (&ready_list, &curr->elem); // 현재 스레드를 레디리스트의 맨 뒤로 삽입한다.
354 */
355 /*------------------------- [P1] Priority Scheduling --------------------------*/
356 list_insert_ordered(&ready_list, &curr -> elem, cmp_priority, NULL); // 정렬된 상태로 스레드가 삽입되도록 한다.
357 }
358 do_schedule (THREAD_READY); // ready 상태로 전환하고 컨텍스트 스위칭을 한다.
359 intr_set_level (old_level); // 이후 다시 이전 상태로 되돌린다.
360}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ destruction_req

struct list destruction_req
static

◆ gdt

uint64_t gdt[3] = { 0, 0x00af9a000000ffff, 0x00cf92000000ffff }
static

◆ global_ticks

int64_t global_ticks = INT64_MAX
static

◆ idle_thread

struct thread* idle_thread
static

◆ idle_ticks

long long idle_ticks
static

◆ initial_thread

struct thread* initial_thread
static

◆ kernel_ticks

long long kernel_ticks
static

◆ ready_list

struct list ready_list
static

◆ sleep_list

struct list sleep_list
static

◆ thread_mlfqs

bool thread_mlfqs

◆ thread_ticks

unsigned thread_ticks
static

◆ tid_lock

struct lock tid_lock
static

◆ user_ticks

long long user_ticks
static