From a2072b5560adf07640b43107e00582b31658540d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 24 Feb 2016 11:22:05 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8940 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/common/oslib/include/chdynamic.h | 97 ------------------ os/common/oslib/src/chdynamic.c | 194 ------------------------------------ os/rt/include/chdynamic.h | 97 ++++++++++++++++++ os/rt/include/chschd.h | 107 +++++++++++--------- os/rt/rt.mk | 10 +- os/rt/src/chdynamic.c | 193 +++++++++++++++++++++++++++++++++++ os/rt/src/chregistry.c | 23 ++++- os/rt/src/chsys.c | 1 + os/rt/src/chthreads.c | 1 + 9 files changed, 379 insertions(+), 344 deletions(-) delete mode 100644 os/common/oslib/include/chdynamic.h delete mode 100644 os/common/oslib/src/chdynamic.c create mode 100644 os/rt/include/chdynamic.h create mode 100644 os/rt/src/chdynamic.c diff --git a/os/common/oslib/include/chdynamic.h b/os/common/oslib/include/chdynamic.h deleted file mode 100644 index fa42bf3ae..000000000 --- a/os/common/oslib/include/chdynamic.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chdynamic.h - * @brief Dynamic threads macros and structures. - * - * @addtogroup dynamic_threads - * @{ - */ - -#ifndef _CHDYNAMIC_H_ -#define _CHDYNAMIC_H_ - -#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Module dependencies check. - */ -#if CH_CFG_USE_WAITEXIT == FALSE -#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT" -#endif - -#if (CH_CFG_USE_HEAP == FALSE) && (CH_CFG_USE_MEMPOOLS == FALSE) -#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_HEAP and/or CH_CFG_USE_MEMPOOLS" -#endif - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* - * Dynamic threads APIs. - */ -#ifdef __cplusplus -extern "C" { -#endif -#if CH_CFG_USE_HEAP == TRUE - thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, - const char *name, tprio_t prio, - tfunc_t pf, void *arg); - void chThdFreeToHeap(thread_t *tp); -#endif -#if CH_CFG_USE_MEMPOOLS == TRUE - thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name, - tprio_t prio, tfunc_t pf, void *arg); - void chThdFreeToMemoryPool(thread_t *tp, memory_pool_t *mp); -#endif -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -#endif /* CH_CFG_USE_DYNAMIC == TRUE */ - -#endif /* _CHDYNAMIC_H_ */ - -/** @} */ diff --git a/os/common/oslib/src/chdynamic.c b/os/common/oslib/src/chdynamic.c deleted file mode 100644 index 3865c318a..000000000 --- a/os/common/oslib/src/chdynamic.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chdynamic.c - * @brief Dynamic threads code. - * - * @addtogroup dynamic_threads - * @details Dynamic threads related APIs and services. - * @note Compatible with RT only. - * @{ - */ - -#include "ch.h" - -#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) -/** - * @brief Creates a new thread allocating the memory from the heap. - * @pre The configuration options @p CH_CFG_USE_DYNAMIC and - * @p CH_CFG_USE_HEAP must be enabled in order to use this function. - * @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 automatically, - * it is responsibility of the creator thread to call @p chThdWait() - * and then release the allocated memory. - * - * @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] name thread name - * @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_t structure allocated for - * the thread into the working space area. - * @retval NULL if the memory cannot be allocated. - * - * @api - */ -thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, - const char *name, tprio_t prio, - tfunc_t pf, void *arg) { - void *wsp; - - wsp = chHeapAllocAligned(heapp, size, PORT_WORKING_AREA_ALIGN); - if (wsp == NULL) { - return NULL; - } - - thread_descriptor_t td = { - name, - wsp, - (stkalign_t *)((uint8_t *)wsp + size), - prio, - pf, - arg - }; - - return chThdCreate(&td); -} - -/** - * @brief Releases a thread working area into the owner heap. - * @pre The thread must have been created using @p chThdCreateFromHeap(). - * @pre The thread must be in the state @p CH_STATE_FINAL (terminated). - * - * @param[in] tp the pointer to the thread - * - * @api - */ -void chThdFreeToHeap(thread_t *tp) { - - chDbgCheck(tp != NULL); - chDbgAssert(tp->state == CH_STATE_FINAL, "not terminated"); - - chHeapFree(chthdGetStackLimitX(tp)); -} -#endif /* CH_CFG_USE_HEAP == TRUE */ - -#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__) -/** - * @brief Creates a new thread allocating the memory from the specified - * memory pool. - * @pre The configuration options @p CH_CFG_USE_DYNAMIC and - * @p CH_CFG_USE_MEMPOOLS must be enabled in order to use this - * function. - * @pre The pool must be initialized to contain only objects with - * alignment @p PORT_WORKING_AREA_ALIGN. - * @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 automatically, - * it is responsibility of the creator thread to call @p chThdWait() - * and then release the allocated memory. - * - * @param[in] mp pointer to the memory pool object - * @param[in] name thread name - * @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_t structure allocated for - * the thread into the working space area. - * @retval NULL if the memory pool is empty. - * - * @api - */ -thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name, - tprio_t prio, tfunc_t pf, void *arg) { - void *wsp; - - chDbgCheck(mp != NULL); - - wsp = chPoolAlloc(mp); - if (wsp == NULL) { - return NULL; - } - - thread_descriptor_t td = { - name, - wsp, - (stkalign_t *)((uint8_t *)wsp + mp->object_size), - prio, - pf, - arg - }; - - return chThdCreate(&td); -} - -/** - * @brief Releases a thread working area into a memory pool. - * @pre The thread must have been created using @p chThdCreateFromMemoryPool(). - * @pre The thread must be in the state @p CH_STATE_FINAL (terminated). - * - * @param[in] tp the pointer to the thread - * @param[in] mp pointer to a @p memory_pool_t structure - * - * @api - */ -void chThdFreeToMemoryPool(thread_t *tp, memory_pool_t *mp) { - - chDbgCheck((tp != NULL) && (mp != NULL)); - chDbgAssert(tp->state == CH_STATE_FINAL, "not terminated"); - - chPoolFree(mp, (void *)chthdGetStackLimitX(tp)); -} -#endif /* CH_CFG_USE_MEMPOOLS == TRUE */ - -#endif /* CH_CFG_USE_DYNAMIC == TRUE */ - -/** @} */ diff --git a/os/rt/include/chdynamic.h b/os/rt/include/chdynamic.h new file mode 100644 index 000000000..fa42bf3ae --- /dev/null +++ b/os/rt/include/chdynamic.h @@ -0,0 +1,97 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chdynamic.h + * @brief Dynamic threads macros and structures. + * + * @addtogroup dynamic_threads + * @{ + */ + +#ifndef _CHDYNAMIC_H_ +#define _CHDYNAMIC_H_ + +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Module dependencies check. + */ +#if CH_CFG_USE_WAITEXIT == FALSE +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT" +#endif + +#if (CH_CFG_USE_HEAP == FALSE) && (CH_CFG_USE_MEMPOOLS == FALSE) +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_HEAP and/or CH_CFG_USE_MEMPOOLS" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* + * Dynamic threads APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif +#if CH_CFG_USE_HEAP == TRUE + thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, + const char *name, tprio_t prio, + tfunc_t pf, void *arg); + void chThdFreeToHeap(thread_t *tp); +#endif +#if CH_CFG_USE_MEMPOOLS == TRUE + thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name, + tprio_t prio, tfunc_t pf, void *arg); + void chThdFreeToMemoryPool(thread_t *tp, memory_pool_t *mp); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_DYNAMIC == TRUE */ + +#endif /* _CHDYNAMIC_H_ */ + +/** @} */ diff --git a/os/rt/include/chschd.h b/os/rt/include/chschd.h index 8275a1eee..ca48afe75 100644 --- a/os/rt/include/chschd.h +++ b/os/rt/include/chschd.h @@ -218,131 +218,148 @@ struct ch_thread { /* End of the fields shared with the ReadyList structure. */ #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) /** - * @brief Thread name or @p NULL. + * @brief Thread name or @p NULL. */ const char *name; #endif /** - * @brief Thread stack boundary. - * @note This pointer matches with the working area base address. + * @brief Thread stack boundary. + * @note This pointer matches with the working area base address. */ stkalign_t *stklimit; /** - * @brief Current thread state. + * @brief Current thread state. */ tstate_t state; /** - * @brief Number of ticks remaining to this thread. + * @brief Various thread flags. + */ + tmode_t flags; +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + /** + * @brief References to this thread. + */ + trefs_t refs; +#endif + /** + * @brief Number of ticks remaining to this thread. */ #if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__) tslices_t preempt; #endif #if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__) /** - * @brief Thread consumed time in ticks. - * @note This field can overflow. + * @brief Thread consumed time in ticks. + * @note This field can overflow. */ volatile systime_t time; #endif /** - * @brief State-specific fields. - * @note All the fields declared in this union are only valid in the - * specified state or condition and are thus volatile. + * @brief State-specific fields. + * @note All the fields declared in this union are only valid in the + * specified state or condition and are thus volatile. */ union { /** - * @brief Thread wakeup code. - * @note This field contains the low level message sent to the thread - * by the waking thread or interrupt handler. The value is valid - * after exiting the @p chSchWakeupS() function. + * @brief Thread wakeup code. + * @note This field contains the low level message sent to the thread + * by the waking thread or interrupt handler. The value is valid + * after exiting the @p chSchWakeupS() function. */ msg_t rdymsg; /** - * @brief Thread exit code. - * @note The thread termination code is stored in this field in order - * to be retrieved by the thread performing a @p chThdWait() on - * this thread. + * @brief Thread exit code. + * @note The thread termination code is stored in this field in order + * to be retrieved by the thread performing a @p chThdWait() on + * this thread. */ msg_t exitcode; /** - * @brief Pointer to a generic "wait" object. - * @note This field is used to get a generic pointer to a synchronization - * object and is valid when the thread is in one of the wait - * states. + * @brief Pointer to a generic "wait" object. + * @note This field is used to get a generic pointer to a synchronization + * object and is valid when the thread is in one of the wait + * states. */ void *wtobjp; /** - * @brief Pointer to a generic thread reference object. - * @note This field is used to get a pointer to a synchronization - * object and is valid when the thread is in @p CH_STATE_SUSPENDED - * state. + * @brief Pointer to a generic thread reference object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_SUSPENDED + * state. */ thread_reference_t *wttrp; #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) /** - * @brief Thread sent message. + * @brief Thread sent message. */ msg_t sentmsg; #endif #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__) /** - * @brief Pointer to a generic semaphore object. - * @note This field is used to get a pointer to a synchronization - * object and is valid when the thread is in @p CH_STATE_WTSEM - * state. + * @brief Pointer to a generic semaphore object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_WTSEM + * state. */ struct ch_semaphore *wtsemp; #endif #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) /** - * @brief Pointer to a generic mutex object. - * @note This field is used to get a pointer to a synchronization - * object and is valid when the thread is in @p CH_STATE_WTMTX - * state. + * @brief Pointer to a generic mutex object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_WTMTX + * state. */ struct ch_mutex *wtmtxp; #endif #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) /** - * @brief Enabled events mask. - * @note This field is only valid while the thread is in the - * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. + * @brief Enabled events mask. + * @note This field is only valid while the thread is in the + * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. */ eventmask_t ewmask; #endif } u; #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__) /** - * @brief Termination waiting list. + * @brief Termination waiting list. */ threads_list_t waiting; #endif #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) /** - * @brief Messages queue. + * @brief Messages queue. */ threads_queue_t msgqueue; #endif #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) /** - * @brief Pending events mask. + * @brief Pending events mask. */ eventmask_t epending; #endif #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) /** - * @brief List of the mutexes owned by this thread. - * @note The list is terminated by a @p NULL in this field. + * @brief List of the mutexes owned by this thread. + * @note The list is terminated by a @p NULL in this field. */ struct ch_mutex *mtxlist; /** - * @brief Thread's own, non-inherited, priority. + * @brief Thread's own, non-inherited, priority. */ tprio_t realprio; #endif +#if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \ + defined(__DOXYGEN__) + /** + * @brief Memory Pool where the thread workspace is returned. + */ + void *mpool; +#endif #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) /** - * @brief Thread statistics. + * @brief Thread statistics. */ time_measurement_t stats; #endif diff --git a/os/rt/rt.mk b/os/rt/rt.mk index 971e18c23..cf92d654d 100644 --- a/os/rt/rt.mk +++ b/os/rt/rt.mk @@ -35,6 +35,9 @@ endif ifneq ($(findstring CH_CFG_USE_QUEUES TRUE,$(CHCONF)),) KERNSRC += $(CHIBIOS)/os/rt/src/chqueues.c endif +ifneq ($(findstring CH_CFG_USE_DYNAMIC TRUE,$(CHCONF)),) +KERNSRC += $(CHIBIOS)/os/rt/src/chdynamic.c +endif ifneq ($(findstring CH_CFG_USE_MAILBOXES TRUE,$(CHCONF)),) KERNSRC += $(CHIBIOS)/os/common/oslib/src/chmboxes.c endif @@ -47,9 +50,6 @@ endif ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHCONF)),) KERNSRC += $(CHIBIOS)/os/common/oslib/src/chmempools.c endif -ifneq ($(findstring CH_CFG_USE_DYNAMIC TRUE,$(CHCONF)),) -KERNSRC += $(CHIBIOS)/os/common/oslib/src/chdynamic.c -endif else KERNSRC := $(CHIBIOS)/os/rt/src/chsys.c \ $(CHIBIOS)/os/rt/src/chdebug.c \ @@ -65,11 +65,11 @@ KERNSRC := $(CHIBIOS)/os/rt/src/chsys.c \ $(CHIBIOS)/os/rt/src/chevents.c \ $(CHIBIOS)/os/rt/src/chmsg.c \ $(CHIBIOS)/os/rt/src/chqueues.c \ + $(CHIBIOS)/os/rt/src/chdynamic.c \ $(CHIBIOS)/os/common/oslib/src/chmboxes.c \ $(CHIBIOS)/os/common/oslib/src/chmemcore.c \ $(CHIBIOS)/os/common/oslib/src/chheap.c \ - $(CHIBIOS)/os/common/oslib/src/chmempools.c \ - $(CHIBIOS)/os/common/oslib/src/chdynamic.c + $(CHIBIOS)/os/common/oslib/src/chmempools.c endif # Required include directories diff --git a/os/rt/src/chdynamic.c b/os/rt/src/chdynamic.c new file mode 100644 index 000000000..414cfe2c8 --- /dev/null +++ b/os/rt/src/chdynamic.c @@ -0,0 +1,193 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chdynamic.c + * @brief Dynamic threads code. + * + * @addtogroup dynamic_threads + * @details Dynamic threads related APIs and services. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the heap. + * @pre The configuration options @p CH_CFG_USE_DYNAMIC and + * @p CH_CFG_USE_HEAP must be enabled in order to use this function. + * @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 automatically, + * it is responsibility of the creator thread to call @p chThdWait() + * and then release the allocated memory. + * + * @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] name thread name + * @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_t structure allocated for + * the thread into the working space area. + * @retval NULL if the memory cannot be allocated. + * + * @api + */ +thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, + const char *name, tprio_t prio, + tfunc_t pf, void *arg) { + void *wsp; + + wsp = chHeapAllocAligned(heapp, size, PORT_WORKING_AREA_ALIGN); + if (wsp == NULL) { + return NULL; + } + + thread_descriptor_t td = { + name, + wsp, + (stkalign_t *)((uint8_t *)wsp + size), + prio, + pf, + arg + }; + + return chThdCreate(&td); +} + +/** + * @brief Releases a thread working area into the owner heap. + * @pre The thread must have been created using @p chThdCreateFromHeap(). + * @pre The thread must be in the state @p CH_STATE_FINAL (terminated). + * + * @param[in] tp the pointer to the thread + * + * @api + */ +void chThdFreeToHeap(thread_t *tp) { + + chDbgCheck(tp != NULL); + chDbgAssert(tp->state == CH_STATE_FINAL, "not terminated"); + + chHeapFree(chthdGetStackLimitX(tp)); +} +#endif /* CH_CFG_USE_HEAP == TRUE */ + +#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the specified + * memory pool. + * @pre The configuration options @p CH_CFG_USE_DYNAMIC and + * @p CH_CFG_USE_MEMPOOLS must be enabled in order to use this + * function. + * @pre The pool must be initialized to contain only objects with + * alignment @p PORT_WORKING_AREA_ALIGN. + * @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 automatically, + * it is responsibility of the creator thread to call @p chThdWait() + * and then release the allocated memory. + * + * @param[in] mp pointer to the memory pool object + * @param[in] name thread name + * @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_t structure allocated for + * the thread into the working space area. + * @retval NULL if the memory pool is empty. + * + * @api + */ +thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name, + tprio_t prio, tfunc_t pf, void *arg) { + void *wsp; + + chDbgCheck(mp != NULL); + + wsp = chPoolAlloc(mp); + if (wsp == NULL) { + return NULL; + } + + thread_descriptor_t td = { + name, + wsp, + (stkalign_t *)((uint8_t *)wsp + mp->object_size), + prio, + pf, + arg + }; + + return chThdCreate(&td); +} + +/** + * @brief Releases a thread working area into a memory pool. + * @pre The thread must have been created using @p chThdCreateFromMemoryPool(). + * @pre The thread must be in the state @p CH_STATE_FINAL (terminated). + * + * @param[in] tp the pointer to the thread + * @param[in] mp pointer to a @p memory_pool_t structure + * + * @api + */ +void chThdFreeToMemoryPool(thread_t *tp, memory_pool_t *mp) { + + chDbgCheck((tp != NULL) && (mp != NULL)); + chDbgAssert(tp->state == CH_STATE_FINAL, "not terminated"); + + chPoolFree(mp, (void *)chthdGetStackLimitX(tp)); +} +#endif /* CH_CFG_USE_MEMPOOLS == TRUE */ + +#endif /* CH_CFG_USE_DYNAMIC == TRUE */ + +/** @} */ diff --git a/os/rt/src/chregistry.c b/os/rt/src/chregistry.c index 944383bf1..7d870897b 100644 --- a/os/rt/src/chregistry.c +++ b/os/rt/src/chregistry.c @@ -101,8 +101,12 @@ ROMCONST chdebug_t ch_debug = { (uint8_t)0, #endif (uint8_t)_offsetof(thread_t, state), - (uint8_t)0, /* Flags no more part of the structure. */ - (uint8_t)0, /* Refs no more part of the structure. */ + (uint8_t)_offsetof(thread_t, flags), +#if CH_CFG_USE_DYNAMIC == TRUE + (uint8_t)_offsetof(thread_t, refs), +#else + (uint8_t)0, +#endif #if CH_CFG_TIME_QUANTUM > 0 (uint8_t)_offsetof(thread_t, preempt), #else @@ -132,6 +136,9 @@ thread_t *chRegFirstThread(void) { chSysLock(); tp = ch.rlist.newer; +#if CH_CFG_USE_DYNAMIC == TRUE + tp->refs++; +#endif chSysUnlock(); return tp; @@ -158,7 +165,16 @@ thread_t *chRegNextThread(thread_t *tp) { /*lint -restore*/ ntp = NULL; } +#if CH_CFG_USE_DYNAMIC == TRUE + else { + chDbgAssert(ntp->refs < (trefs_t)255, "too many references"); + ntp->refs++; + } +#endif chSysUnlock(); +#if CH_CFG_USE_DYNAMIC == TRUE + chThdRelease(tp); +#endif return ntp; } @@ -186,7 +202,6 @@ thread_t *chRegFindThreadByName(const char *name) { return NULL; } -#endif /* CH_CFG_USE_REGISTRY == TRUE */ /** * @brief Confirms that a pointer is a valid thread pointer. @@ -212,4 +227,6 @@ thread_t *chRegFindThreadByPointer(thread_t *tp) { return NULL; } +#endif /* CH_CFG_USE_REGISTRY == TRUE */ + /** @} */ diff --git a/os/rt/src/chsys.c b/os/rt/src/chsys.c index d9ca6d81a..18459849d 100644 --- a/os/rt/src/chsys.c +++ b/os/rt/src/chsys.c @@ -129,6 +129,7 @@ void chSysInit(void) { /* Setting up the caller as current thread.*/ currp->state = CH_STATE_CURRENT; + currp->flags = CH_FLAG_MODE_STATIC; /* Port layer initialization last because it depend on some of the initializations performed before.*/ diff --git a/os/rt/src/chthreads.c b/os/rt/src/chthreads.c index e706c0d77..0fff76604 100644 --- a/os/rt/src/chthreads.c +++ b/os/rt/src/chthreads.c @@ -175,6 +175,7 @@ thread_t *chThdCreateSuspendedI(const thread_descriptor_t *tdp) { /* Initial state.*/ tp->state = CH_STATE_WTSTART; + tp->flags = CH_FLAG_MODE_STATIC; /* Stack boundary.*/ tp->stklimit = tdp->wbase; -- cgit v1.2.3