From fe281c251a49cebad725208234dd06a6f73731f1 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 5 Mar 2012 00:11:30 +0000 Subject: bugfixes, readd rqlen, signal on any channel --- kernel/adc.c | 2 +- kernel/clock.c | 2 +- kernel/kernel.c | 55 +++++++++++++++++++++++++++++++++---------------------- kernel/kernel.h | 4 ++-- 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); -- cgit v1.2.3