mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
timer: don't die at a few specific edge cases anymore
This commit is contained in:
@@ -24,6 +24,7 @@ typedef struct{
|
|||||||
size_t timerticksperus;
|
size_t timerticksperus;
|
||||||
timer_req* timerfirstreq;
|
timer_req* timerfirstreq;
|
||||||
timer_req schedreq;
|
timer_req schedreq;
|
||||||
|
bool timerpending;
|
||||||
} cls_t;
|
} cls_t;
|
||||||
|
|
||||||
void bsp_setcls();
|
void bsp_setcls();
|
||||||
|
|||||||
+29
-2
@@ -10,13 +10,28 @@ void timer_init(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void timer_irq(arch_regs* ctx){
|
void timer_irq(arch_regs* ctx){
|
||||||
|
|
||||||
timer_req* pendingreq = arch_getcls()->timerfirstreq;
|
timer_req* pendingreq = arch_getcls()->timerfirstreq;
|
||||||
timer_req* iter = pendingreq->next;
|
timer_req* iter = pendingreq->next;
|
||||||
|
|
||||||
|
if(arch_getcls()->timerpending){ // if we know we stopped, don't do anything yet
|
||||||
|
while(iter){
|
||||||
|
iter->ticks -= pendingreq->ticks;
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
arch_getcls()->timerfirstreq = iter;
|
arch_getcls()->timerfirstreq = iter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while(iter){
|
while(iter){
|
||||||
iter->ticks -= pendingreq->ticks;
|
iter->ticks -= pendingreq->ticks;
|
||||||
|
if(iter->ticks == 0){
|
||||||
|
iter->func(ctx, iter->argptr);
|
||||||
|
arch_getcls()->timerfirstreq = iter->next;
|
||||||
|
}
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +44,14 @@ void timer_irq(arch_regs* ctx){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void timer_resume(){
|
void timer_resume(){
|
||||||
|
if(arch_getcls()->timerpending){ // if an int was pending, have it happen
|
||||||
|
timer_req* iter = arch_getcls()->timerfirstreq;
|
||||||
|
while(iter){
|
||||||
|
iter->ticks++;
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
arch_getcls()->timerpending = false;
|
||||||
|
}
|
||||||
arch_cputimer_fire(arch_getcls()->timerfirstreq->ticks);
|
arch_cputimer_fire(arch_getcls()->timerfirstreq->ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +59,11 @@ void timer_stop(){
|
|||||||
|
|
||||||
size_t remainingticks = arch_cputimer_stop();
|
size_t remainingticks = arch_cputimer_stop();
|
||||||
timer_req* iter = arch_getcls()->timerfirstreq;
|
timer_req* iter = arch_getcls()->timerfirstreq;
|
||||||
|
if(!iter) return;
|
||||||
|
|
||||||
|
if(remainingticks == 0) // interrupt is pending
|
||||||
|
arch_getcls()->timerpending = true;
|
||||||
|
|
||||||
size_t subticks = iter->ticks - remainingticks;
|
size_t subticks = iter->ticks - remainingticks;
|
||||||
while(iter){
|
while(iter){
|
||||||
iter->ticks -= subticks;
|
iter->ticks -= subticks;
|
||||||
@@ -44,7 +72,6 @@ void timer_stop(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void timer_add(timer_req* req, size_t us, bool start){
|
void timer_add(timer_req* req, size_t us, bool start){
|
||||||
|
|
||||||
size_t remainingticks = arch_cputimer_stop();
|
size_t remainingticks = arch_cputimer_stop();
|
||||||
|
|
||||||
timer_req* iter = arch_getcls()->timerfirstreq;
|
timer_req* iter = arch_getcls()->timerfirstreq;
|
||||||
|
|||||||
Reference in New Issue
Block a user