diff --git a/ChangeLog b/ChangeLog index 5a0dab4..911b4cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,13 +1,18 @@ 2013-05-29 Niibe Yutaka + * entry.c (entry): Initialize data section. + * chopstx.c (svc): Implement race avoidance between chx_handle_intr. (chx_handle_intr): Increment ->ready. Put to ready queue only when it's not running. (chx_sched): Add an argument for race avoidance. - (chopstx_intr_wait): Fix the race condition. + (chopstx_intr_wait): Fix race condition. (chopstx_cond_broadcast): Fix initial value. (chopstx_join): Check RET. + (chx_init): Initialize q_exit and q_join. + (chopstx_release_irq, chopstx_release_irq_thread): Enable IRQ on + release (as system reset default). * board/board-olimex-stm32-h103.h (NEUG_ADC_SETTING2_*): Add. diff --git a/chopstx.c b/chopstx.c index 6a81638..acb9258 100644 --- a/chopstx.c +++ b/chopstx.c @@ -51,27 +51,22 @@ struct chx_dll { }; +struct chx_queue { + struct chx_thread *next, *prev; + struct chx_spinlock lock; +}; + /* READY: priority queue. */ -struct chx_ready { - struct chx_thread *next, *prev; - struct chx_spinlock lock; -}; +static struct chx_queue q_ready; -static struct chx_ready q_ready; - -struct chx_timer { - struct chx_thread *next, *prev; - struct chx_spinlock lock; -}; - -/* threads waiting for timer. */ -static struct chx_timer q_timer; +/* Queue of threads waiting for timer. */ +static struct chx_queue q_timer; /* Queue of threads which have been exited. */ -static struct chx_timer q_exit; +static struct chx_queue q_exit; /* Queue of threads which wait exit of some thread. */ -static struct chx_timer q_join; +static struct chx_queue q_join; /* Forward declaration(s). */ @@ -648,6 +643,8 @@ chx_init (struct chx_thread *tp) memset (&tp->tc, 0, sizeof (tp->tc)); q_ready.next = q_ready.prev = (struct chx_thread *)&q_ready; q_timer.next = q_timer.prev = (struct chx_thread *)&q_timer; + q_exit.next = q_exit.prev = (struct chx_thread *)&q_exit; + q_join.next = q_join.prev = (struct chx_thread *)&q_join; tp->next = tp->prev = tp; tp->mutex_list = NULL; tp->state = THREAD_RUNNING; @@ -692,7 +689,7 @@ chx_exit (void *retval) struct chx_thread *q; asm volatile ("cpsid i" : : : "memory"); - if (!running->flag_join_req) + if (running->flag_join_req) { /* wake up a thread which requests to join */ chx_LOCK (&q_join.lock); for (q = q_join.next; q != (struct chx_thread *)&q_join; q = q->next) @@ -706,13 +703,13 @@ chx_exit (void *retval) } chx_LOCK (&q_exit.lock); - if (!running->flag_detached) + if (running->flag_detached) + running->state = THREAD_FINISHED; + else { ll_insert (running, &q_exit); running->state = THREAD_EXITED; } - else - running->state = THREAD_FINISHED; chx_UNLOCK (&q_exit.lock); asm volatile ("cpsie i" : : "r" (r4) : "memory"); chx_sched (NULL); @@ -1016,7 +1013,7 @@ chopstx_release_irq (chopstx_intr_t *intr0) chopstx_intr_t *intr, *intr_prev; asm volatile ("cpsid i" : : : "memory"); - chx_disable_intr (intr0->irq_num); + chx_enable_intr (intr0->irq_num); intr_prev = intr_top; for (intr = intr_top; intr; intr = intr->next) if (intr == intr0) @@ -1043,7 +1040,7 @@ chopstx_release_irq_thread (struct chx_thread *tp) if (intr) { - chx_disable_intr (intr->irq_num); + chx_enable_intr (intr->irq_num); if (intr == intr_top) intr_top = intr_top->next; else diff --git a/entry.c b/entry.c index 727bffb..1b6d65e 100644 --- a/entry.c +++ b/entry.c @@ -264,14 +264,27 @@ static __attribute__ ((naked,section(".text.startup.0"))) void entry (void) { asm volatile ("bl clock_init\n\t" - /* Clear BSS. Assume its size is > 0. */ + /* Clear BSS section. */ "mov r0, #0\n\t" "ldr r1, =_bss_start\n\t" "ldr r2, =_bss_end\n" "0:\n\t" + "cmp r1, r2\n\t" + "beq 1f\n\t" "str r0, [r1], #4\n\t" - "cmp r2, r1\n\t" - "bhi 0b\n\t" + "b 0b\n" + "1:\n\t" + /* Copy data section. */ + "ldr r1, =_data\n\t" + "ldr r2, =_edata\n\t" + "ldr r3, =_textdata\n" + "2:\n\t" + "cmp r1, r2\n\t" + "beq 3f\n\t" + "ldr r0, [r3], #4\n\t" + "str r0, [r1], #4\n\t" + "b 2b\n" + "3:\n\t" /* Switch to PSP. */ "ldr r0, =__process0_stack_end__\n\t" "sub r0, #56\n\t" @@ -289,8 +302,8 @@ void entry (void) /* Call main. */ "mov r1, r0\n\t" "bl main\n" - "1:\n\t" - "b 1b" + "4:\n\t" + "b 4b" : /* no output */ : /* no input */ : "memory"); }