aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-03-05 00:11:30 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-03-05 00:11:30 +0000
commitfe281c251a49cebad725208234dd06a6f73731f1 (patch)
tree528a233434f2c8e0c1a4e4ec7f2cbaf2db8f2997
parenta99c5b516dd6d065a803e63747592b12f2ee9597 (diff)
bugfixes, readd rqlen, signal on any channel
-rw-r--r--kernel/adc.c2
-rw-r--r--kernel/clock.c2
-rw-r--r--kernel/kernel.c55
-rw-r--r--kernel/kernel.h4
4 files changed, 37 insertions, 26 deletions
diff --git a/kernel/adc.c b/kernel/adc.c
index e806c99..e3223a5 100644
--- a/kernel/adc.c
+++ b/kernel/adc.c
@@ -44,7 +44,7 @@ adc(void *arg)
}
wait(0);
fprintf(stderr, "\n%8lx%8x", now(), a->value[0]);
- signal();
+ signal(0);
sleep(0, 100000);
}
}
diff --git a/kernel/clock.c b/kernel/clock.c
index 91276d9..7368bf0 100644
--- a/kernel/clock.c
+++ b/kernel/clock.c
@@ -39,7 +39,7 @@ clock(void *arg)
wait(0);
fprintf(stderr, "\r%4d:%.2d:%.2d:%.2d.%1d ", d, h, m, s, ds);
- signal();
+ signal(0);
sleep(0, 100000);
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index ecb9e59..b8d2526 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -53,6 +53,7 @@ struct kernel {
uint16_t cycles;
uint8_t *freemem;
uint8_t semaphore;
+ uint8_t rqlen;
} kernel;
ISR(TIMER1_OVF_vect)
@@ -74,26 +75,33 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
PORTB ^= _BV(PB1); /* DEBUG */
#endif
- if (kernel.current == TAILQ_FIRST(&kernel.runq)) {
+ if (kernel.current == kernel.idle) {
+ /* drop idle */
TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
- if (kernel.current != kernel.idle)
- TAILQ_INSERT_TAIL(&kernel.timeq, kernel.current, t_link);
+ --kernel.rqlen;
+ } else if (kernel.current == TAILQ_FIRST(&kernel.runq)) {
+ /* runq not changed && not empty -> yield */
+ TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
+ TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, r_link);
}
/* release waiting tasks */
TAILQ_FOREACH_SAFE(tp, &kernel.timeq, t_link, tmp) {
- if (DISTANCE(now, tp->release) <= 0) {
+ if (DISTANCE(tp->release, now) >= 0) {
TAILQ_REMOVE(&kernel.timeq, tp, t_link);
TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
+ ++kernel.rqlen;
} else
break;
}
/* idle if nothing to run */
- if (TAILQ_EMPTY(&kernel.runq))
+ if (TAILQ_EMPTY(&kernel.runq)) {
TAILQ_INSERT_TAIL(&kernel.runq, kernel.idle, r_link);
+ ++kernel.rqlen;
+ }
- nexthit = UINT16_MAX;
+ nexthit = UINT16_MAX >> kernel.rqlen;
if ((tp = TAILQ_FIRST(&kernel.timeq))) {
dist = DISTANCE(now, tp->release);
@@ -101,6 +109,8 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
nexthit = dist;
}
+ nexthit >>= kernel.rqlen;
+
OCR1A = (uint16_t)(now + nexthit);
/* switch context */
@@ -140,6 +150,7 @@ init(uint8_t stack)
kernel.idle->release = 0;
TAILQ_INSERT_TAIL(&kernel.runq, kernel.idle, r_link);
kernel.current = TAILQ_FIRST(&kernel.runq);
+ kernel.rqlen = 0;
sei();
}
@@ -173,6 +184,7 @@ exec(void (*fun)(void *), void *args, uint8_t stack)
tp->chan = 0;
tp->sp = (uint16_t)sp; /* SP */
TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
+ ++kernel.rqlen;
SCHEDULE();
}
@@ -182,41 +194,41 @@ wait(uint8_t chan)
{
cli();
- TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
kernel.current->chan = chan;
- if (kernel.semaphore & _BV(kernel.current->chan)) {
+ if (kernel.semaphore & _BV(chan)) {
/* semaphore busy, go into wait queue */
+ TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
+ --kernel.rqlen;
TAILQ_INSERT_TAIL(&kernel.waitq, kernel.current, w_link);
+
+ SCHEDULE();
} else {
/* occupy semaphore */
- kernel.semaphore |= _BV(kernel.current->chan);
- TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, r_link);
- }
+ kernel.semaphore |= _BV(chan);
- SCHEDULE();
+ sei();
+ }
}
void
-signal(void)
+signal(uint8_t chan)
{
struct task *tp, *tmp;
cli();
- TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
-
/* release waiting tasks from wait queue */
TAILQ_FOREACH_SAFE(tp, &kernel.waitq, w_link, tmp) {
- if (tp->chan == kernel.current->chan) {
+ if (tp->chan == chan) {
TAILQ_REMOVE(&kernel.waitq, tp, w_link);
TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
+ ++kernel.rqlen;
}
}
- /* clear semaphore, and go back to run queue */
- kernel.semaphore &= ~_BV(kernel.current->chan);
- TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, r_link);
+ /* clear semaphore */
+ kernel.semaphore &= ~_BV(chan);
SCHEDULE();
}
@@ -229,6 +241,7 @@ sleep(uint32_t sec, uint32_t usec)
cli();
TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
+ --kernel.rqlen;
kernel.current->release += SEC(sec) + USEC(usec);
/* find right position on time queue */
@@ -249,9 +262,6 @@ yield(void)
{
cli();
- TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
- TAILQ_INSERT_TAIL(&kernel.timeq, kernel.current, t_link);
-
SCHEDULE();
}
@@ -261,6 +271,7 @@ suspend(void)
cli();
TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
+ --kernel.rqlen;
SCHEDULE();
}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index b53634c..df7dd6d 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -81,8 +81,8 @@
void init(uint8_t stack);
void exec(void (*fun)(void *), void *args, uint8_t stack);
-void wait(uint8_t sema);
-void signal(void);
+void wait(uint8_t chan);
+void signal(uint8_t chan);
void suspend(void);
void sleep(uint32_t sec, uint32_t usec);