aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-03-05 01:03:37 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-03-05 01:03:37 +0000
commit80d133f74a14daae36989e937e80dae644e0d36b (patch)
treeafc0406a7084eb9eb48c2b7c7e684130ddd9f4cf
parent652f877abd0d3a47d9b3fdb5ae27db0483e1cf94 (diff)
readd separate semaphore queues
-rw-r--r--kernel/Makefile.inc3
-rw-r--r--kernel/dmx/Makefile1
-rw-r--r--kernel/kernel.c28
-rw-r--r--kernel/kernel.h5
4 files changed, 21 insertions, 16 deletions
diff --git a/kernel/Makefile.inc b/kernel/Makefile.inc
index f52bcbc..c8677ca 100644
--- a/kernel/Makefile.inc
+++ b/kernel/Makefile.inc
@@ -11,7 +11,8 @@ SIZE= avr-size
CFLAGS= -mmcu=${MCU} -Wall -Os \
-DF_CPU=${F_CPU} -DPRESCALE=${PRESCALE} \
- -DBAUD=${BAUD} -DSTACK=${STACK} -DTASKS=${TASKS}
+ -DBAUD=${BAUD} -DSTACK=${STACK} -DTASKS=${TASKS} \
+ -DSEMAPHORES=${SEMAPHORES}
LDFLAGS= -mmcu=${MCU} -Wl,-Map,${PROG}.map
.SUFFIXES: .lst .hex .bin .srec .ehex .ebin .esrec
diff --git a/kernel/dmx/Makefile b/kernel/dmx/Makefile
index 7e1ac51..9bcdfec 100644
--- a/kernel/dmx/Makefile
+++ b/kernel/dmx/Makefile
@@ -11,6 +11,7 @@ PRESCALE= 8 # res 0.5usec cycle 32.7msec
#STACK= 48
STACK= 80
TASKS= 11 # +1 idle = 12
+SEMAPHORES= 2
BAUD= 9600
PROG= dmx
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 5d74199..f7c18c6 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -41,12 +41,11 @@ enum State { TERMINATED, RUNQ, TIMEQ, WAITQ, SIGNAL };
struct task {
uint32_t release;
uint16_t sp; /* stack pointer */
- uint8_t chan; /* wait channel */
TAILQ_ENTRY(task) r_link, t_link, w_link;
};
struct kernel {
- TAILQ_HEAD(queue, task) runq, timeq, waitq;
+ TAILQ_HEAD(queue, task) runq, timeq, waitq[SEMAPHORES];
struct task idle[1 + TASKS];
struct task *nextfree;
struct task *current;
@@ -125,6 +124,8 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
void
init(uint8_t stack)
{
+ uint8_t i;
+
cli();
/* Set up timer 1 */
@@ -142,7 +143,8 @@ init(uint8_t stack)
TAILQ_INIT(&kernel.runq);
TAILQ_INIT(&kernel.timeq);
- TAILQ_INIT(&kernel.waitq);
+ for (i = 0; i < SEMAPHORES; i++)
+ TAILQ_INIT(&kernel.waitq[i]);
kernel.cycles = 0;
kernel.nextfree = kernel.idle + 1;
@@ -181,7 +183,6 @@ exec(void (*fun)(void *), void *args, uint8_t stack)
tp = kernel.nextfree++;
tp->release = 0;
- tp->chan = 0;
tp->sp = (uint16_t)sp; /* SP */
TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
++kernel.rqlen;
@@ -194,13 +195,11 @@ wait(uint8_t chan)
{
cli();
- kernel.current->chan = 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);
+ TAILQ_INSERT_TAIL(&kernel.waitq[chan], kernel.current, w_link);
SCHEDULE();
} else {
@@ -214,21 +213,20 @@ wait(uint8_t chan)
void
signal(uint8_t chan)
{
- struct task *tp, *tmp;
+ struct task *tp;
cli();
/* release waiting tasks from wait queue */
- TAILQ_FOREACH_SAFE(tp, &kernel.waitq, w_link, tmp) {
- if (tp->chan == chan) {
- TAILQ_REMOVE(&kernel.waitq, tp, w_link);
- TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
- ++kernel.rqlen;
- }
+ if ((tp = TAILQ_FIRST(&kernel.waitq[chan]))) {
+ TAILQ_REMOVE(&kernel.waitq[chan], tp, w_link);
+ TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
+ ++kernel.rqlen;
}
/* clear semaphore */
- kernel.semaphore &= ~_BV(chan);
+ if (TAILQ_EMPTY(&kernel.waitq[chan]))
+ kernel.semaphore &= ~_BV(chan);
SCHEDULE();
}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 0fe9182..9ad3b5d 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -23,6 +23,11 @@
#define TASKS 8
#endif
+#ifndef SEMAPHORES
+#warning SEMAPHORES not set, fallback to default: 4
+#define SEMAPHORES 4
+#endif
+
#ifndef STACK
#warning STACK not set, fallback to default: 64
#define STACK 64