aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-03-04 17:00:25 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-03-04 17:00:25 +0000
commit9619334634b1921a4f3af220adbd7feea85e2c02 (patch)
tree842a0672012bc67eac1ca70fa42fe34c2d882bb4
parentd73a265d598c2c4b35ec8b59e1fbdd3fe5b67729 (diff)
reduce size
-rw-r--r--kernel/dmx.c8
-rw-r--r--kernel/kernel.c112
2 files changed, 54 insertions, 66 deletions
diff --git a/kernel/dmx.c b/kernel/dmx.c
index d7369c8..74596b1 100644
--- a/kernel/dmx.c
+++ b/kernel/dmx.c
@@ -41,10 +41,10 @@ main()
init(48);
exec(heartbeat, NULL, 48);
- exec(rgb, &rgbargs, 72);
- exec(pwm, &pwmargs[0], 56);
- exec(pwm, &pwmargs[1], 56);
- exec(pwm, &pwmargs[2], 56);
+ exec(rgb, &rgbargs, 66);
+ exec(pwm, &pwmargs[0], 60);
+ exec(pwm, &pwmargs[1], 60);
+ exec(pwm, &pwmargs[2], 60);
exec(adc, &adcarg, 96);
exec(clock, NULL, 96);
#if 0
diff --git a/kernel/kernel.c b/kernel/kernel.c
index c285fbf..8ef32b9 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -50,13 +50,18 @@ struct kernel {
TAILQ_HEAD(queue, task) runq, timeq, waitq;
struct task task[1 + TASKS];
struct task *nextfree;
- struct task *current;
uint16_t cycles;
uint8_t *freemem;
uint8_t semaphore;
- uint8_t rqlen;
} kernel;
+void
+setrq(struct task *tp)
+{
+ tp->state = RUNQ;
+ TAILQ_INSERT_TAIL(&kernel.runq, tp, link);
+}
+
ISR(TIMER1_OVF_vect)
{
++kernel.cycles;
@@ -64,7 +69,7 @@ ISR(TIMER1_OVF_vect)
ISR(TIMER1_COMPA_vect, ISR_NAKED)
{
- struct task *tp, *tmp;
+ struct task *tp, *tmp, *cur;
uint32_t now;
uint16_t nexthit;
int32_t dist;
@@ -76,74 +81,61 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
PORTB ^= _BV(PB1); /* DEBUG */
#endif
- /* store context */
- kernel.current->sp = SP;
- TAILQ_REMOVE(&kernel.runq, kernel.current, link);
- --kernel.rqlen;
+ cur = TAILQ_FIRST(&kernel.runq);
+ TAILQ_REMOVE(&kernel.runq, cur, link);
/* release waiting tasks */
TAILQ_FOREACH_SAFE(tp, &kernel.timeq, link, tmp) {
if (DISTANCE(now, tp->release) <= 0) {
TAILQ_REMOVE(&kernel.timeq, tp, link);
- tp->state = RUNQ;
- TAILQ_INSERT_TAIL(&kernel.runq, tp, link);
- ++kernel.rqlen;
+ setrq(tp);
} else
break;
}
- switch (kernel.current->state) {
+ switch (cur->state) {
case RUNQ:
/* 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;
+ if (cur != &kernel.task[0])
+ setrq(cur);
break;
case TIMEQ:
/* find right position on time queue */
- TAILQ_FOREACH(tp, &kernel.timeq, link) {
- if (DISTANCE(kernel.current->release, tp->release) > 0)
+ TAILQ_FOREACH(tp, &kernel.timeq, link)
+ if (DISTANCE(cur->release, tp->release) > 0)
break;
- }
if (tp)
- TAILQ_INSERT_BEFORE(tp, kernel.current, link);
+ TAILQ_INSERT_BEFORE(tp, cur, link);
else
- TAILQ_INSERT_TAIL(&kernel.timeq, kernel.current, link);
+ TAILQ_INSERT_TAIL(&kernel.timeq, cur, link);
break;
case WAITQ:
- if (kernel.semaphore & _BV(kernel.current->chan)) {
+ if (kernel.semaphore & _BV(cur->chan)) {
/* semaphore busy, go into wait queue */
- TAILQ_INSERT_TAIL(&kernel.waitq, kernel.current, link);
+ TAILQ_INSERT_TAIL(&kernel.waitq, cur, link);
} else {
/* occupy semaphore */
- kernel.semaphore |= _BV(kernel.current->chan);
+ kernel.semaphore |= _BV(cur->chan);
/* go into the end of run queue again */
- kernel.current->state = RUNQ;
- TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, link);
- ++kernel.rqlen;
+ setrq(cur);
}
break;
case SIGNAL:
/* release waiting tasks from wait queue */
TAILQ_FOREACH_SAFE(tp, &kernel.waitq, link, tmp) {
- if (tp->chan == kernel.current->chan) {
+ if (tp->chan == cur->chan) {
TAILQ_REMOVE(&kernel.waitq, tp, link);
- tp->state = RUNQ;
- TAILQ_INSERT_TAIL(&kernel.runq, tp, link);
- ++kernel.rqlen;
+ setrq(tp);
}
}
- /* clear semaphore */
- kernel.semaphore &= ~_BV(kernel.current->chan);
- /* and go back to run queue */
- kernel.current->state = RUNQ;
- TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, link);
- ++kernel.rqlen;
+ /* clear semaphore, and go back to run queue */
+ kernel.semaphore &= ~_BV(cur->chan);
+ setrq(cur);
break;
default:
@@ -151,16 +143,10 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
}
/* idle if nothing to run */
- if (TAILQ_EMPTY(&kernel.runq)) {
- TAILQ_INSERT_TAIL(&kernel.runq, &kernel.task[0], link);
- ++kernel.rqlen;
- }
+ if (TAILQ_EMPTY(&kernel.runq))
+ setrq(&kernel.task[0]);
- /* restore context */
- kernel.current = TAILQ_FIRST(&kernel.runq);
- SP = kernel.current->sp;
-
- nexthit = UINT16_MAX >> kernel.rqlen;
+ nexthit = UINT16_MAX;
if ((tp = TAILQ_FIRST(&kernel.timeq))) {
dist = DISTANCE(now, tp->release);
@@ -170,6 +156,10 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
OCR1A = (uint16_t)(now + nexthit);
+ /* switch context */
+ cur->sp = SP;
+ SP = TAILQ_FIRST(&kernel.runq)->sp;
+
POP_ALL();
reti();
}
@@ -199,11 +189,9 @@ init(uint8_t stack)
kernel.cycles = 0;
kernel.nextfree = &kernel.task[1];
kernel.freemem = (void *)(RAMEND - stack);
- kernel.current = &kernel.task[0];
- kernel.current->state = TERMINATED;
- kernel.current->release = 0;
+ kernel.task->state = RUNQ;
+ kernel.task->release = 0;
TAILQ_INSERT_TAIL(&kernel.runq, &kernel.task[0], link);
- kernel.rqlen = 1;
sei();
}
@@ -211,7 +199,7 @@ init(uint8_t stack)
void
exec(void (*fun)(void *), void *args, uint8_t stack)
{
- struct task *t;
+ struct task *tp;
uint8_t *sp;
cli();
@@ -232,12 +220,12 @@ exec(void (*fun)(void *), void *args, uint8_t stack)
sp -= 6;
memset(sp, 0, 6); /* r26-r31 */
- t = kernel.nextfree++;
- t->release = NOW(kernel.cycles, TCNT1);
- t->chan = 0;
- t->sp = (uint16_t)sp; /* SP */
- t->state = TIMEQ;
- TAILQ_INSERT_TAIL(&kernel.timeq, t, link);
+ tp = kernel.nextfree++;
+ tp->release = NOW(kernel.cycles, TCNT1);
+ tp->chan = 0;
+ tp->sp = (uint16_t)sp; /* SP */
+ tp->state = TIMEQ;
+ TAILQ_INSERT_TAIL(&kernel.timeq, tp, link);
SCHEDULE();
}
@@ -247,8 +235,8 @@ wait(uint8_t chan)
{
cli();
- kernel.current->chan = chan;
- kernel.current->state = WAITQ;
+ TAILQ_FIRST(&kernel.runq)->chan = chan;
+ TAILQ_FIRST(&kernel.runq)->state = WAITQ;
SCHEDULE();
}
@@ -258,7 +246,7 @@ signal(void)
{
cli();
- kernel.current->state = SIGNAL;
+ TAILQ_FIRST(&kernel.runq)->state = SIGNAL;
SCHEDULE();
}
@@ -268,8 +256,8 @@ sleep(uint32_t sec, uint32_t usec)
{
cli();
- kernel.current->release += SEC(sec) + USEC(usec);
- kernel.current->state = TIMEQ;
+ TAILQ_FIRST(&kernel.runq)->release += SEC(sec) + USEC(usec);
+ TAILQ_FIRST(&kernel.runq)->state = TIMEQ;
SCHEDULE();
}
@@ -287,7 +275,7 @@ suspend(void)
{
cli();
- kernel.current->state = TERMINATED;
+ TAILQ_FIRST(&kernel.runq)->state = TERMINATED;
SCHEDULE();
}
@@ -301,5 +289,5 @@ now(void)
uint8_t
running(void)
{
- return kernel.current - kernel.task;
+ return TAILQ_FIRST(&kernel.runq) - kernel.task;
}