diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-18 16:52:00 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-18 16:52:00 +0900 |
commit | db413813b6cd8a0891805a1111824ffd4d5a3737 (patch) | |
tree | c69366352fc31f9b7bc8953bed056a579caafae9 | |
parent | 7f009dbb5d44ae67d7bb3529973f2eee2e186612 (diff) |
eventflag rewrite
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | NEWS | 25 | ||||
-rw-r--r-- | chopstx.c | 65 | ||||
-rw-r--r-- | chopstx.h | 13 | ||||
-rw-r--r-- | doc/chopstx-api.texi | 37 | ||||
-rw-r--r-- | eventflag.c | 80 | ||||
-rw-r--r-- | eventflag.h | 10 |
7 files changed, 129 insertions, 109 deletions
@@ -1,7 +1,11 @@ 2016-05-18 NIIBE Yutaka <gniibe@fsij.org> + * eventflag.c: Update using chopstx_poll. + * chopstx.c (requeue): New. (chopstx_mutex_lock, chopstx_join): Fix by requeue. + (chopstx_main_init): Remove. + (chopstx_setpriority): New. * example-cdc/usb-cdc.c: Prepare for multiple TTYs. @@ -245,7 +249,7 @@ comply AAPCS (ARM Architecture Procedure Call Standard). (chx_init): Initialize W. - * example-cdc/{usb_stm32f103.c,usb_lld.h}: Update from Gnuk. + * example-cdc/usb_stm32f103.c, usb_lld.h: Update from Gnuk. * example-cdc/usb-cdc.c: Update. 2015-11-05 Niibe Yutaka <gniibe@fsij.org> @@ -263,7 +267,7 @@ * chopstx.c (q_exit): Remove. (chx_init, chx_exit): Remove access to Q_EXIT. - (chx_release_irq_thread): Fix removing form the list. + (chx_release_irq_thread): Fix removing from the list. 2015-09-11 Niibe Yutaka <gniibe@fsij.org> @@ -3,16 +3,32 @@ NEWS - Noteworthy changes * Major changes in Chopstx 0.11 - Released 2016-0X-XX + Released 2016-05-19 ** New feature: polling New function chopstx_poll is added to watch multiple condition variables, threads' exit, or IRQ, simultaneously with timeout. -** Remove the function chopstx_release_irq -IRQ is enabled only a thread is blocked in polling. When it (the +** Change API of eventflag + +The initialization function eventflag_init only has EV. The eventflag +is can be waited with timeout or can be waited with no timeout, +dynamically. It is not determined at initialization time. Besides, +the eventflag can be waited by any threads. + + +** Removal of the function chopstx_release_irq +IRQ is enabled only when a thread is blocked in polling. When it (the thread in polling) is canceled, IRQ is disabled. +** Removal of the function chopstx_main_init +Removed because it's too special. Please use chopstx_setpriority +instead. + +** New function: chopstx_setpriority +This function is not recommended in general. It is only added to +offer the purpose of chopstx_main_init. + ** Function chopstx_intr_wait is deprecated Use of chopstx_poll is recommended. @@ -28,6 +44,9 @@ doesn't have complex exception mechism of ICI/IT (which is supported on Cortex-M3), it is actually possible to implement the context switch in user mode. This is done. +** New sys.c (3.0) +Don't touch NVIC in usb_lld_sys_init. + * Major changes in Chopstx 0.10 @@ -333,6 +333,11 @@ struct chx_thread { /* inherits PQ */ struct chx_cleanup *clp; }; +struct chx_poll_head { + uint16_t type; + uint16_t ready; +}; + static void chx_cpu_sched_lock (void) @@ -692,27 +697,6 @@ chx_init (struct chx_thread *tp) } -/** - * chopstx_main_init - initialize main thread - * @prio: priority - * - * Initialize main thread with @prio. - * The thread main is created with priority CHX_PRIO_MAIN_INIT, - * and it runs with that priority until this routine will is called. - */ -void -chopstx_main_init (chopstx_prio_t prio) -{ - struct chx_thread *tp = (struct chx_thread *)chopstx_main; - - tp->prio_orig = prio; - - if (prio >= CHOPSTX_PRIO_INHIBIT_PREEMPTION) - chx_cpu_sched_lock (); - - tp->prio = prio; -} - static void chx_request_preemption (uint16_t prio) @@ -1137,6 +1121,8 @@ chx_snooze (uint32_t state, uint32_t *usec_p) * * Sleep for micro seconds, specified by @var. * Another thread can clear @var to stop the caller going into sleep. + * + * This function is DEPRECATED. Please use chopstx_poll. */ void chopstx_usec_wait_var (uint32_t *var) @@ -1524,13 +1510,13 @@ chopstx_cleanup_pop (int execute) /** - * chopstx_exit - Terminate the execution of thread + * chopstx_exit - Terminate the execution of running thread * @retval: Return value (to be caught by a joining thread) * - * Calling this function terminates the execution of thread, after - * calling clean up functions. If the calling thread still holds - * mutexes, they will be released. If the calling thread claiming - * IRQ, it will be released, too. This function never returns. + * Calling this function terminates the execution of running thread, + * after calling clean up functions. If the calling thread still + * holds mutexes, they will be released. This function never + * returns. */ void chopstx_exit (void *retval) @@ -1667,6 +1653,9 @@ chx_join_hook (struct chx_px *px, struct chx_poll_head *pd) * * Canceling the timer, wake up the sleeping thread. * No return value. + * + * This function is DEPRECATED. Please use chopstx_cond_signal, + * where sleeping process calls chopstx_poll. */ void chopstx_wakeup_usec_wait (chopstx_t thd) @@ -1909,6 +1898,30 @@ chopstx_poll (uint32_t *usec_p, int n, ...) return counter; } + + +/** + * chopstx_setpriority - change the schedule priority of running thread + * @prio: priority + * + * Change the schedule priority with @prio. + * + * In general, it is not recommended to use this function because + * dynamically changing schedule priorities complicates the system. + * Only a possible valid usage of this function is in the main thread + * which starts its execution with priority of CHX_PRIO_MAIN_INIT, and + * let it change its priority after initialization of other threads. + */ +void +chopstx_setpriority (chopstx_prio_t prio) +{ + struct chx_thread *tp = running; + + tp->prio_orig = prio; + if (prio >= CHOPSTX_PRIO_INHIBIT_PREEMPTION) + chx_cpu_sched_lock (); + tp->prio = prio; +} /* * Lower layer architecture specific exception handling entries. @@ -35,7 +35,6 @@ typedef uint8_t chopstx_prio_t; extern chopstx_t chopstx_main; -void chopstx_main_init (chopstx_prio_t); /* NOTE: This signature is different to PTHREAD's one. */ chopstx_t @@ -48,8 +47,6 @@ chopstx_create (uint32_t flags_and_prio, #define CHOPSTX_PRIO_INHIBIT_PREEMPTION 248 -void chopstx_usec_wait_var (uint32_t *arg); - void chopstx_usec_wait (uint32_t usec); struct chx_spinlock { @@ -117,7 +114,10 @@ void chopstx_cleanup_push (chopstx_cleanup_t *clp); void chopstx_cleanup_pop (int execute); -void chopstx_wakeup_usec_wait (chopstx_t thd); +void chopstx_setpriority (chopstx_prio_t); + +void chopstx_usec_wait_var (uint32_t *arg); /* DEPRECATED */ +void chopstx_wakeup_usec_wait (chopstx_t thd); /* DEPRECATED */ enum { CHOPSTX_POLL_COND = 0, @@ -157,11 +157,6 @@ void chopstx_claim_irq (chopstx_intr_t *intr, uint8_t irq_num); void chopstx_intr_wait (chopstx_intr_t *intr); /* DEPRECATED */ -struct chx_poll_head { - uint16_t type; - uint16_t ready; -}; - int chopstx_poll (uint32_t *usec_p, int n, ...); #define CHOPSTX_THREAD_SIZE 64 diff --git a/doc/chopstx-api.texi b/doc/chopstx-api.texi index 7c5f5a2..17b2de8 100644 --- a/doc/chopstx-api.texi +++ b/doc/chopstx-api.texi @@ -7,16 +7,6 @@ When it detects a coding error, this function will be called to stop further execution of code. It never returns. @end deftypefun -@subheading chopstx_main_init -@anchor{chopstx_main_init} -@deftypefun {void} {chopstx_main_init} (chopstx_prio_t @var{prio}) -@var{prio}: priority - -Initialize main thread with @var{prio}. -The thread main is created with priority CHX_PRIO_MAIN_INIT, -and it runs with that priority until this routine will is called. -@end deftypefun - @subheading chopstx_create @anchor{chopstx_create} @deftypefun {chopstx_t} {chopstx_create} (uint32_t @var{flags_and_prio}, uint32_t @var{stack_addr}, size_t @var{stack_size}, voidfunc @var{thread_entry}, void * @var{arg}) @@ -40,6 +30,8 @@ Create a thread. Returns thread ID. Sleep for micro seconds, specified by @var{var}. Another thread can clear @var{var} to stop the caller going into sleep. + +This function is DEPRECATED. Please use chopstx_poll. @end deftypefun @subheading chopstx_usec_wait @@ -150,10 +142,10 @@ clean-up will be executed. @deftypefun {void} {chopstx_exit} (void * @var{retval}) @var{retval}: Return value (to be caught by a joining thread) -Calling this function terminates the execution of thread, after -calling clean up functions. If the calling thread still holds -mutexes, they will be released. If the calling thread claiming -IRQ, it will be released, too. This function never returns. +Calling this function terminates the execution of running thread, +after calling clean up functions. If the calling thread still +holds mutexes, they will be released. This function never +returns. @end deftypefun @subheading chopstx_join @@ -174,6 +166,9 @@ Returns 0 on success, 1 when waiting is interrupted. Canceling the timer, wake up the sleeping thread. No return value. + +This function is DEPRECATED. Please use chopstx_cond_signal, +where sleeping process calls chopstx_poll. @end deftypefun @subheading chopstx_cancel @@ -214,3 +209,17 @@ Returns old state which is 0 when it was enabled. Returns number of active descriptors. @end deftypefun +@subheading chopstx_setpriority +@anchor{chopstx_setpriority} +@deftypefun {void} {chopstx_setpriority} (chopstx_prio_t @var{prio}) +@var{prio}: priority + +Change the schedule priority with @var{prio}. + +In general, it is not recommended to use this function because +dynamically changing schedule priorities complicates the system. +Only a possible valid usage of this function is in the main thread +which starts its execution with priority of CHX_PRIO_MAIN_INIT, and +let it change its priority after initialization of other threads. +@end deftypefun + diff --git a/eventflag.c b/eventflag.c index 27714a1..c30d40c 100644 --- a/eventflag.c +++ b/eventflag.c @@ -1,7 +1,7 @@ /* - * eventflag.c - Eventflag with/without timeout + * eventflag.c - Eventflag * - * Copyright (C) 2013 Flying Stone Technology + * Copyright (C) 2013, 2016 Flying Stone Technology * Author: NIIBE Yutaka <gniibe@fsij.org> * * This file is a part of Chopstx, a thread library for embedded. @@ -31,23 +31,12 @@ #include <chopstx.h> #include <eventflag.h> -enum { - EVENTFLAG_ERR_WAIT = CHOPSTX_ERR_JOIN + 1, - EVENTFLAG_ERR_TIMED_WAIT, -}; - void -eventflag_init (struct eventflag *ev, chopstx_t sleeper) +eventflag_init (struct eventflag *ev) { - ev->sleeper = sleeper; - - if (sleeper) - ev->u.wait_usec = 0; - else - chopstx_cond_init (&ev->u.cond); - - ev->flag = 0; + ev->flags = 0; + chopstx_cond_init (&ev->cond); chopstx_mutex_init (&ev->mutex); } @@ -57,48 +46,52 @@ eventflag_wait (struct eventflag *ev) { int n; - if (ev->sleeper) - chx_fatal (EVENTFLAG_ERR_WAIT); - chopstx_mutex_lock (&ev->mutex); - if (!ev->flag) + if (!ev->flags) chopstx_cond_wait (&ev->u.cond, &ev->mutex); - n = __builtin_ffs (ev->flag); - ev->flag &= ~(1 << (n - 1)); + n = __builtin_ffs (ev->flags); + ev->flags &= ~(1 << (n - 1)); chopstx_mutex_unlock (&ev->mutex); return (1 << (n - 1)); } + +static int +eventflag_check (void *arg) +{ + struct eventflag *ev = arg; + + return ev->flags != 0; +} + + eventmask_t eventflag_wait_timeout (struct eventflag *ev, uint32_t usec) { - eventmask_t em = 0; + chopstx_poll_cond_t poll_desc; int n; + eventmask_t em = 0; - if (ev->sleeper == 0) - chx_fatal (EVENTFLAG_ERR_TIMED_WAIT); - - chopstx_mutex_lock (&ev->mutex); + poll_desc.type = CHOPSTX_POLL_COND; + poll_desc.ready = 0; + poll_desc.cond = &ev->cond; + poll_desc.mutex = &ev->mutex; + poll_desc.check = eventflag_check; + poll_desc.arg = ev; - if (!ev->flag) - { - ev->u.wait_usec = usec; - chopstx_mutex_unlock (&ev->mutex); - chopstx_usec_wait_var (&ev->u.wait_usec); - chopstx_mutex_lock (&ev->mutex); - ev->u.wait_usec = 0; - } + chopstx_poll (&usec, 1, &poll_desc); - n = __builtin_ffs (ev->flag); + chopstx_mutex_lock (&ev->mutex); + n = __builtin_ffs (ev->flags); if (n) { em = (1 << (n - 1)); - ev->flag &= ~em; + ev->flags &= ~em; } - chopstx_mutex_unlock (&ev->mutex); + return em; } @@ -108,15 +101,6 @@ eventflag_signal (struct eventflag *ev, eventmask_t m) { chopstx_mutex_lock (&ev->mutex); ev->flag |= m; - if (ev->sleeper) - { - if (ev->u.wait_usec) - { - ev->u.wait_usec = 0; - chopstx_wakeup_usec_wait (ev->sleeper); - } - } - else - chopstx_cond_signal (&ev->u.cond); + chopstx_cond_signal (&ev->u.cond); chopstx_mutex_unlock (&ev->mutex); } diff --git a/eventflag.h b/eventflag.h index b218ac1..d1b9392 100644 --- a/eventflag.h +++ b/eventflag.h @@ -1,16 +1,12 @@ typedef uint32_t eventmask_t; struct eventflag { - chopstx_t sleeper; - eventmask_t flag; + eventmask_t flags; chopstx_mutex_t mutex; - union { - uint32_t wait_usec; - chopstx_cond_t cond; - } u; + chopstx_cond_t cond; }; -void eventflag_init (struct eventflag *ev, chopstx_t owner); +void eventflag_init (struct eventflag *ev); eventmask_t eventflag_wait (struct eventflag *ev); eventmask_t eventflag_wait_timeout (struct eventflag *ev, uint32_t usec); void eventflag_signal (struct eventflag *ev, eventmask_t m); |