Skip to content

Commit

Permalink
Merge pull request #70 from bassaer/develop
Browse files Browse the repository at this point in the history
[ver 1.13.0] support multiple timer
  • Loading branch information
bassaer committed Mar 5, 2020
2 parents dab39d9 + cc561bc commit e85e002
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 26 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## ver 1.13.0
- support multiple timer

## ver 1.12.0
- add sleep command

Expand Down
12 changes: 10 additions & 2 deletions bin/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ int sleep(char *args[], int size) {
return EXIT_FAILURE;
}

struct Timer *timer = new_timer();
if(timer == 0) {
printf("failed to make timer\n");
return EXIT_FAILURE;
}

struct Queue queue;
unsigned char buf[8];
init_queue(&queue, 8, buf);
int timeout = atoi(args[1]) * 100;

set_timer(timeout, &queue, 1);
init_timer(timer, &queue, 1);

int timeout = atoi(args[1]) * 100;
set_timer(timer, timeout);

while(1) {
// 割り込み無効化
Expand Down
27 changes: 23 additions & 4 deletions include/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,36 @@

#include <lib/queue.h>

struct timer_ctrl {
unsigned int count;
#define TIMER_MAX_NUM 500

enum TimerStatus {
STOPPED,
READY,
RUNNING
};

struct Timer {
unsigned int timeout;
enum TimerStatus status;
struct Queue *queue;
unsigned char data;
} timer;
};

struct TimerCtrl {
unsigned int uptime;
struct Timer timers[TIMER_MAX_NUM];
} timerctrl;

void init_pit();

struct Timer* new_timer();

void free_timer(struct Timer *timer);

void init_timer(struct Timer *timer, struct Queue *queue, unsigned char data);

void handle_intr20(int *esp);

void set_timer(unsigned int timeout, struct Queue *queue, unsigned char data);
void set_timer(struct Timer *timer, unsigned int timeout);

#endif
64 changes: 44 additions & 20 deletions kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,59 @@ void init_pit() {
*/
outb_p(PIT_CNT0, 0x9c);
outb_p(PIT_CNT0, 0x2e);
timer.count++;
timerctrl.uptime = 0;

// タイマーの状態を初期化
int i;
for (i = 0; i < TIMER_MAX_NUM; i++) {
timerctrl.timers[i].status = STOPPED;
}
}

struct Timer* new_timer() {
int i;
for (i = 0; i < TIMER_MAX_NUM; i++) {
if (timerctrl.timers[i].status == STOPPED) {
timerctrl.timers[i].status = READY;
return &timerctrl.timers[i];
}
}
return 0;
}


void free_timer(struct Timer *timer) {
timer->status = STOPPED;
}

void init_timer(struct Timer *timer, struct Queue *queue, unsigned char data) {
timer->queue = queue;
timer->data = data;
}

/**
* IRQ0用割り込みハンドラ
*/
void handle_intr20(int *esp) {
outb_p(PIC0_OCW2, 0x60); // IRQ-00受付完了をPICに通知
timer.count++;
// タイムアウトが設定されている場合
if (timer.timeout > 0) {
timer.timeout--;
if (timer.timeout == 0 ){//&& queue_status(timer.queue) != 0) {
unsigned char buf[8];
dequeue(timer.queue, buf);
timerctrl.uptime++;
int i;
for(i = 0; i < TIMER_MAX_NUM; i++) {
if (timerctrl.timers[i].status == RUNNING) {
// タイムアウトが設定されている場合
timerctrl.timers[i].timeout--;
if (timerctrl.timers[i].timeout == 0 ){
timerctrl.timers[i].status = READY;
unsigned char buf[8];
dequeue(timerctrl.timers[i].queue, buf);
}
}
}
}

void set_timer(unsigned int timeout, struct Queue *queue, unsigned char data) {
// EFLAGSは32bit拡張のレジスタ
// キャリーフラグや割り込みフラグなどを保持する
int eflags = io_load_eflags();
// 設定中の割り込みを禁止する
io_cli();
timer.timeout = timeout;
timer.queue = queue;
timer.data = data;
enqueue(timer.queue, timer.data);
// 割り込み状態を元の状態に戻す
io_store_eflags(eflags);
void set_timer(struct Timer *timer, unsigned int timeout) {
// 現在時刻から
timer->timeout = timeout;
timer->status = RUNNING;
enqueue(timer->queue, timer->data);
}

0 comments on commit e85e002

Please sign in to comment.