Implemented registry subsystem (still in progress).

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1558 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2010-02-02 20:20:12 +00:00
parent ce91c3f44a
commit e515bcf581
10 changed files with 186 additions and 119 deletions

View File

@ -123,6 +123,16 @@
/* Subsystem options. */ /* Subsystem options. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
#define CH_USE_REGISTRY TRUE
#endif
/** /**
* @brief Threads synchronization APIs. * @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in * @details If enabled then the @p chThdWait() function is included in

View File

@ -79,6 +79,7 @@
#include "heap.h" #include "heap.h"
#include "mempools.h" #include "mempools.h"
#include "threads.h" #include "threads.h"
#include "registry.h"
#include "inline.h" #include "inline.h"
#include "queues.h" #include "queues.h"
#include "streams.h" #include "streams.h"

View File

@ -64,19 +64,27 @@
* @extends ThreadsQueue * @extends ThreadsQueue
*/ */
typedef struct { typedef struct {
ThreadsQueue r_queue; /**< Threads queue.*/ ThreadsQueue r_queue; /**< Threads queue. */
tprio_t r_prio; /**< This field must be initialized to tprio_t r_prio; /**< This field must be initialized to
zero.*/ zero. */
struct context p_ctx; /**< Not used, present because
offsets. */
#if CH_USE_REGISTRY
Thread *p_newer; /**< Newer registry element. */
Thread *p_older; /**< Older registry element. */
#endif
/* End of the fields shared with the Thread structure.*/ /* End of the fields shared with the Thread structure.*/
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
cnt_t r_preempt; /**< Round robin counter.*/ cnt_t r_preempt; /**< Round robin counter. */
#endif #endif
#ifndef CH_CURRP_REGISTER_CACHE #ifndef CH_CURRP_REGISTER_CACHE
Thread *r_current; /**< The currently running thread.*/ Thread *r_current; /**< The currently running thread. */
#endif #endif
} ReadyList; } ReadyList;
#if !defined(__DOXYGEN__)
extern ReadyList rlist; extern ReadyList rlist;
#endif
#ifdef CH_CURRP_REGISTER_CACHE #ifdef CH_CURRP_REGISTER_CACHE
register Thread *currp asm(CH_CURRP_REGISTER_CACHE); register Thread *currp asm(CH_CURRP_REGISTER_CACHE);

View File

@ -53,13 +53,17 @@ struct Thread {
queue. */ queue. */
/* End of the fields shared with the ThreadsQueue structure. */ /* End of the fields shared with the ThreadsQueue structure. */
tprio_t p_prio; /**< Thread priority. */ tprio_t p_prio; /**< Thread priority. */
struct context p_ctx; /**< Processor context. */
#if CH_USE_REGISTRY
Thread *p_newer; /**< Newer registry element. */
Thread *p_older; /**< Older registry element. */
#endif
/* End of the fields shared with the ReadyList structure. */ /* End of the fields shared with the ReadyList structure. */
#if CH_USE_DYNAMIC #if CH_USE_DYNAMIC
trefs_t p_refs; /**< References to this thread. */ trefs_t p_refs; /**< References to this thread. */
#endif #endif
tstate_t p_state; /**< Current thread state. */ tstate_t p_state; /**< Current thread state. */
tmode_t p_flags; /**< Various thread flags. */ tmode_t p_flags; /**< Various thread flags. */
struct context p_ctx; /**< Processor context. */
#if CH_USE_NESTED_LOCKS #if CH_USE_NESTED_LOCKS
cnt_t p_locks; /**< Number of nested locks. */ cnt_t p_locks; /**< Number of nested locks. */
#endif #endif
@ -181,13 +185,19 @@ extern "C" {
} }
#endif #endif
/** Returns the pointer to the @p Thread currently in execution.*/ /**
* Returns a pointer to the current @p Thread.
*/
#define chThdSelf() currp #define chThdSelf() currp
/** Returns the current thread priority.*/ /**
* Returns the current thread priority.
*/
#define chThdGetPriority() (currp->p_prio) #define chThdGetPriority() (currp->p_prio)
/** Returns the pointer to the @p Thread local storage area, if any.*/ /**
* Returns the pointer to the @p Thread local storage area, if any.
*/
#define chThdLS() (void *)(currp + 1) #define chThdLS() (void *)(currp + 1)
/** /**

View File

@ -6,6 +6,7 @@ KERNSRC = ${CHIBIOS}/os/kernel/src/chsys.c \
${CHIBIOS}/os/kernel/src/chvt.c \ ${CHIBIOS}/os/kernel/src/chvt.c \
${CHIBIOS}/os/kernel/src/chschd.c \ ${CHIBIOS}/os/kernel/src/chschd.c \
${CHIBIOS}/os/kernel/src/chthreads.c \ ${CHIBIOS}/os/kernel/src/chthreads.c \
${CHIBIOS}/os/kernel/src/chregistry.c \
${CHIBIOS}/os/kernel/src/chsem.c \ ${CHIBIOS}/os/kernel/src/chsem.c \
${CHIBIOS}/os/kernel/src/chmtx.c \ ${CHIBIOS}/os/kernel/src/chmtx.c \
${CHIBIOS}/os/kernel/src/chcond.c \ ${CHIBIOS}/os/kernel/src/chcond.c \

View File

@ -26,9 +26,10 @@
#include "ch.h" #include "ch.h"
/** @cond never */ /**
* @brief Ready list header.
*/
ReadyList rlist; ReadyList rlist;
/** @endcond */
/** /**
* @brief Scheduler initialization. * @brief Scheduler initialization.
@ -42,6 +43,9 @@ void scheduler_init(void) {
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM; rlist.r_preempt = CH_TIME_QUANTUM;
#endif #endif
#if CH_USE_REGISTRY
rlist.p_newer = rlist.p_older = (Thread *)&rlist;
#endif
} }
/** /**

View File

@ -27,13 +27,21 @@
#include "ch.h" #include "ch.h"
/** /**
* @brief Initializes a thread structure. * @brief Initializes a thread structure.
*
* @param[in] tp pointer to the thread
* @param[in] prio the priority level for the new thread
*
* @return The same thread pointer passed as parameter.
*/ */
Thread *init_thread(Thread *tp, tprio_t prio) { Thread *init_thread(Thread *tp, tprio_t prio) {
tp->p_flags = THD_MEM_MODE_STATIC; tp->p_flags = THD_MEM_MODE_STATIC;
tp->p_prio = prio; tp->p_prio = prio;
tp->p_state = THD_STATE_SUSPENDED; tp->p_state = THD_STATE_SUSPENDED;
#if CH_USE_REGISTRY
REG_INSERT(tp);
#endif
#if CH_USE_DYNAMIC #if CH_USE_DYNAMIC
tp->p_refs = 1; tp->p_refs = 1;
#endif #endif
@ -69,22 +77,23 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
#endif #endif
/** /**
* @brief Initializes a new thread. * @brief Initializes a new thread.
* @details The new thread is initialized but not inserted in the ready list, * @details The new thread is initialized but not inserted in the ready list,
* the initial state is @p THD_STATE_SUSPENDED. * the initial state is @p THD_STATE_SUSPENDED.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note This function can be invoked from within an interrupt handler
* even if it is not an I-Class API because it does not touch
* any critical kernel data structure.
* *
* @param[out] wsp pointer to a working area dedicated to the thread stack * @param[out] wsp pointer to a working area dedicated to the thread stack
* @param[in] size size of the working area * @param[in] size size of the working area
* @param[in] prio the priority level for the new thread * @param[in] prio the priority level for the new thread
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL. * @param[in] arg an argument passed to the thread function. It can be
* @return The pointer to the @p Thread structure allocated for the * @p NULL.
* thread into the working space area. * @return The pointer to the @p Thread structure allocated for the
* @note A thread can terminate by calling @p chThdExit() or by simply * thread into the working space area.
* returning from its main function.
* @note This function can be invoked from within an interrupt handler even if
* it is not an I-Class API because it does not touch any critical kernel
* data structure.
*/ */
Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
/* Thread structure is layed out in the lower part of the thread workspace */ /* Thread structure is layed out in the lower part of the thread workspace */
@ -103,18 +112,18 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
} }
/** /**
* @brief Creates a new thread into a static memory area. * @brief Creates a new thread into a static memory area.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* *
* @param[out] wsp pointer to a working area dedicated to the thread * @param[out] wsp pointer to a working area dedicated to the thread stack
* stack * @param[in] size size of the working area
* @param[in] size size of the working area * @param[in] prio the priority level for the new thread
* @param[in] prio the priority level for the new thread * @param[in] pf the thread function
* @param[in] pf the thread function * @param[in] arg an argument passed to the thread function. It can be
* @param[in] arg an argument passed to the thread function. It can be @p NULL. * @p NULL.
* @return The pointer to the @p Thread structure allocated for the * @return The pointer to the @p Thread structure allocated for the
* thread into the working space area. * thread into the working space area.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
*/ */
Thread *chThdCreateStatic(void *wsp, size_t size, Thread *chThdCreateStatic(void *wsp, size_t size,
tprio_t prio, tfunc_t pf, void *arg) { tprio_t prio, tfunc_t pf, void *arg) {
@ -124,24 +133,25 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
#if CH_USE_DYNAMIC && CH_USE_HEAP #if CH_USE_DYNAMIC && CH_USE_HEAP
/** /**
* @brief Creates a new thread allocating the memory from the heap. * @brief Creates a new thread allocating the memory from the heap.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
* *
* @param[in] heapp heap from which allocate the memory or NULL for the * @param[in] heapp heap from which allocate the memory or @p NULL for the
* default heap * default heap
* @param[in] size size of the working area to be allocated * @param[in] size size of the working area to be allocated
* @param[in] prio the priority level for the new thread * @param[in] prio the priority level for the new thread
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL. * @param[in] arg an argument passed to the thread function. It can be
* @return The pointer to the @p Thread structure allocated for the * @p NULL.
* thread into the working space area. * @return The pointer to the @p Thread structure allocated for the
* @retval NULL if the memory cannot be allocated. * thread into the working space area.
* @note A thread can terminate by calling @p chThdExit() or by simply * @retval NULL if the memory cannot be allocated.
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
*/ */
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
tprio_t prio, tfunc_t pf, void *arg) { tprio_t prio, tfunc_t pf, void *arg) {
@ -159,24 +169,25 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
/** /**
* @brief Creates a new thread allocating the memory from the specified Memory * @brief Creates a new thread allocating the memory from the specified
* Pool. * Memory Pool.
* @note A thread can terminate by calling @p chThdExit() or by simply
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
* *
* @param[in] mp the memory pool * @param[in] mp pointer to the memory pool object
* @param[in] prio the priority level for the new thread * @param[in] prio the priority level for the new thread
* @param[in] pf the thread function * @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL. * @param[in] arg an argument passed to the thread function. It can be
* @return The pointer to the @p Thread structure allocated for the * @p NULL.
* thread into the working space area or @p NULL if the memory cannot * @return The pointer to the @p Thread structure allocated for the
* be allocated. * thread into the working space area or @p NULL if the memory cannot
* @retval NULL if the memory pool is empty. * be allocated.
* @note A thread can terminate by calling @p chThdExit() or by simply * @retval NULL if the memory pool is empty.
* returning from its main function.
* @note The memory allocated for the thread is not released when the thread
* terminates but when a @p chThdWait() is performed.
* @note The function is available only if the @p CH_USE_DYNAMIC,
* @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled
* in @p chconf.h.
*/ */
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tfunc_t pf, void *arg) { tfunc_t pf, void *arg) {
@ -196,14 +207,14 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ #endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */
/** /**
* @brief Changes the running thread priority level then reschedules if * @brief Changes the running thread priority level then reschedules if
* necessary. * necessary.
* @note The function returns the real thread priority regardless of the
* current priority that could be higher than the real priority
* because the priority inheritance mechanism.
* *
* @param[in] newprio the new priority level of the running thread * @param[in] newprio the new priority level of the running thread
* @return The old priority level. * @return The old priority level.
* @note The function returns the real thread priority regardless of the
* current priority that could be higher than the real priority because
* the priority inheritance mechanism.
*/ */
tprio_t chThdSetPriority(tprio_t newprio) { tprio_t chThdSetPriority(tprio_t newprio) {
tprio_t oldprio; tprio_t oldprio;
@ -227,12 +238,11 @@ tprio_t chThdSetPriority(tprio_t newprio) {
} }
/** /**
* @brief Resumes a suspended thread. * @brief Resumes a suspended thread.
* @note Use this function to resume threads created with @p chThdInit().
* *
* @param[in] tp the pointer to the thread * @param[in] tp pointer to the thread
* @return The pointer to the thread. * @return The pointer to the thread.
* @note This call is supposed to resume threads created with @p chThdInit().
* It should not be used on threads suspended using @p chThdSuspend().
*/ */
Thread *chThdResume(Thread *tp) { Thread *chThdResume(Thread *tp) {
@ -246,12 +256,12 @@ Thread *chThdResume(Thread *tp) {
} }
/** /**
* @brief Requests a thread termination. * @brief Requests a thread termination.
* @note The thread is not terminated but a termination request is added to
* its @p p_flags field. The thread can read this status by
* invoking @p chThdShouldTerminate() and then terminate cleanly.
* *
* @param[in] tp the pointer to the thread * @param[in] tp pointer to the thread
* @note The thread is not termitated but a termination request is added to
* its @p p_flags field. The thread can read this status by
* invoking @p chThdShouldTerminate() and then terminate cleanly.
*/ */
void chThdTerminate(Thread *tp) { void chThdTerminate(Thread *tp) {
@ -261,16 +271,16 @@ void chThdTerminate(Thread *tp) {
} }
/** /**
* @brief Suspends the invoking thread for the specified time. * @brief Suspends the invoking thread for the specified time.
* *
* @param[in] time the delay in system ticks, the special values are handled as * @param[in] time the delay in system ticks, the special values are handled
* follow: * as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep * - @a TIME_INFINITE the thread enters an infinite sleep
* state. * state.
* - @a TIME_IMMEDIATE this value is accepted but interpreted * - @a TIME_IMMEDIATE this value is accepted but interpreted
* as a normal time specification not as an immediate timeout * as a normal time specification not as an immediate
* specification. * timeout specification.
* . * .
*/ */
void chThdSleep(systime_t time) { void chThdSleep(systime_t time) {
@ -282,10 +292,10 @@ void chThdSleep(systime_t time) {
} }
/** /**
* @brief Suspends the invoking thread until the system time arrives to the * @brief Suspends the invoking thread until the system time arrives to the
* specified value. * specified value.
* *
* @param[in] time the absolute system time * @param[in] time absolute system time
*/ */
void chThdSleepUntil(systime_t time) { void chThdSleepUntil(systime_t time) {
@ -296,7 +306,7 @@ void chThdSleepUntil(systime_t time) {
} }
/** /**
* @brief Yields the time slot. * @brief Yields the time slot.
* @details Yields the CPU control to the next thread in the ready list with * @details Yields the CPU control to the next thread in the ready list with
* equal priority, if any. * equal priority, if any.
*/ */
@ -308,11 +318,11 @@ void chThdYield(void) {
} }
/** /**
* @brief Terminates the current thread by specifying an exit status code. * @brief Terminates the current thread by specifying an exit status code.
* *
* @param[in] msg the thread exit code. The code can be retrieved by using * @param[in] msg thread exit code. The code can be retrieved by using
* @p chThdWait(). * @p chThdWait().
* @return The same thread pointer passed as parameter. * @return The same thread pointer passed as parameter.
*/ */
void chThdExit(msg_t msg) { void chThdExit(msg_t msg) {
Thread *tp = currp; Thread *tp = currp;
@ -323,11 +333,20 @@ void chThdExit(msg_t msg) {
#if CH_USE_WAITEXIT #if CH_USE_WAITEXIT
while (notempty(&tp->p_waiting)) while (notempty(&tp->p_waiting))
chSchReadyI(list_remove(&tp->p_waiting)); chSchReadyI(list_remove(&tp->p_waiting));
#endif
#if CH_USE_REGISTRY
REG_REMOVE(tp);
#endif #endif
chSchGoSleepS(THD_STATE_FINAL); chSchGoSleepS(THD_STATE_FINAL);
} }
#if CH_USE_DYNAMIC || defined(__DOXYGEN__) #if CH_USE_DYNAMIC || defined(__DOXYGEN__)
/**
* @brief Adds a reference to a thread object.
*
* @param[in] tp pointer to the thread
* @return The same thread pointer passed as parameter.
*/
Thread *chThdAddRef(Thread *tp) { Thread *chThdAddRef(Thread *tp) {
chSysLock(); chSysLock();
@ -343,8 +362,8 @@ Thread *chThdAddRef(Thread *tp) {
* to the proper allocator. * to the proper allocator.
* @note Static threads are not affected. * @note Static threads are not affected.
* *
* @param[in] tp the thread pointer * @param[in] tp pointer to the thread
* @return The same thread pointer passed as parameter. * @return The same thread pointer passed as parameter.
*/ */
Thread *chThdRelease(Thread *tp) { Thread *chThdRelease(Thread *tp) {
trefs_t refs; trefs_t refs;
@ -393,14 +412,15 @@ Thread *chThdRelease(Thread *tp) {
* then the working area is returned to the owning memory pool. * then the working area is returned to the owning memory pool.
* . * .
* Please read the @ref article_lifecycle article for more details. * Please read the @ref article_lifecycle article for more details.
* @param[in] tp the thread pointer * @note After invoking @p chThdWait() the thread pointer becomes invalid
* @return The exit code from the terminated thread * and must not be used as parameter for further system calls.
* @note After invoking @p chThdWait() the thread pointer becomes invalid and * @note The function is available only if the @p CH_USE_WAITEXIT
* must not be used as parameter for further system calls. * option is enabled in @p chconf.h.
* @note The function is available only if the @p CH_USE_WAITEXIT * @note If @p CH_USE_DYNAMIC is not specified this function just waits for
* option is enabled in @p chconf.h. * the thread termination, no memory allocators are involved.
* @note If @p CH_USE_DYNAMIC is not specified this function just waits for *
* the thread termination, no memory allocators are involved. * @param[in] tp pointer to the thread
* @return The exit code from the terminated thread
*/ */
msg_t chThdWait(Thread *tp) { msg_t chThdWait(Thread *tp) {
msg_t msg; msg_t msg;

View File

@ -125,6 +125,16 @@
/* Subsystem options. */ /* Subsystem options. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
#define CH_USE_REGISTRY TRUE
#endif
/** /**
* @brief Threads synchronization APIs. * @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in * @details If enabled then the @p chThdWait() function is included in

View File

@ -87,8 +87,8 @@ void SVCallVector(Thread *otp, Thread *ntp) {
asm volatile ("mrs r3, BASEPRI \n\t" \ asm volatile ("mrs r3, BASEPRI \n\t" \
"mrs r12, PSP \n\t" \ "mrs r12, PSP \n\t" \
"stmdb r12!, {r3-r6,r8-r11, lr} \n\t" \ "stmdb r12!, {r3-r6,r8-r11, lr} \n\t" \
"str r12, [r0, #16] \n\t" \ "str r12, [r0, #12] \n\t" \
"ldr r12, [r1, #16] \n\t" \ "ldr r12, [r1, #12] \n\t" \
"ldmia r12!, {r3-r6,r8-r11, lr} \n\t" \ "ldmia r12!, {r3-r6,r8-r11, lr} \n\t" \
"msr PSP, r12 \n\t" \ "msr PSP, r12 \n\t" \
"msr BASEPRI, r3 \n\t" \ "msr BASEPRI, r3 \n\t" \
@ -97,8 +97,8 @@ void SVCallVector(Thread *otp, Thread *ntp) {
asm volatile ("mrs r3, BASEPRI \n\t" \ asm volatile ("mrs r3, BASEPRI \n\t" \
"mrs r12, PSP \n\t" \ "mrs r12, PSP \n\t" \
"stmdb r12!, {r3-r11, lr} \n\t" \ "stmdb r12!, {r3-r11, lr} \n\t" \
"str r12, [r0, #16] \n\t" \ "str r12, [r0, #12] \n\t" \
"ldr r12, [r1, #16] \n\t" \ "ldr r12, [r1, #12] \n\t" \
"ldmia r12!, {r3-r11, lr} \n\t" \ "ldmia r12!, {r3-r11, lr} \n\t" \
"msr PSP, r12 \n\t" \ "msr PSP, r12 \n\t" \
"msr BASEPRI, r3 \n\t" \ "msr BASEPRI, r3 \n\t" \

View File

@ -52,14 +52,17 @@
***************************************************************************** *****************************************************************************
*** 1.5.1 *** *** 1.5.1 ***
- FIX: Fixed wrong notes on function chThdResume() (bug 2943160).
- NEW: Implemented the concept of thread references, this mechanism ensures - NEW: Implemented the concept of thread references, this mechanism ensures
that a dynamic thread's memory is not freed while some other thread still that a dynamic thread's memory is not freed while some other thread still
owns a pointer to the thread. Static threads are not affected by the new owns a pointer to the thread. Static threads are not affected by the new
mechanism. Two new APIs have been added: chThdAddRef() and chThdRelease(). mechanism. Two new APIs have been added: chThdAddRef() and chThdRelease().
- NEW: Not more than one thread can be waiting in chThdWait(), this - NEW: Not more than one thread can be waiting in chThdWait() as long they
capability was already present in beta versions before 0.8.0 but removed own a reference.
because at the time there was not the references mechanism in place. - NEW: Implemented a new threads registry subsystem, the registry allows to
enumerate the active threads at runtime. The registry is meant as both
a runtime API and a support for debuggers.
*** 1.5.0 *** *** 1.5.0 ***
- FIX: Fixed missing dependencies check for CH_USE_DYNAMIC (bug 2942757) - FIX: Fixed missing dependencies check for CH_USE_DYNAMIC (bug 2942757)
(backported in 1.4.1). (backported in 1.4.1).