Add join and exit

This commit is contained in:
NIIBE Yutaka
2013-05-27 09:08:17 +09:00
parent cf4a340023
commit b0cfda694f
4 changed files with 86 additions and 11 deletions

View File

@@ -1,3 +1,7 @@
2013-05-27 Niibe Yutaka <gniibe@fsij.org>
* chopstx.c (chx_fatal, chopstx_exit, chopstx_join): New.
2013-05-24 Niibe Yutaka <gniibe@fsij.org>
* chopstx.c (chx_request_preemption): Rename from chx_preempt.

View File

@@ -31,6 +31,14 @@
#include <string.h>
#include <chopstx.h>
void __attribute__((weak))
chx_fatal (uint32_t err_code)
{
(void)err_code;
for (;;);
}
/* RUNNING: the current thread. */
struct chx_thread *running;
@@ -59,7 +67,12 @@ struct chx_timer {
/* threads waiting for timer. */
static struct chx_timer q_timer;
/* XXX: q_exit; Queue for threads already exited. */
/* Queue of threads which have been exited. */
static struct chx_timer q_exit;
/* Queue of threads which wait exit of some thread. */
static struct chx_timer q_waitexit;
/* Forward declaration(s). */
static void chx_request_preemption (void);
@@ -226,7 +239,7 @@ ll_prio_enqueue (struct chx_thread *tp0, void *head)
*/
#define THREAD_WAIT_MTX 0x00000001
#define THREAD_WAIT_CND 0x00000002
#define THREAD_WAITTIME 0x00000003
#define THREAD_WAIT_OBJ 0x00000003 /* Timer (24-bit), thread */
#define THREAD_RUNNING 0x00000000
#define THREAD_WAIT_INT 0x00000004
@@ -408,7 +421,7 @@ chx_set_timer (struct chx_thread *q, uint32_t ticks)
*SYST_RVR = 0;
}
else
q->v = (ticks<<8)|THREAD_WAITTIME;
q->v = (ticks<<8)|THREAD_WAIT_OBJ;
}
static void
@@ -508,12 +521,12 @@ chx_set_intr_prio (uint8_t n)
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (INTR_PRIO << sh);
}
static chopstix_intr_t *intr_top;
static chopstx_intr_t *intr_top;
void
chx_handle_intr (void)
{
chopstix_intr_t *intr;
chopstx_intr_t *intr;
register uint32_t irq_num;
asm volatile ("cpsid i\n\t"
@@ -838,7 +851,7 @@ chopstx_cond_broadcast (chopstx_cond_t *cond)
void
chopstx_intr_register (chopstix_intr_t *intr, uint8_t irq_num)
chopstx_intr_register (chopstx_intr_t *intr, uint8_t irq_num)
{
intr->irq_num = irq_num;
intr->t = running;
@@ -853,7 +866,7 @@ chopstx_intr_register (chopstix_intr_t *intr, uint8_t irq_num)
void
chopstx_wait_intr (chopstix_intr_t *intr)
chopstx_wait_intr (chopstx_intr_t *intr)
{
asm volatile ("cpsid i" : : : "memory");
chx_enable_intr (intr->irq_num);
@@ -868,3 +881,58 @@ chopstx_wait_intr (chopstix_intr_t *intr)
intr->ready--;
asm volatile ("cpsie i" : : : "memory");
}
/* The RETVAL is saved into register R4. */
void __attribute__((noreturn))
chopstx_exit (void *retval)
{
register uint32_t r4 __asm__ ("r4") = (uint32_t)retval;
struct chx_thread *q;
asm volatile ("cpsid i" : : : "memory");
/* wake up a thread waiting to join */
chx_LOCK (&q_waitexit.lock);
for (q = q_waitexit.next; q != (struct chx_thread *)&q_waitexit; q = q->next)
if ((q->v & ~3) == (uint32_t)running)
{ /* should be one at most. */
ll_dequeue (q);
chx_ready_enqueue (q);
break;
}
chx_UNLOCK (&q_waitexit.lock);
chx_LOCK (&q_exit.lock);
ll_insert (running, &q_exit);
running->v = THREAD_EXITED;
chx_UNLOCK (&q_exit.lock);
asm volatile ("cpsie i" : : "r" (r4) : "memory");
chx_sched ();
/* never comes here. */
for (;;);
}
int
chopstx_join (chopstx_t thd, void **ret)
{
struct chx_thread *tp = (struct chx_thread *)thd;
/* XXX: check if another thread is waiting same thread and return error. */
/* XXX: dead lock detection (waiting each other) and return error. */
asm volatile ("cpsid i" : : : "memory");
if (tp->v != THREAD_EXITED)
{
chx_LOCK (&q_waitexit.lock);
ll_insert (running, &q_waitexit);
running->v = ((uint32_t) tp) | THREAD_WAIT_OBJ;
chx_UNLOCK (&q_waitexit.lock);
asm volatile ("cpsie i" : : : "memory");
chx_sched ();
}
else
asm volatile ("cpsie i" : : : "memory");
*ret = (void *)tp->tc.reg[0];
return 0;
}

View File

@@ -84,8 +84,11 @@ typedef struct chx_intr {
struct chx_thread *t;
uint8_t irq_num;
uint8_t ready;
} chopstix_intr_t;
} chopstx_intr_t;
void chopstx_intr_register (chopstix_intr_t *intr, uint8_t irq_num);
void chopstx_intr_register (chopstx_intr_t *intr, uint8_t irq_num);
void chopstx_wait_intr (chopstix_intr_t *intr);
void chopstx_wait_intr (chopstx_intr_t *intr);
/* Library provides default as weak reference. User can replace it. */
void chx_fatal (uint32_t err_code);

View File

@@ -63,7 +63,7 @@ usb_intr (void *arg)
extern void usb_lld_init (uint8_t feature);
extern void usb_interrupt_handler (void);
chopstix_intr_t interrupt;
chopstx_intr_t interrupt;
(void)arg;
asm volatile ("cpsid i" : : : "memory");