aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-02-24 14:31:15 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-02-24 14:31:15 +0000
commit2e846df799e47af67fe177472e0912f88e4f5146 (patch)
treee4bfb6db75a85609427d5fab41481cac258cd5e3
parent82b01d18481c7b41a585ad8fba2150fecc599ba1 (diff)
introduce run queue length, trying to predict next wakeup, still buggy
-rw-r--r--kernel/kernel.c24
-rw-r--r--kernel/kernel.h1
-rw-r--r--kernel/uart.c20
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 : '.';
}