Skip to content

Commit

Permalink
Merge pull request #72 from bassaer/develop
Browse files Browse the repository at this point in the history
[ver 1.15.0] use linear list for timer
  • Loading branch information
bassaer committed Mar 7, 2020
2 parents 777f728 + 7ab21ba commit f9a7141
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 45 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.15.0
- use linear list for timer

## ver 1.14.0
- improve timer intr handler
- rename struct
Expand Down
11 changes: 5 additions & 6 deletions include/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ enum timer_status {
RUNNING
};

typedef struct {
typedef struct timer {
struct timer *next;
unsigned int timeout;
enum timer_status status;
queue_t *queue;
Expand All @@ -21,12 +22,10 @@ typedef struct {
typedef struct {
// システム起動時間
unsigned int uptime;
// 次回のタイムアウト時刻
unsigned int next_timeout;
// 次回のタイマー
unsigned int next;
// 現在稼働中のタイマー
unsigned int running_num;
// ソート済みタイマーのリスト
timer_t *sorted_timers[TIMER_MAX_NUM];
timer_t *next_timer;
// すべてのタイマーリスト
timer_t all_timers[TIMER_MAX_NUM];
} timerctrl_t;
Expand Down
81 changes: 42 additions & 39 deletions kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,20 @@ void init_pit() {
outb_p(PIT_CNT0, 0x2e);
timerctrl.uptime = 0;
// 最短のタイマーを設定するため最大値を初期値に設定
timerctrl.next = 0xffffffff;
timerctrl.running_num = 0;
timerctrl.next_timeout = 0xffffffff;
// タイマーの状態を初期化
int i;
for (i = 0; i < TIMER_MAX_NUM; i++) {
timerctrl.all_timers[i].status = STOPPED;
}
timer_t *last_timer = new_timer();
// 最大のタイムアウト時間を設定(約497日)
last_timer->timeout = 0xffffffff;
last_timer->status = RUNNING;
// 次のタイマーはなし
last_timer->next = 0;
timerctrl.next_timer = last_timer;
timerctrl.next_timeout = last_timer->timeout;
}

timer_t* new_timer() {
Expand Down Expand Up @@ -70,32 +77,26 @@ void handle_intr20(int *esp) {
// uptimeを更新
timerctrl.uptime++;
// 次のタイマーの時刻を確認
if (timerctrl.next > timerctrl.uptime) {
if (timerctrl.next_timeout > timerctrl.uptime) {
return;
}
int i;
for(i = 0; i < timerctrl.running_num; i++) {
if (timerctrl.sorted_timers[i]->timeout > timerctrl.uptime ){
// 次のタイマーを取得
timer_t *timer = timerctrl.next_timer;
while(1) {
if (timer->timeout > timerctrl.uptime ){
break;
}
// タイムアウト
timerctrl.sorted_timers[i]->status = READY;
timer->status = READY;
unsigned char buf[8];
dequeue(timerctrl.sorted_timers[i]->queue, buf);
}
// i個タイムアウト
timerctrl.running_num -= i;
int j;
for(j = 0; j < timerctrl.running_num; i++) {
// 残りのタイマーをずらす
timerctrl.sorted_timers[j] = timerctrl.sorted_timers[i + j];
}
if (timerctrl.running_num > 0) {
// 最短のタイマーをセット
timerctrl.next = timerctrl.sorted_timers[0]->timeout;
} else {
timerctrl.next = 0xffffffff;
dequeue(timer->queue, buf);
// 次のタイマーの番地をセット
timer = timer->next;
}
timerctrl.next_timer = timer;

// 最短のタイマーをセット
timerctrl.next_timeout = timerctrl.next_timer->timeout;
}

void set_timer(timer_t *timer, unsigned int timeout) {
Expand All @@ -106,25 +107,27 @@ void set_timer(timer_t *timer, unsigned int timeout) {
// 割り込み禁止
io_cli();

// 格納する場所を探索
int i;
for (i = 0; i < timerctrl.running_num; i++) {
if (timerctrl.sorted_timers[i]->timeout >= timer->timeout) {
break;
}
}
enqueue(timer->queue, timer->data);

// 後ろにずらす
int j;
for (j = 0; j < timerctrl.running_num; j++) {
timerctrl.sorted_timers[j] = timerctrl.sorted_timers[j - 1];
timer_t *next_timer = timerctrl.next_timer;
if (timer->timeout <= next_timer->timeout) {
timerctrl.next_timer = timer;
timer->next = next_timer;
timerctrl.next_timeout = timer->timeout;
io_store_eflags(eflags);
return;
}

timerctrl.running_num++;
// 時間順に格納する
timerctrl.sorted_timers[i] = timer;
enqueue(timer->queue, timer->data);
// 最短のタイマーの場合は更新
timerctrl.next = timerctrl.sorted_timers[0]->timeout;
io_store_eflags(eflags);
timer_t *prev_timer;
while(1) {
prev_timer = next_timer;
next_timer = next_timer->next;
if (timer->timeout <= next_timer->timeout) {
// prev_timerとnext_timerの間に入れる場合
prev_timer->next = timer;
timer->next = next_timer;
io_store_eflags(eflags);
return;
}
}
}

0 comments on commit f9a7141

Please sign in to comment.