diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-02-02 20:20:12 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-02-02 20:20:12 +0000 |
commit | e515bcf581c92643c21eb6ed53ba0d0b1604fe4b (patch) | |
tree | efae1098d4db1532fcf51f1387add77747ffc061 | |
parent | ce91c3f44a3f0b9cacd07972a052c7360fb24053 (diff) | |
download | ChibiOS-e515bcf581c92643c21eb6ed53ba0d0b1604fe4b.tar.gz ChibiOS-e515bcf581c92643c21eb6ed53ba0d0b1604fe4b.tar.bz2 ChibiOS-e515bcf581c92643c21eb6ed53ba0d0b1604fe4b.zip |
Implemented registry subsystem (still in progress).
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1558 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r-- | demos/ARMCM3-STM32F103-GCC/chconf.h | 10 | ||||
-rw-r--r-- | os/kernel/include/ch.h | 1 | ||||
-rw-r--r-- | os/kernel/include/scheduler.h | 16 | ||||
-rw-r--r-- | os/kernel/include/threads.h | 18 | ||||
-rw-r--r-- | os/kernel/kernel.mk | 1 | ||||
-rw-r--r-- | os/kernel/src/chschd.c | 8 | ||||
-rw-r--r-- | os/kernel/src/chthreads.c | 222 | ||||
-rw-r--r-- | os/kernel/templates/chconf.h | 10 | ||||
-rw-r--r-- | os/ports/GCC/ARMCM3/chcore.c | 8 | ||||
-rw-r--r-- | readme.txt | 11 |
10 files changed, 186 insertions, 119 deletions
diff --git a/demos/ARMCM3-STM32F103-GCC/chconf.h b/demos/ARMCM3-STM32F103-GCC/chconf.h index 3b29983cb..d0d7e7d41 100644 --- a/demos/ARMCM3-STM32F103-GCC/chconf.h +++ b/demos/ARMCM3-STM32F103-GCC/chconf.h @@ -124,6 +124,16 @@ /*===========================================================================*/
/**
+ * @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
* the kernel.
diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index 683c69cc6..109040262 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -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"
diff --git a/os/kernel/include/scheduler.h b/os/kernel/include/scheduler.h index 539c678fa..9d8af9ecc 100644 --- a/os/kernel/include/scheduler.h +++ b/os/kernel/include/scheduler.h @@ -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); diff --git a/os/kernel/include/threads.h b/os/kernel/include/threads.h index a9209e6ea..24b79a3cd 100644 --- a/os/kernel/include/threads.h +++ b/os/kernel/include/threads.h @@ -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) /** diff --git a/os/kernel/kernel.mk b/os/kernel/kernel.mk index 47c8bb1d4..b97b0e5dc 100644 --- a/os/kernel/kernel.mk +++ b/os/kernel/kernel.mk @@ -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 \
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index f7be9c6a8..5b4d18133 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -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 } /** diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 26183706a..95b1e68bf 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -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; @@ -324,10 +334,19 @@ void chThdExit(msg_t msg) { 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; diff --git a/os/kernel/templates/chconf.h b/os/kernel/templates/chconf.h index 7fc7ea82b..4cb12bd74 100644 --- a/os/kernel/templates/chconf.h +++ b/os/kernel/templates/chconf.h @@ -126,6 +126,16 @@ /*===========================================================================*/
/**
+ * @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
* the kernel.
diff --git a/os/ports/GCC/ARMCM3/chcore.c b/os/ports/GCC/ARMCM3/chcore.c index 80354f863..bcd726a7b 100644 --- a/os/ports/GCC/ARMCM3/chcore.c +++ b/os/ports/GCC/ARMCM3/chcore.c @@ -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" \
diff --git a/readme.txt b/readme.txt index d97427fa0..724a57f20 100644 --- a/readme.txt +++ b/readme.txt @@ -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).
|