eventflag rewrite
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
25
NEWS
25
NEWS
@@ -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
|
||||
|
||||
|
||||
65
chopstx.c
65
chopstx.c
@@ -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.
|
||||
|
||||
13
chopstx.h
13
chopstx.h
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
80
eventflag.c
80
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);
|
||||
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;
|
||||
|
||||
chopstx_poll (&usec, 1, &poll_desc);
|
||||
|
||||
chopstx_mutex_lock (&ev->mutex);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
n = __builtin_ffs (ev->flag);
|
||||
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);
|
||||
}
|
||||
|
||||
10
eventflag.h
10
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);
|
||||
|
||||
Reference in New Issue
Block a user