git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8941 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
a2072b5560
commit
6d6284c9e6
|
@ -71,16 +71,16 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
thread_t *chThdAddRef(thread_t *tp);
|
||||
void chThdRelease(thread_t *tp);
|
||||
#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
|
||||
}
|
||||
|
|
|
@ -37,14 +37,6 @@
|
|||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Event bit reserved for thread termination request.
|
||||
* @note The most significant bit of the events mask is conventionally
|
||||
* used for thread termination but it can eventually be used for
|
||||
* other events.
|
||||
*/
|
||||
#define CH_EVENT_TERMINATE ~(((eventmask_t)-1) >> 1U)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -182,6 +182,7 @@ extern "C" {
|
|||
tprio_t prio, tfunc_t pf, void *arg);
|
||||
thread_t *chThdStart(thread_t *tp);
|
||||
tprio_t chThdSetPriority(tprio_t newprio);
|
||||
void chThdTerminate(thread_t *tp);
|
||||
msg_t chThdSuspendS(thread_reference_t *trp);
|
||||
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);
|
||||
void chThdResumeI(thread_reference_t *trp, msg_t msg);
|
||||
|
@ -276,6 +277,19 @@ static inline bool chThdTerminatedX(thread_t *tp) {
|
|||
return (bool)(tp->state == CH_STATE_FINAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verifies if the current thread has a termination request pending.
|
||||
*
|
||||
* @retval true termination request pending.
|
||||
* @retval false termination request not pending.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline bool chThdShouldTerminateX(void) {
|
||||
|
||||
return (bool)((chThdGetSelfX()->flags & CH_FLAG_TERMINATE) != (tmode_t)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resumes a thread created with @p chThdCreateI().
|
||||
*
|
||||
|
|
|
@ -54,6 +54,78 @@
|
|||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Adds a reference to a thread object.
|
||||
* @pre The configuration option @p CH_CFG_USE_DYNAMIC must be enabled in
|
||||
* order to use this function.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
* @return The same thread pointer passed as parameter
|
||||
* representing the new reference.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
thread_t *chThdAddRef(thread_t *tp) {
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert(tp->refs < (trefs_t)255, "too many references");
|
||||
tp->refs++;
|
||||
chSysUnlock();
|
||||
|
||||
return tp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a reference to a thread object.
|
||||
* @details If the references counter reaches zero <b>and</b> the thread
|
||||
* is in the @p CH_STATE_FINAL state then the thread's memory is
|
||||
* returned to the proper allocator.
|
||||
* @pre The configuration option @p CH_CFG_USE_DYNAMIC must be enabled in
|
||||
* order to use this function.
|
||||
* @note Static threads are not affected.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chThdRelease(thread_t *tp) {
|
||||
trefs_t refs;
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert(tp->refs > (trefs_t)0, "not referenced");
|
||||
tp->refs--;
|
||||
refs = tp->refs;
|
||||
chSysUnlock();
|
||||
|
||||
/* If the references counter reaches zero and the thread is in its
|
||||
terminated state then the memory can be returned to the proper
|
||||
allocator. Of course static threads are not affected.*/
|
||||
if ((refs == (trefs_t)0) && (tp->state == CH_STATE_FINAL)) {
|
||||
switch (tp->flags & CH_FLAG_MODE_MASK) {
|
||||
#if CH_CFG_USE_HEAP == TRUE
|
||||
case CH_FLAG_MODE_HEAP:
|
||||
#if CH_CFG_USE_REGISTRY == TRUE
|
||||
REG_REMOVE(tp);
|
||||
#endif
|
||||
chHeapFree(chthdGetStackLimitX(tp));
|
||||
break;
|
||||
#endif
|
||||
#if CH_CFG_USE_MEMPOOLS == TRUE
|
||||
case CH_FLAG_MODE_MPOOL:
|
||||
#if CH_CFG_USE_REGISTRY == TRUE
|
||||
REG_REMOVE(tp);
|
||||
#endif
|
||||
chPoolFree(tp->mpool, chthdGetStackLimitX(tp));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Nothing to do for static threads, those are removed from the
|
||||
registry on exit.*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Creates a new thread allocating the memory from the heap.
|
||||
|
@ -82,6 +154,7 @@
|
|||
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
||||
const char *name, tprio_t prio,
|
||||
tfunc_t pf, void *arg) {
|
||||
thread_t *tp;
|
||||
void *wsp;
|
||||
|
||||
wsp = chHeapAllocAligned(heapp, size, PORT_WORKING_AREA_ALIGN);
|
||||
|
@ -98,24 +171,19 @@ thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
|||
arg
|
||||
};
|
||||
|
||||
return chThdCreate(&td);
|
||||
}
|
||||
#if CH_DBG_FILL_THREADS == TRUE
|
||||
_thread_memfill((uint8_t *)wsp,
|
||||
(uint8_t *)wsp + size,
|
||||
CH_DBG_STACK_FILL_VALUE);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
chSysLock();
|
||||
tp = chThdCreateSuspendedI(&td);
|
||||
tp->flags = CH_FLAG_MODE_HEAP;
|
||||
chSchWakeupS(tp, MSG_OK);
|
||||
chSysUnlock();
|
||||
|
||||
chDbgCheck(tp != NULL);
|
||||
chDbgAssert(tp->state == CH_STATE_FINAL, "not terminated");
|
||||
|
||||
chHeapFree(chthdGetStackLimitX(tp));
|
||||
return tp;
|
||||
}
|
||||
#endif /* CH_CFG_USE_HEAP == TRUE */
|
||||
|
||||
|
@ -148,6 +216,7 @@ void chThdFreeToHeap(thread_t *tp) {
|
|||
*/
|
||||
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name,
|
||||
tprio_t prio, tfunc_t pf, void *arg) {
|
||||
thread_t *tp;
|
||||
void *wsp;
|
||||
|
||||
chDbgCheck(mp != NULL);
|
||||
|
@ -166,25 +235,21 @@ thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name,
|
|||
arg
|
||||
};
|
||||
|
||||
return chThdCreate(&td);
|
||||
}
|
||||
#if CH_DBG_FILL_THREADS == TRUE
|
||||
_thread_memfill((uint8_t *)wsp,
|
||||
(uint8_t *)wsp + mp->object_size,
|
||||
CH_DBG_STACK_FILL_VALUE);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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");
|
||||
chSysLock();
|
||||
tp = chThdCreateSuspendedI(&td);
|
||||
tp->flags = CH_FLAG_MODE_MPOOL;
|
||||
tp->mpool = mp;
|
||||
chSchWakeupS(tp, MSG_OK);
|
||||
chSysUnlock();
|
||||
|
||||
chPoolFree(mp, (void *)chthdGetStackLimitX(tp));
|
||||
return tp;
|
||||
}
|
||||
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
|
||||
|
||||
|
|
|
@ -129,7 +129,6 @@ 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.*/
|
||||
|
|
|
@ -88,6 +88,8 @@
|
|||
thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) {
|
||||
|
||||
tp->prio = prio;
|
||||
tp->state = CH_STATE_WTSTART;
|
||||
tp->flags = CH_FLAG_MODE_STATIC;
|
||||
#if CH_CFG_TIME_QUANTUM > 0
|
||||
tp->preempt = (tslices_t)CH_CFG_TIME_QUANTUM;
|
||||
#endif
|
||||
|
@ -101,6 +103,9 @@ thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) {
|
|||
#if CH_DBG_THREADS_PROFILING == TRUE
|
||||
tp->time = (systime_t)0;
|
||||
#endif
|
||||
#if CH_CFG_USE_DYNAMIC == TRUE
|
||||
tp->refs = (trefs_t)1;
|
||||
#endif
|
||||
#if CH_CFG_USE_REGISTRY == TRUE
|
||||
tp->name = name;
|
||||
REG_INSERT(tp);
|
||||
|
@ -173,10 +178,6 @@ thread_t *chThdCreateSuspendedI(const thread_descriptor_t *tdp) {
|
|||
tp = (thread_t *)((uint8_t *)tdp->wend -
|
||||
MEM_ALIGN_NEXT(sizeof (thread_t), PORT_STACK_ALIGN));
|
||||
|
||||
/* Initial state.*/
|
||||
tp->state = CH_STATE_WTSTART;
|
||||
tp->flags = CH_FLAG_MODE_STATIC;
|
||||
|
||||
/* Stack boundary.*/
|
||||
tp->stklimit = tdp->wbase;
|
||||
|
||||
|
@ -379,6 +380,25 @@ tprio_t chThdSetPriority(tprio_t newprio) {
|
|||
return oldprio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requests a thread termination.
|
||||
* @pre The target thread must be written to invoke periodically
|
||||
* @p chThdShouldTerminate() and terminate cleanly if it returns
|
||||
* @p true.
|
||||
* @post The specified thread will terminate after detecting the termination
|
||||
* condition.
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chThdTerminate(thread_t *tp) {
|
||||
|
||||
chSysLock();
|
||||
tp->flags |= CH_FLAG_TERMINATE;
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspends the invoking thread for the specified time.
|
||||
*
|
||||
|
@ -501,14 +521,20 @@ void chThdExitS(msg_t msg) {
|
|||
thread_t *tp = currp;
|
||||
|
||||
tp->u.exitcode = msg;
|
||||
#if defined(CH_CFG_THREAD_EXIT_HOOK)
|
||||
CH_CFG_THREAD_EXIT_HOOK(tp);
|
||||
#endif
|
||||
#if CH_CFG_USE_WAITEXIT == TRUE
|
||||
while (list_notempty(&tp->waiting)) {
|
||||
(void) chSchReadyI(list_remove(&tp->waiting));
|
||||
}
|
||||
#endif
|
||||
#if CH_CFG_USE_REGISTRY == TRUE
|
||||
/* Static threads are immediately removed from the registry because
|
||||
there is no memory to recover.*/
|
||||
if ((tp->flags & CH_FLAG_MODE_MASK) == CH_FLAG_MODE_STATIC) {
|
||||
REG_REMOVE(tp);
|
||||
}
|
||||
#endif
|
||||
chSchGoSleepS(CH_STATE_FINAL);
|
||||
|
||||
|
@ -520,12 +546,28 @@ void chThdExitS(msg_t msg) {
|
|||
/**
|
||||
* @brief Blocks the execution of the invoking thread until the specified
|
||||
* thread terminates then the exit code is returned.
|
||||
* @details This function waits for the specified thread to terminate then
|
||||
* decrements its reference counter, if the counter reaches zero then
|
||||
* the thread working area is returned to the proper allocator.<br>
|
||||
* The memory used by the exited thread is handled in different ways
|
||||
* depending on the API that spawned the thread:
|
||||
* - If the thread was spawned by @p chThdCreateStatic() or by
|
||||
* @p chThdCreateI() then nothing happens and the thread working
|
||||
* area is not released or modified in any way. This is the
|
||||
* default, totally static, behavior.
|
||||
* - If the thread was spawned by @p chThdCreateFromHeap() then
|
||||
* the working area is returned to the system heap.
|
||||
* - If the thread was spawned by @p chThdCreateFromMemoryPool()
|
||||
* then the working area is returned to the owning memory pool.
|
||||
* .
|
||||
* @pre The configuration option @p CH_CFG_USE_WAITEXIT must be enabled in
|
||||
* order to use this function.
|
||||
* @post Enabling @p chThdWait() requires 2-4 (depending on the
|
||||
* architecture) extra bytes in the @p thread_t structure.
|
||||
* @post After invoking @p chThdWait() the thread pointer becomes invalid
|
||||
* and must not be used as parameter for further system calls.
|
||||
* @note If @p CH_CFG_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.
|
||||
|
@ -539,6 +581,9 @@ msg_t chThdWait(thread_t *tp) {
|
|||
|
||||
chSysLock();
|
||||
chDbgAssert(tp != currp, "waiting self");
|
||||
#if CH_CFG_USE_DYNAMIC == TRUE
|
||||
chDbgAssert(tp->refs > (trefs_t)0, "not referenced");
|
||||
#endif
|
||||
if (tp->state != CH_STATE_FINAL) {
|
||||
list_insert(currp, &tp->waiting);
|
||||
chSchGoSleepS(CH_STATE_WTEXIT);
|
||||
|
@ -546,6 +591,11 @@ msg_t chThdWait(thread_t *tp) {
|
|||
msg = tp->u.exitcode;
|
||||
chSysUnlock();
|
||||
|
||||
#if CH_CFG_USE_DYNAMIC == TRUE
|
||||
/* Releasing a lock if it is a dynamic thread.*/
|
||||
chThdRelease(tp);
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* CH_CFG_USE_WAITEXIT */
|
||||
|
|
|
@ -144,12 +144,12 @@ static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) {
|
|||
chprintf(chp, "Usage: threads\r\n");
|
||||
return;
|
||||
}
|
||||
chprintf(chp, "stklimit stack addr prio state name\r\n");
|
||||
chprintf(chp, "stklimit stack addr refs prio state name\r\n");
|
||||
tp = chRegFirstThread();
|
||||
do {
|
||||
chprintf(chp, "%08lx %08lx %08lx %4lu %9s %12s\r\n",
|
||||
chprintf(chp, "%08lx %08lx %08lx %4lu %4lu %9s %12s\r\n",
|
||||
(uint32_t)tp->stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp,
|
||||
(uint32_t)tp->prio, states[tp->state],
|
||||
(uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state],
|
||||
tp->name == NULL ? "" : tp->name);
|
||||
tp = chRegNextThread(tp);
|
||||
} while (tp != NULL);
|
||||
|
@ -173,7 +173,6 @@ static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) {
|
|||
return;
|
||||
}
|
||||
chThdWait(tp);
|
||||
chThdFreeToHeap(tp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,11 +26,7 @@ a series of important new features.
|
|||
- Enhanced trace buffer, it is able to store events regarding not just threads
|
||||
but also IRQs, halts and user events.
|
||||
- Enhanced Registry, it is now possible to find threads by name or by pointer.
|
||||
- Simplified the dynamic threading model, now it is the thread creator
|
||||
responsible for memory release, the references counter has been removed
|
||||
and the code is much simpler.
|
||||
- New threading API, now creating static threads is even faster.
|
||||
- Saved space in thread_t structure.
|
||||
- Extended priority range to 1..255.
|
||||
- Experimental NASA OSAL implementation.
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "testevt.h"
|
||||
#include "testheap.h"
|
||||
#include "testpools.h"
|
||||
#include "testdyn.h"
|
||||
#include "testqueues.h"
|
||||
#include "testbmk.h"
|
||||
|
||||
|
@ -51,6 +52,7 @@ static ROMCONST struct testcase * ROMCONST *patterns[] = {
|
|||
patternevt,
|
||||
patternheap,
|
||||
patternpools,
|
||||
patterndyn,
|
||||
patternqueues,
|
||||
patternbmk,
|
||||
NULL
|
||||
|
@ -191,6 +193,17 @@ bool _test_assert_time_window(unsigned point, systime_t start, systime_t end) {
|
|||
* Threads utils.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets a termination request in all the test-spawned threads.
|
||||
*/
|
||||
void test_terminate_threads(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_THREADS; i++)
|
||||
if (threads[i])
|
||||
chThdTerminate(threads[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits for the completion of all the test-spawned threads.
|
||||
*/
|
||||
|
|
|
@ -90,6 +90,7 @@ extern "C" {
|
|||
bool _test_assert(unsigned point, bool condition);
|
||||
bool _test_assert_sequence(unsigned point, char *expected);
|
||||
bool _test_assert_time_window(unsigned point, systime_t start, systime_t end);
|
||||
void test_terminate_threads(void);
|
||||
void test_wait_threads(void);
|
||||
systime_t test_wait_tick(void);
|
||||
void test_start_timer(unsigned ms);
|
||||
|
|
|
@ -8,6 +8,7 @@ TESTSRC = ${CHIBIOS}/test/rt/test.c \
|
|||
${CHIBIOS}/test/rt/testevt.c \
|
||||
${CHIBIOS}/test/rt/testheap.c \
|
||||
${CHIBIOS}/test/rt/testpools.c \
|
||||
${CHIBIOS}/test/rt/testdyn.c \
|
||||
${CHIBIOS}/test/rt/testqueues.c \
|
||||
${CHIBIOS}/test/rt/testsys.c \
|
||||
${CHIBIOS}/test/rt/testbmk.c
|
||||
|
|
|
@ -344,7 +344,8 @@ ROMCONST struct testcase testbmk6 = {
|
|||
|
||||
static THD_FUNCTION(thread3, p) {
|
||||
|
||||
while (!*(bool *)p)
|
||||
(void)p;
|
||||
while (!chThdShouldTerminateX())
|
||||
chSemWait(&sem1);
|
||||
}
|
||||
|
||||
|
@ -355,13 +356,12 @@ static void bmk7_setup(void) {
|
|||
|
||||
static void bmk7_execute(void) {
|
||||
uint32_t n;
|
||||
bool terminate = false;
|
||||
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread3, &terminate);
|
||||
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, thread3, &terminate);
|
||||
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread3, &terminate);
|
||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, thread3, &terminate);
|
||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, thread3, &terminate);
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread3, NULL);
|
||||
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, thread3, NULL);
|
||||
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread3, NULL);
|
||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, thread3, NULL);
|
||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, thread3, NULL);
|
||||
|
||||
n = 0;
|
||||
test_wait_tick();
|
||||
|
@ -373,7 +373,7 @@ static void bmk7_execute(void) {
|
|||
_sim_check_for_interrupts();
|
||||
#endif
|
||||
} while (!test_timer_done);
|
||||
terminate = true;
|
||||
test_terminate_threads();
|
||||
chSemReset(&sem1, 0);
|
||||
test_wait_threads();
|
||||
|
||||
|
@ -401,44 +401,39 @@ ROMCONST struct testcase testbmk7 = {
|
|||
* The performance is calculated by measuring the number of iterations after
|
||||
* a second of continuous operations.
|
||||
*/
|
||||
typedef struct {
|
||||
bool terminate;
|
||||
uint32_t n;
|
||||
} params_t;
|
||||
|
||||
static THD_FUNCTION(thread8, p) {
|
||||
params_t *pp = (params_t *)p;
|
||||
|
||||
do {
|
||||
chThdYield();
|
||||
chThdYield();
|
||||
chThdYield();
|
||||
chThdYield();
|
||||
pp->n += 4;
|
||||
(*(uint32_t *)p) += 4;
|
||||
#if defined(SIMULATOR)
|
||||
_sim_check_for_interrupts();
|
||||
#endif
|
||||
} while (!pp->terminate);
|
||||
} while(!chThdShouldTerminateX());
|
||||
}
|
||||
|
||||
static void bmk8_execute(void) {
|
||||
params_t params = {false, 0};
|
||||
uint32_t n;
|
||||
|
||||
params.n = 0;
|
||||
n = 0;
|
||||
test_wait_tick();
|
||||
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)¶ms);
|
||||
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)¶ms);
|
||||
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)¶ms);
|
||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)¶ms);
|
||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)¶ms);
|
||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)&n);
|
||||
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)&n);
|
||||
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)&n);
|
||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)&n);
|
||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread8, (void *)&n);
|
||||
|
||||
chThdSleepSeconds(1);
|
||||
params.terminate = true;
|
||||
test_terminate_threads();
|
||||
test_wait_threads();
|
||||
|
||||
test_print("--- Score : ");
|
||||
test_printn(params.n);
|
||||
test_printn(n);
|
||||
test_println(" ctxswc/S");
|
||||
}
|
||||
|
||||
|
|
|
@ -87,13 +87,16 @@ static void dyn1_execute(void) {
|
|||
/* Starting threads from the heap. */
|
||||
threads[0] = chThdCreateFromHeap(&heap1,
|
||||
THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
|
||||
"dyn1",
|
||||
prio-1, thread, "A");
|
||||
threads[1] = chThdCreateFromHeap(&heap1,
|
||||
THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
|
||||
"dyn2",
|
||||
prio-2, thread, "B");
|
||||
/* Large working area in order to make the thread creation fail.*/
|
||||
threads[2] = chThdCreateFromHeap(&heap1,
|
||||
THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE * 16),
|
||||
"dyn3",
|
||||
prio-3, thread, "C");
|
||||
|
||||
test_assert(1, (threads[0] != NULL) &&
|
||||
|
@ -145,11 +148,11 @@ static void dyn2_execute(void) {
|
|||
chPoolFree(&mp1, wa[i]);
|
||||
|
||||
/* Starting threads from the memory pool. */
|
||||
threads[0] = chThdCreateFromMemoryPool(&mp1, prio-1, thread, "A");
|
||||
threads[1] = chThdCreateFromMemoryPool(&mp1, prio-2, thread, "B");
|
||||
threads[2] = chThdCreateFromMemoryPool(&mp1, prio-3, thread, "C");
|
||||
threads[3] = chThdCreateFromMemoryPool(&mp1, prio-4, thread, "D");
|
||||
threads[4] = chThdCreateFromMemoryPool(&mp1, prio-5, thread, "E");
|
||||
threads[0] = chThdCreateFromMemoryPool(&mp1, "dyn1", prio-1, thread, "A");
|
||||
threads[1] = chThdCreateFromMemoryPool(&mp1, "dyn2", prio-2, thread, "B");
|
||||
threads[2] = chThdCreateFromMemoryPool(&mp1, "dyn3", prio-3, thread, "C");
|
||||
threads[3] = chThdCreateFromMemoryPool(&mp1, "dyn4", prio-4, thread, "D");
|
||||
threads[4] = chThdCreateFromMemoryPool(&mp1, "dyn5", prio-5, thread, "E");
|
||||
|
||||
test_assert(1, (threads[0] != NULL) &&
|
||||
(threads[1] != NULL) &&
|
||||
|
@ -207,7 +210,7 @@ static void dyn3_execute(void) {
|
|||
tprio_t prio = chThdGetPriorityX();
|
||||
|
||||
/* Testing references increase/decrease and final detach.*/
|
||||
tp = chThdCreateFromHeap(&heap1, WA_SIZE, prio-1, thread, "A");
|
||||
tp = chThdCreateFromHeap(&heap1, WA_SIZE, "dyn1", prio-1, thread, "A");
|
||||
test_assert(1, tp->refs == 1, "wrong initial reference counter");
|
||||
chThdAddRef(tp);
|
||||
test_assert(2, tp->refs == 2, "references increase failure");
|
||||
|
|
|
@ -160,8 +160,7 @@ int main(void) {
|
|||
thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
|
||||
"shell", NORMALPRIO + 1,
|
||||
shellThread, (void *)&shell_cfg1);
|
||||
chThdWait(shelltp); /* Waiting termination. */
|
||||
chThdFreeToHeap(shelltp); /* Returning memory to heap. */
|
||||
chThdWait(shelltp);
|
||||
}
|
||||
#if 0
|
||||
if (palReadPad(GPIOI, GPIOI_BUTTON_USER)) {
|
||||
|
|
Loading…
Reference in New Issue