[Krafton Jungle] PintOS 2.0.0
크래프톤 정글 PintOS
 
Loading...
Searching...
No Matches
timer.c File Reference
#include "devices/timer.h"
#include <debug.h>
#include <inttypes.h>
#include <round.h>
#include <stdio.h>
#include "threads/interrupt.h"
#include "threads/io.h"
#include "threads/synch.h"
#include "threads/thread.h"
Include dependency graph for timer.c:

Functions

static bool too_many_loops (unsigned loops)
 
static void busy_wait (int64_t loops)
 
static void real_time_sleep (int64_t num, int32_t denom)
 
void timer_init (void)
 
void timer_calibrate (void)
 
int64_t timer_ticks (void)
 
int64_t timer_elapsed (int64_t then)
 
void timer_sleep (int64_t ticks)
 
void timer_msleep (int64_t ms)
 
void timer_usleep (int64_t us)
 
void timer_nsleep (int64_t ns)
 
void timer_print_stats (void)
 
static void timer_interrupt (struct intr_frame *args UNUSED)
 

Variables

static int64_t ticks
 
static unsigned loops_per_tick
 
static intr_handler_func timer_interrupt
 

Function Documentation

◆ busy_wait()

static void NO_INLINE busy_wait ( int64_t  loops)
static
170 {
171 while (loops-- > 0)
172 barrier ();
173}
#define barrier()
Definition: synch.h:50
Here is the caller graph for this function:

◆ real_time_sleep()

static void real_time_sleep ( int64_t  num,
int32_t  denom 
)
static
177 {
178 /* Convert NUM/DENOM seconds into timer ticks, rounding down.
179
180 (NUM / DENOM) s
181 ---------------------- = NUM * TIMER_FREQ / DENOM ticks.
182 1 s / TIMER_FREQ ticks
183 */
184 int64_t ticks = num * TIMER_FREQ / denom;
185
187 if (ticks > 0) {
188 /* We're waiting for at least one full timer tick. Use
189 timer_sleep() because it will yield the CPU to other
190 processes. */
192 } else {
193 /* Otherwise, use a busy-wait loop for more accurate
194 sub-tick timing. We scale the numerator and denominator
195 down by 1000 to avoid the possibility of overflow. */
196 ASSERT (denom % 1000 == 0);
197 busy_wait (loops_per_tick * num / 1000 * TIMER_FREQ / (denom / 1000));
198 }
199}
#define ASSERT(CONDITION)
Definition: debug.h:30
@ INTR_ON
Definition: interrupt.h:10
enum intr_level intr_get_level(void)
Definition: interrupt.c:115
signed long long int int64_t
Definition: stdint.h:16
static unsigned loops_per_tick
Definition: timer.c:26
static int64_t ticks
Definition: timer.c:22
static void busy_wait(int64_t loops)
Definition: timer.c:170
void timer_sleep(int64_t ticks)
Definition: timer.c:95
#define TIMER_FREQ
Definition: timer.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_calibrate()

void timer_calibrate ( void  )
51 {
52 unsigned high_bit, test_bit;
53
55 printf ("Calibrating timer... ");
56
57 /* Approximate loops_per_tick as the largest power-of-two
58 still less than one timer tick. */
59 loops_per_tick = 1u << 10;
60 while (!too_many_loops (loops_per_tick << 1)) {
61 loops_per_tick <<= 1;
63 }
64
65 /* Refine the next 8 bits of loops_per_tick. */
66 high_bit = loops_per_tick;
67 for (test_bit = high_bit >> 1; test_bit != high_bit >> 10; test_bit >>= 1)
68 if (!too_many_loops (high_bit | test_bit))
69 loops_per_tick |= test_bit;
70
71 printf ("%'"PRIu64" loops/s.\n", (uint64_t) loops_per_tick * TIMER_FREQ);
72}
#define PRIu64
Definition: inttypes.h:30
unsigned long long int uint64_t
Definition: stdint.h:29
int printf(const char *,...) PRINTF_FORMAT(1
static bool too_many_loops(unsigned loops)
Definition: timer.c:147
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_elapsed()

int64_t timer_elapsed ( int64_t  then)
87 {
88 return timer_ticks () - then;
89}
int64_t timer_ticks(void)
Definition: timer.c:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_init()

void timer_init ( void  )
37 {
38 /* 8254 input frequency divided by TIMER_FREQ, rounded to
39 nearest. */
40 uint16_t count = (1193180 + TIMER_FREQ / 2) / TIMER_FREQ;
41
42 outb (0x43, 0x34); /* CW: counter 0, LSB then MSB, mode 2, binary. */
43 outb (0x40, count & 0xff);
44 outb (0x40, count >> 8);
45
46 intr_register_ext (0x20, timer_interrupt, "8254 Timer");
47}
void intr_register_ext(uint8_t vec, intr_handler_func *, const char *name)
Definition: interrupt.c:228
static void outb(uint16_t port, uint8_t data)
Definition: io.h:109
unsigned short int uint16_t
Definition: stdint.h:23
static intr_handler_func timer_interrupt
Definition: timer.c:28
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_interrupt()

static void timer_interrupt ( struct intr_frame *args  UNUSED)
static
135 {
136 ticks++;
137 thread_tick (); // update the cpu usage for running process
138
139 if (get_global_ticks() <= ticks){ // 현재 시각이 글로벌 틱보다 크면 스레드 깨우기
141 }
142}
void thread_awake(int64_t ticks)
Definition: thread.c:405
void thread_tick(void)
Definition: thread.c:156
int64_t get_global_ticks(void)
Definition: thread.c:390
Here is the call graph for this function:

◆ timer_msleep()

void timer_msleep ( int64_t  ms)
110 {
111 real_time_sleep (ms, 1000);
112}
static void real_time_sleep(int64_t num, int32_t denom)
Definition: timer.c:177
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_nsleep()

void timer_nsleep ( int64_t  ns)
122 {
123 real_time_sleep (ns, 1000 * 1000 * 1000);
124}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_print_stats()

void timer_print_stats ( void  )
128 {
129 printf ("Timer: %"PRId64" ticks\n", timer_ticks ());
130}
#define PRId64
Definition: inttypes.h:27
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_sleep()

void timer_sleep ( int64_t  ticks)
95 { // ticks 시간 만큼 뒤에 꺠어난다.(상대 시간 (eg. 5분))
96 int64_t start = timer_ticks (); // 현재 시간(프로그램 부트 이후 시간 (eg. 12시))
97
99 /* 기존 코드 : busy waiting 방식
100 while (timer_elapsed (start) < ticks)
101 thread_yield ();
102 */
103 if (timer_elapsed (start) < ticks) // 현재 시간부터의 경과 시간이 ticks 보다 작으면(깨울 때가 아님)
104 thread_sleep(start + ticks); // 해당 스레드를 sleep(BLOCKED)시킨다.
105 // ↳ 해당 스레드가 깨어나야할 절대 시간인 (start + ticks)를 인자로 넘긴다.
106}
void thread_sleep(int64_t ticks)
Definition: thread.c:365
int64_t timer_elapsed(int64_t then)
Definition: timer.c:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_ticks()

int64_t timer_ticks ( void  )
76 {
77 enum intr_level old_level = intr_disable ();
78 int64_t t = ticks;
79 intr_set_level (old_level);
80 barrier ();
81 return t;
82}
enum intr_level intr_set_level(enum intr_level)
Definition: interrupt.c:130
enum intr_level intr_disable(void)
Definition: interrupt.c:151
intr_level
Definition: interrupt.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_usleep()

void timer_usleep ( int64_t  us)
116 {
117 real_time_sleep (us, 1000 * 1000);
118}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ too_many_loops()

static bool too_many_loops ( unsigned  loops)
static
147 {
148 /* Wait for a timer tick. */
149 int64_t start = ticks;
150 while (ticks == start)
151 barrier ();
152
153 /* Run LOOPS loops. */
154 start = ticks;
155 busy_wait (loops);
156
157 /* If the tick count changed, we iterated too long. */
158 barrier ();
159 return start != ticks;
160}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ loops_per_tick

unsigned loops_per_tick
static

◆ ticks

int64_t ticks
static

◆ timer_interrupt

intr_handler_func timer_interrupt
static