Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- HTML
- 모션비트
- 크래프톤정글
- userprog
- 핀토스
- TiL
- 자바스크립트
- 나만무
- Flutter
- 소켓
- Java
- 알고리즘
- 코드트리
- 4기
- defee
- 리액트
- 스택
- Vue.js
- 티스토리챌린지
- 사이드프로젝트
- 백준
- 큐
- JavaScript
- 오블완
- corou
- 자바
- CSS
- 시스템콜
- pintos
- 크래프톤 정글
Archives
- Today
- Total
미새문지
pintOS - project1(Thread) timer.c 본문
728x90
timer.c
< macro >
더보기
// 초당 타이머 인터럽트 횟수가 19 초과 1000 미만
#if TIMER_FREQ < 19
#error 8254 timer requires TIMER_FREQ >= 19
#endif
#if TIMER_FREQ > 1000
#error TIMER_FREQ <= 1000 recommended
#endif
< timer_init >
더보기
/*초당 PIT_FREQ를 인터럽트하고 해당 인터럽트를 등록시킨다.
pit = 프로그래밍된 카운트에 도달할 때 출력 신호를 생성하는 카운터*/
void
timer_init (void) {
/* 8254 입력 주파수를 TIMER_FREQ로 나눈 값을 가장 가까운 값으로 반올림 */
uint16_t count = (1193180 + TIMER_FREQ / 2) / TIMER_FREQ;
/* outb (pit의 제어워드 레지스터, 설정하려는 제어워드 값) */
outb (0x43, 0x34); /* CW: counter 0, LSB then MSB, mode 2, binary. */
outb (0x40, count & 0xff);
outb (0x40, count >> 8);
// 운영체제의 인터럽트 처리 시스템에서 사용되는 함수 호출
// (인터럽트 벡터 번호, 인터럽트 발생 시 호출 함수, 처리 루틴이나 이름 제공)
intr_register_ext (0x20, timer_interrupt, "8254 Timer");
}
< timer_calibrate >
더보기
// 짧은 지연을 구현하는데 사용하는 loops_per_tick을 보정한다.
void
timer_calibrate (void) {
unsigned high_bit, test_bit;
ASSERT (intr_get_level () == INTR_ON);
printf ("Calibrating timer... ");
// 적절한 loops_per_tick을 2의 제곱형태로 보여준다. << 여전히 timer tick보다 작다.
loops_per_tick = 1u << 10;
while (!too_many_loops (loops_per_tick << 1)) {
loops_per_tick <<= 1;
ASSERT (loops_per_tick != 0);
}
// 다음 8비트의 loops_per_tick을 세분화
high_bit = loops_per_tick;
for (test_bit = high_bit >> 1; test_bit != high_bit >> 10; test_bit >>= 1)
if (!too_many_loops (high_bit | test_bit))
loops_per_tick |= test_bit;
printf ("%'"PRIu64" loops/s.\n", (uint64_t) loops_per_tick * TIMER_FREQ);
}
< timer_ticks >
더보기
// OS 부팅 후 타이머 틱 수를 반환한다.
int64_t
timer_ticks (void) {
enum intr_level old_level = intr_disable (); // 기존 인터럽트 상태를 저장하고 비활성화
int64_t t = ticks; // t에 ticks를 저장
intr_set_level (old_level); // 다시 이전 인터럽트 상태를 가져오기
barrier (); // 메모리 접근 순서를 명확하게 하기 위해 사용
return t;
}
< timer_elapsed >
더보기
// timer_ticks에 의해 반환된 값, 이후 경과한 타이머 틱수를 반환한다.
int64_t
timer_elapsed (int64_t then) {
return timer_ticks () - then;
}
< timer_sleep >
더보기
// TICKS timer ticks를 대략적으로 실행을 중지한다.
void
timer_sleep (int64_t ticks) {
int64_t start = timer_ticks (); // 타이머 틱수를 start에 저장
if(ticks <= 0) // 만약 받아온 ticks가 없으면 종료
return;
ASSERT(intr_get_level() == INTR_ON); // 인터럽트가 꺼져있으면 종료
thread_sleep(ticks+start); // 스레드를 재우기 위해 ticks와 부팅 후 지난 ticks를 더해 매개변수로 전달
}
< timer_interrput >
더보기
// 인터럽트 핸들러
static void
timer_interrupt (struct intr_frame *args UNUSED) {
// ticks를 증가시키고 틱마다 인터럽트 핸들러를 호출
ticks++;
thread_tick ();
thread_wakeup(ticks); // ticks를 전달하여 스레드를 깨운다.
// mlfqs가 활성화 되있으면 일정한 주기마다 시스템의 평균 부하를 계산한다.
if (thread_mlfqs == true){
if(timer_ticks() % TIMER_FREQ == 0)
update_load_avg();
}
}
< too_many_loops >
더보기
/* 루프 반복이 ticks보다 오래걸리는지 확인 */
static bool
too_many_loops (unsigned loops) {
// 타이머가 울릴 때까지 기다린다
int64_t start = ticks;
while (ticks == start)
barrier ();
// loops만큼 반복 작업 수행
start = ticks;
busy_wait (loops);
// 틱수가 다르면 너무 오래 반복한 것 false 반환, 같으면 true 반환
barrier ();
return start != ticks;
}
< busy_wait >
더보기
// 루프를 loops 시간만큼 반복
static void NO_INLINE
busy_wait (int64_t loops) {
while (loops-- > 0)
barrier ();
}
728x90
'크래프톤 정글 > pintOS' 카테고리의 다른 글
pintOS - Project 2 Userprog WIL (2) | 2024.03.23 |
---|---|
pintOS - project1(Thread) synch.c (2) | 2024.03.12 |
pintOS - project1(Thread) thread.c - mlfqs (3) | 2024.03.11 |
pintOS - project1(Thread) thread.c (1) | 2024.03.11 |
pintOS - Project 1 Thread WIL (1) | 2024.03.11 |