diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-09-22 15:29:48 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-09-22 15:29:48 +0000 |
commit | 9a1c91e6ee9baaee3529e16fc732cbd9c7e99844 (patch) | |
tree | 5916995c67730dc328d2bd40392f6d21c3a54c7e /src/chthreads.c | |
parent | 9b2c9869dd0f5b544d6f1c43c2abea30e5a27b94 (diff) | |
download | ChibiOS-9a1c91e6ee9baaee3529e16fc732cbd9c7e99844.tar.gz ChibiOS-9a1c91e6ee9baaee3529e16fc732cbd9c7e99844.tar.bz2 ChibiOS-9a1c91e6ee9baaee3529e16fc732cbd9c7e99844.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@437 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'src/chthreads.c')
-rw-r--r-- | src/chthreads.c | 169 |
1 files changed, 150 insertions, 19 deletions
diff --git a/src/chthreads.c b/src/chthreads.c index e98bb725f..f4d355a4b 100644 --- a/src/chthreads.c +++ b/src/chthreads.c @@ -27,7 +27,7 @@ /* * Initializes a thread structure. */ -void init_thread(tprio_t prio, Thread *tp) { +void init_thread(Thread *tp, tprio_t prio) { static tid_t nextid = 0; tp->p_tid = nextid++; @@ -83,8 +83,8 @@ static void memfill(uint8_t *p, uint32_t n, uint8_t v) { * @note This function can be used to start a thead from within an interrupt * handler by manually making it ready with \p chSchReadyI(). */ -Thread *chThdInit(tprio_t prio, void *workspace, - size_t wsize, tfunc_t pf, void *arg) { +Thread *chThdInit(void *workspace, size_t wsize, + tprio_t prio, tfunc_t pf, void *arg) { /* thread structure is layed out in the lower part of the thread workspace */ Thread *tp = workspace; @@ -95,17 +95,17 @@ Thread *chThdInit(tprio_t prio, void *workspace, memfill(workspace, wsize, MEM_FILL_PATTERN); #endif SETUP_CONTEXT(workspace, wsize, pf, arg); - init_thread(prio, tp); + init_thread(tp, prio); return tp; } /** - * Creates a new thread. + * Creates a new thread into a static memory area. + * @param workspace pointer to a working area dedicated to the thread stack + * @param wsize size of the working area. * @param prio the priority level for the new thread. Usually the threads are * created with priority \p NORMALPRIO, priorities * can range from \p LOWPRIO to \p HIGHPRIO. - * @param workspace pointer to a working area dedicated to the thread stack - * @param wsize size of the working area. * @param pf the thread function. Returning from this function automatically * terminates the thread. * @param arg an argument passed to the thread function. It can be \p NULL. @@ -114,16 +114,113 @@ Thread *chThdInit(tprio_t prio, void *workspace, * @note A thread can terminate by calling \p chThdExit() or by simply * returning from its main function. */ -Thread *chThdCreate(tprio_t prio, void *workspace, - size_t wsize, tfunc_t pf, void *arg) { +Thread *chThdCreateStatic(void *workspace, size_t wsize, + tprio_t prio, tfunc_t pf, void *arg) { - Thread *tp = chThdInit(prio, workspace, wsize, pf, arg); + Thread *tp = chThdInit(workspace, wsize, prio, pf, arg); chSysLock(); chSchWakeupS(tp, RDY_OK); chSysUnlock(); return tp; } +#if defined(CH_USE_DYNAMIC) && defined(CH_USE_WAITEXIT) && defined(CH_USE_HEAP) +/** + * Creates a new thread allocating the memory from the heap. + * @param wsize size of the working area to be allocated + * @param prio the priority level for the new thread. Usually the threads are + * created with priority \p NORMALPRIO, priorities + * can range from \p LOWPRIO to \p HIGHPRIO. + * @param pf the thread function. Returning from this function automatically + * terminates the thread. + * @param 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. + * @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. + */ +Thread *chThdCreateFromHeap(size_t wsize, tprio_t prio, + tfunc_t pf, void *arg) { + + void *workspace = chHeapAlloc(wsize); + if (workspace == NULL) + return NULL; + Thread *tp = chThdInit(workspace, wsize, prio, pf, arg); + tp->p_flags |= P_MEM_MODE_HEAP; + chSysLock(); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} +#endif /* defined(CH_USE_DYNAMIC) && defined(CH_USE_WAITEXIT) && defined(CH_USE_HEAP) */ + +#if defined(CH_USE_DYNAMIC) && defined(CH_USE_WAITEXIT) && defined(CH_USE_MEMPOOLS) +/** + * Creates a new thread allocating the memory from the specified Memory Pool. + * @param mp the memory pool + * @param prio the priority level for the new thread. Usually the threads are + * created with priority \p NORMALPRIO, priorities + * can range from \p LOWPRIO to \p HIGHPRIO. + * @param pf the thread function. Returning from this function automatically + * terminates the thread. + * @param 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. + * @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. + */ +Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, + tfunc_t pf, void *arg) { + + void *workspace = chPoolAlloc(mp); + if (workspace == NULL) + return NULL; + Thread *tp = chThdInit(workspace, mp->mp_object_size, prio, pf, arg); + tp->p_flags |= P_MEM_MODE_MEMPOOL; + tp->p_mpool = mp; + chSysLock(); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} +#endif /* defined(CH_USE_DYNAMIC) && defined(CH_USE_WAITEXIT) && defined(CH_USE_MEMPOOLS) */ + +/** + * Creates a new thread. + * @param prio the priority level for the new thread. Usually the threads are + * created with priority \p NORMALPRIO, priorities + * can range from \p LOWPRIO to \p HIGHPRIO. + * @param mode ignored + * @param workspace pointer to a working area dedicated to the thread stack + * @param wsize size of the working area. + * @param pf the thread function. Returning from this function automatically + * terminates the thread. + * @param 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. + * @deprecated Please use \p chThdCreateStatic() or \p chThdInit() instead, + * this function will be removed in version 1.0.0. + */ +Thread *chThdCreate(tprio_t prio, tmode_t mode, void *workspace, + size_t wsize, tfunc_t pf, void *arg) { + + return chThdCreateStatic(workspace, wsize, prio, pf, arg); +} + /** * Creates a new thread. * @param prio the priority level for the new thread. Usually the threads are @@ -137,16 +234,13 @@ Thread *chThdCreate(tprio_t prio, void *workspace, * thread into the working space area. * @note A thread can terminate by calling \p chThdExit() or by simply * returning from its main function. - * @deprecated + * @deprecated Please use \p chThdCreateStatic() or \p chThdInit() instead, + * this function will be removed in version 1.0.0. */ Thread *chThdCreateFast(tprio_t prio, void *workspace, size_t wsize, tfunc_t pf) { - Thread *tp = chThdInit(prio, workspace, wsize, pf, NULL); - chSysLock(); - chSchWakeupS(tp, RDY_OK); - chSysUnlock(); - return tp; + return chThdCreateStatic(workspace, wsize, prio, pf, NULL); } /** @@ -245,9 +339,21 @@ void chThdExit(msg_t msg) { /** * Blocks the execution of the invoking thread until the specified thread * terminates then the exit code is returned. - * - * @param tp the pointer to the thread - * @return the exit code + * The memory used by the exited thread is handled in different ways depending + * on the API that spawned the thread: + * <ul> + * <li>If the thread was spawned by \p chThdCreateStatic() or by \p chThdInit() + * then nothing happens and the thread working area is not released or + * modified in any way. This is the default, totally static, behavior.</li> + * <li>If the thread was spawned by \p chThdCreateFromHeap() then the working + * area is returned to the system heap.</li> + * <li>If the thread was spawned by \p chThdCreateFromMemoryPool() then the + * working area is returned to the owning memory pool.</li> + * </ul> + * @param 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. */ @@ -262,8 +368,33 @@ msg_t chThdWait(Thread *tp) { } msg = tp->p_exitcode; +#ifndef CH_USE_DYNAMIC + chSysUnlock(); + return msg; +#else /* CH_USE_DYNAMIC */ + if (notempty(&tp->p_waiting)) { + chSysUnlock(); + return msg; + } + + /* This is the last thread waiting for termination, returning memory.*/ + tmode_t mode = tp->p_flags & P_MEM_MODE_MASK; chSysUnlock(); + + switch (mode) { +#ifdef CH_USE_HEAP + case P_MEM_MODE_HEAP: + chHeapFree(tp); + break; +#endif +#ifdef CH_USE_MEMPOOLS + case P_MEM_MODE_MEMPOOL: + chPoolFree(tp->p_mpool, tp); + break; +#endif + } return msg; +#endif /* CH_USE_DYNAMIC */ } #endif /* CH_USE_WAITEXIT */ |