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. */
/*===========================================================================*/
/**
* @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.
* @details If enabled then the @p chThdWait() function is included in

View File

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

View File

@ -64,19 +64,27 @@
* @extends ThreadsQueue
*/
typedef struct {
ThreadsQueue r_queue; /**< Threads queue.*/
ThreadsQueue r_queue; /**< Threads queue. */
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.*/
#if CH_TIME_QUANTUM > 0
cnt_t r_preempt; /**< Round robin counter.*/
cnt_t r_preempt; /**< Round robin counter. */
#endif
#ifndef CH_CURRP_REGISTER_CACHE
Thread *r_current; /**< The currently running thread.*/
Thread *r_current; /**< The currently running thread. */
#endif
} ReadyList;
#if !defined(__DOXYGEN__)
extern ReadyList rlist;
#endif
#ifdef CH_CURRP_REGISTER_CACHE
register Thread *currp asm(CH_CURRP_REGISTER_CACHE);

View File

@ -53,13 +53,17 @@ struct Thread {
queue. */
/* End of the fields shared with the ThreadsQueue structure. */
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. */
#if CH_USE_DYNAMIC
trefs_t p_refs; /**< References to this thread. */
#endif
tstate_t p_state; /**< Current thread state. */
tmode_t p_flags; /**< Various thread flags. */
struct context p_ctx; /**< Processor context. */
#if CH_USE_NESTED_LOCKS
cnt_t p_locks; /**< Number of nested locks. */
#endif
@ -181,13 +185,19 @@ extern "C" {
}
#endif
/** Returns the pointer to the @p Thread currently in execution.*/
/**
* Returns a pointer to the current @p Thread.
*/
#define chThdSelf() currp
/** Returns the current thread priority.*/
/**
* Returns the current thread priority.
*/
#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)
/**

View File

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

View File

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

View File

@ -27,13 +27,21 @@
#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) {
tp->p_flags = THD_MEM_MODE_STATIC;
tp->p_prio = prio;
tp->p_state = THD_STATE_SUSPENDED;
#if CH_USE_REGISTRY
REG_INSERT(tp);
#endif
#if CH_USE_DYNAMIC
tp->p_refs = 1;
#endif
@ -69,22 +77,23 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
#endif
/**
* @brief Initializes a new thread.
* @brief Initializes a new thread.
* @details The new thread is initialized but not inserted in the ready list,
* 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[in] size size of the working area
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area.
* @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[in] size size of the working area
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be
* @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area.
*/
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 */
@ -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
* stack
* @param[in] size size of the working area
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space 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 stack
* @param[in] size size of the working area
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be
* @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area.
*/
Thread *chThdCreateStatic(void *wsp, size_t size,
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
/**
* @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
* @param[in] size size of the working area to be allocated
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area.
* @retval NULL if the memory cannot be allocated.
* @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] size size of the working area to be allocated
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be
* @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area.
* @retval NULL if the memory cannot be allocated.
*/
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
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
/**
* @brief Creates a new thread allocating the memory from the specified Memory
* Pool.
* @brief Creates a new thread allocating the memory from the specified
* 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] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area or @p NULL if the memory cannot
* be allocated.
* @retval NULL if the memory pool is empty.
* @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 pointer to the memory pool object
* @param[in] prio the priority level for the new thread
* @param[in] pf the thread function
* @param[in] arg an argument passed to the thread function. It can be
* @p NULL.
* @return The pointer to the @p Thread structure allocated for the
* thread into the working space area or @p NULL if the memory cannot
* be allocated.
* @retval NULL if the memory pool is empty.
*/
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tfunc_t pf, void *arg) {
@ -196,14 +207,14 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */
/**
* @brief Changes the running thread priority level then reschedules if
* necessary.
* @brief Changes the running thread priority level then reschedules if
* 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
* @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.
* @return The old priority level.
*/
tprio_t chThdSetPriority(tprio_t newprio) {
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
* @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().
* @param[in] tp pointer to the thread
* @return The pointer to the thread.
*/
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
* @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.
* @param[in] tp pointer to the thread
*/
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
* follow:
* - @a TIME_INFINITE the thread enters an infinite sleep
* state.
* - @a TIME_IMMEDIATE this value is accepted but interpreted
* as a normal time specification not as an immediate timeout
* specification.
* .
* @param[in] time the delay in system ticks, the special values are handled
* as follow:
* - @a TIME_INFINITE the thread enters an infinite sleep
* state.
* - @a TIME_IMMEDIATE this value is accepted but interpreted
* as a normal time specification not as an immediate
* timeout specification.
* .
*/
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
* specified value.
* @brief Suspends the invoking thread until the system time arrives to the
* specified value.
*
* @param[in] time the absolute system time
* @param[in] time absolute system 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
* 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
* @p chThdWait().
* @return The same thread pointer passed as parameter.
* @param[in] msg thread exit code. The code can be retrieved by using
* @p chThdWait().
* @return The same thread pointer passed as parameter.
*/
void chThdExit(msg_t msg) {
Thread *tp = currp;
@ -323,11 +333,20 @@ void chThdExit(msg_t msg) {
#if CH_USE_WAITEXIT
while (notempty(&tp->p_waiting))
chSchReadyI(list_remove(&tp->p_waiting));
#endif
#if CH_USE_REGISTRY
REG_REMOVE(tp);
#endif
chSchGoSleepS(THD_STATE_FINAL);
}
#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) {
chSysLock();
@ -343,8 +362,8 @@ Thread *chThdAddRef(Thread *tp) {
* to the proper allocator.
* @note Static threads are not affected.
*
* @param[in] tp the thread pointer
* @return The same thread pointer passed as parameter.
* @param[in] tp pointer to the thread
* @return The same thread pointer passed as parameter.
*/
Thread *chThdRelease(Thread *tp) {
trefs_t refs;
@ -393,14 +412,15 @@ Thread *chThdRelease(Thread *tp) {
* then the working area is returned to the owning memory pool.
* .
* Please read the @ref article_lifecycle article for more details.
* @param[in] tp the thread pointer
* @return The exit code from the terminated thread
* @note After invoking @p chThdWait() the thread pointer becomes invalid and
* must not be used as parameter for further system calls.
* @note The function is available only if the @p CH_USE_WAITEXIT
* option is enabled in @p chconf.h.
* @note If @p CH_USE_DYNAMIC is not specified this function just waits for
* the thread termination, no memory allocators are involved.
* @note After invoking @p chThdWait() the thread pointer becomes invalid
* and must not be used as parameter for further system calls.
* @note The function is available only if the @p CH_USE_WAITEXIT
* option is enabled in @p chconf.h.
* @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 msg;

View File

@ -125,6 +125,16 @@
/* 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.
* @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" \
"mrs r12, PSP \n\t" \
"stmdb r12!, {r3-r6,r8-r11, lr} \n\t" \
"str r12, [r0, #16] \n\t" \
"ldr r12, [r1, #16] \n\t" \
"str r12, [r0, #12] \n\t" \
"ldr r12, [r1, #12] \n\t" \
"ldmia r12!, {r3-r6,r8-r11, lr} \n\t" \
"msr PSP, r12 \n\t" \
"msr BASEPRI, r3 \n\t" \
@ -97,8 +97,8 @@ void SVCallVector(Thread *otp, Thread *ntp) {
asm volatile ("mrs r3, BASEPRI \n\t" \
"mrs r12, PSP \n\t" \
"stmdb r12!, {r3-r11, lr} \n\t" \
"str r12, [r0, #16] \n\t" \
"ldr r12, [r1, #16] \n\t" \
"str r12, [r0, #12] \n\t" \
"ldr r12, [r1, #12] \n\t" \
"ldmia r12!, {r3-r11, lr} \n\t" \
"msr PSP, r12 \n\t" \
"msr BASEPRI, r3 \n\t" \

View File

@ -52,14 +52,17 @@
*****************************************************************************
*** 1.5.1 ***
- FIX: Fixed wrong notes on function chThdResume() (bug 2943160).
- NEW: Implemented the concept of thread references, this mechanism ensures
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
mechanism. Two new APIs have been added: chThdAddRef() and chThdRelease().
- NEW: Not more than one thread can be waiting in chThdWait(), this
capability was already present in beta versions before 0.8.0 but removed
because at the time there was not the references mechanism in place.
- NEW: Not more than one thread can be waiting in chThdWait() as long they
own a reference.
- 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 ***
- FIX: Fixed missing dependencies check for CH_USE_DYNAMIC (bug 2942757)
(backported in 1.4.1).