-
Notifications
You must be signed in to change notification settings - Fork 1
/
timer.cpp
124 lines (110 loc) · 1.97 KB
/
timer.cpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "asmfunc.hpp"
#include "timer.hpp"
#include "fifo.hpp"
#include "heap.hpp"
#include "inputdevices.hpp"
#include "task.hpp"
TIMERCTRL *timerctrl;
void init_pit(){
timerctrl=(TIMERCTRL*)malloc(sizeof(TIMERCTRL));
register_interrupt_handler(IRQ0,&timer_handler);
io_out8(PIT_CTRL,0x34);
io_out8(PIT_CNT0,0x9c);
io_out8(PIT_CNT0,0x2e);
timerctrl->count=0;
for(int i=0;i<MAX_TIMER;i++)
timerctrl->timer[i].flag=FREE;
auto t=timer_alloc();
t->timeout=0xffffffff;
t->flag=USING;
t->next=NULL;
timerctrl->t0=t;
timerctrl->next=0xffffffff;
return;
}
registers_t *regists;
void timer_handler(registers_t regs){
regists=®s;
io_out8(PIC0_OCW2,0x60);
timerctrl->interrupt();
return;
}
extern TIMER *mt_timer;
void TIMERCTRL::interrupt(){
count++;
char ts=0;
if(next>count)return;
auto timer=t0;
for(;;){
if(timer->timeout>count)break;
if(timer!=mt_timer){
if(!timer->fifo->destroyed)
timer->push();
}else{
timer->flag=ALLOC;
ts=1;
}
timer=timer->next;
}
t0=timer;
next=t0->timeout;
if(ts!=0)mt_taskswitch();
return;
}
void TIMERCTRL::regist(TIMER *timer){
auto t=t0;
if(timer->timeout<=t->timeout){
t0=timer;
timer->next=t;
next=timer->timeout;
return;
}
TIMER *s;
for(;;){
s=t;
t=t->next;
if(t==NULL)break;
if(timer->timeout<=t->timeout){
s->next=timer;
timer->next=t;
return;
}
}
return;
}
TIMER *timer_alloc(){
return timerctrl->alloc();
}
TIMER *TIMERCTRL::alloc(){
for(int i=0;i<MAX_TIMER;i++)
if(timer[i].flag==FREE){
timer[i].flag=ALLOC;
return &timer[i];
}
return 0;
}
void TIMER::push(){
flag=ALLOC;
fifo->put(data);
}
void TIMER::free(){
flag=FREE;
return;
}
TIMER *TIMER::init(FIFO *fifo,int data){
this->fifo=fifo;
this->data=data;
return this;
}
void TIMER::setdata(int data){
this->data=data;
}
void TIMER::set(unsigned int timeout){
this->timeout=timerctrl->count+timeout;
flag=USING;
int e=io_load_eflags();
io_cli();
timerctrl->regist(this);
io_store_eflags(e);
return;
}