From 2e846df799e47af67fe177472e0912f88e4f5146 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 24 Feb 2012 14:31:15 +0000 Subject: introduce run queue length, trying to predict next wakeup, still buggy --- kernel/kernel.c | 24 +++++++++++++++++++++--- kernel/kernel.h | 1 + kernel/uart.c | 20 +++++++++++++++++++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index d0bfdb1..933dd25 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -54,6 +54,7 @@ struct kernel { uint16_t cycles; uint8_t *freemem; uint8_t semaphore; + uint8_t rqlen; } kernel; ISR(TIMER1_OVF_vect) @@ -76,13 +77,15 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* store context */ kernel.current->sp = SP; TAILQ_REMOVE(&kernel.runq, kernel.current, link); + --kernel.rqlen; /* release waiting tasks */ TAILQ_FOREACH_SAFE(tp, &kernel.timeq, link, tmp) { if (DISTANCE(now, tp->release) <= 0) { - tp->state = RUNQ; TAILQ_REMOVE(&kernel.timeq, tp, link); + tp->state = RUNQ; TAILQ_INSERT_TAIL(&kernel.runq, tp, link); + ++kernel.rqlen; } else break; } @@ -92,6 +95,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* readd current task at the end of run queue */ /* idle is always in TERMINATED state and is skipped here */ TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, link); + ++kernel.rqlen; break; case TIMEQ: /* find right position on time queue */ @@ -114,6 +118,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* go into the end of run queue again */ kernel.current->state = RUNQ; TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, link); + ++kernel.rqlen; } break; case SIGNAL: @@ -123,6 +128,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) TAILQ_REMOVE(&kernel.waitq, tp, link); tp->state = RUNQ; TAILQ_INSERT_TAIL(&kernel.runq, tp, link); + ++kernel.rqlen; } } @@ -131,14 +137,17 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* and go back to run queue */ kernel.current->state = RUNQ; TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, link); + ++kernel.rqlen; break; default: break; } /* idle if nothing to run */ - if (TAILQ_EMPTY(&kernel.runq)) + if (TAILQ_EMPTY(&kernel.runq)) { TAILQ_INSERT_TAIL(&kernel.runq, &kernel.task[0], link); + ++kernel.rqlen; + } /* restore context */ kernel.current = TAILQ_FIRST(&kernel.runq); @@ -147,7 +156,9 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* nexthit */ if ((tp = TAILQ_FIRST(&kernel.timeq))) now += DISTANCE(now, tp->release); - OCR1A = now; + else + now += UINT16_MAX / kernel.rqlen; + OCR1A = (uint16_t)now; POP_ALL(); reti(); @@ -183,6 +194,7 @@ init(uint8_t stack) kernel.current->state = TERMINATED; kernel.current->release = 0; TAILQ_INSERT_TAIL(&kernel.runq, &kernel.task[0], link); + kernel.rqlen = 1; sei(); } @@ -283,3 +295,9 @@ running(void) { return kernel.current - kernel.task; } + +uint8_t +load(void) +{ + return kernel.rqlen; +} diff --git a/kernel/kernel.h b/kernel/kernel.h index b53634c..b22519f 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -90,6 +90,7 @@ void yield(void); uint32_t now(void); uint8_t running(void); +uint8_t load(void); /* __END_DECLS */ diff --git a/kernel/uart.c b/kernel/uart.c index 8407113..9522808 100644 --- a/kernel/uart.c +++ b/kernel/uart.c @@ -33,6 +33,9 @@ FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); +enum { Tasks, Load }; +uint8_t udrie_flag = Tasks; + #ifdef USE_RXCIE ISR(SIG_UART_RECV) { @@ -53,8 +56,14 @@ ISR(SIG_UART_RECV) break; case 'T': UCSRB |= _BV(UDRIE); + udrie_flag = Tasks; + break; + case 'L': + UCSRB |= _BV(UDRIE); + udrie_flag = Load; break; case 't': + case 'l': UCSRB &= ~_BV(UDRIE); break; case '\r': @@ -68,7 +77,16 @@ ISR(SIG_UART_RECV) ISR(SIG_UART_DATA) { - uint8_t r = running(); + uint8_t r = 0; + + switch (udrie_flag) { + case Tasks: + r = running(); + break; + case Load: + r = load(); + break; + } UDR = r ? '0' + r : '.'; } -- cgit v1.2.3