git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1532 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2010-01-20 14:39:34 +00:00
parent ca013cf8e4
commit 7bd8164f8f
12 changed files with 167 additions and 192 deletions

View File

@ -44,118 +44,94 @@
*/ */
struct Thread { struct Thread {
Thread *p_next; /**< Next @p Thread in the threads Thread *p_next; /**< Next @p Thread in the threads
list/queue.*/ list/queue. */
/* End of the fields shared with the ThreadsList structure. */ /* End of the fields shared with the ThreadsList structure. */
Thread *p_prev; /**< Previous @p Thread in the threads Thread *p_prev; /**< Previous @p Thread in the threads
queue.*/ queue. */
/* End of the fields shared with the ThreadsQueue structure. */ /* End of the fields shared with the ThreadsQueue structure. */
tprio_t p_prio; /**< Thread priority.*/ tprio_t p_prio; /**< Thread priority. */
/* End of the fields shared with the ReadyList structure. */ /* End of the fields shared with the ReadyList structure. */
tstate_t p_state; /**< Current thread state.*/ tstate_t p_state; /**< Current thread state. */
tmode_t p_flags; /**< Various flags.*/ tmode_t p_flags; /**< Various thread flags. */
struct context p_ctx; /**< Processor context.*/ struct context p_ctx; /**< Processor context. */
#if CH_USE_NESTED_LOCKS #if CH_USE_NESTED_LOCKS
cnt_t p_locks; /**< Number of nested locks.*/ cnt_t p_locks; /**< Number of nested locks. */
#endif #endif
#if CH_DBG_THREADS_PROFILING #if CH_DBG_THREADS_PROFILING
volatile systime_t p_time; /**< Consumed time. volatile systime_t p_time; /**< Thread consumed time in ticks.
@note This field can overflow.*/ @note This field can overflow. */
#endif #endif
/*
* The following fields are merged in unions because they are all
* state-specific fields. This trick saves some extra space for each
* thread in the system.
*/
union { union {
msg_t p_rdymsg; /**< Thread wakeup code.*/ msg_t rdymsg; /**< Thread wakeup code. */
msg_t p_exitcode; /**< The thread exit code msg_t exitcode; /**< The thread exit code
(@p PREXIT state).*/ (@p THD_STATE_FINAL state). */
void *p_wtobjp; /**< Generic kernel object pointer used void *wtobjp; /**< Generic kernel object pointer. */
for opaque access.*/
#if CH_USE_SEMAPHORES
Semaphore *p_wtsemp; /**< Semaphore where the thread is
waiting on (@p PRWTSEM state).*/
#endif
#if CH_USE_MUTEXES
Mutex *p_wtmtxp; /**< Mutex where the thread is waiting
on (@p PRWTMTX state).*/
#endif
#if CH_USE_CONDVARS
CondVar *p_wtcondp; /**< CondVar where the thread is
waiting on (@p PRWTCOND state).*/
#endif
#if CH_USE_MESSAGES
Thread *p_wtthdp; /**< Destination thread for message
send @p PRSNDMSG state).*/
#endif
#if CH_USE_EVENTS #if CH_USE_EVENTS
eventmask_t p_ewmask; /**< Enabled events mask (@p PRWTOREVT eventmask_t ewmask; /**< Enabled events mask
or @p PRWTANDEVT states).*/ (@p THD_STATE_WTOREVT or
@p THD_STATE_WTANDEVT states). */
#endif #endif
}; } p_u; /**< State-specific fields. */
/*
* Start of the optional fields.
*/
#if CH_USE_WAITEXIT #if CH_USE_WAITEXIT
Thread *p_waiting; /**< Thread waiting for termination.*/ Thread *p_waiting; /**< Thread waiting for termination.*/
#endif #endif
#if CH_USE_MESSAGES #if CH_USE_MESSAGES
ThreadsQueue p_msgqueue; /**< Message queue.*/ ThreadsQueue p_msgqueue; /**< Messages queue. */
msg_t p_msg; /**< The message.*/ msg_t p_msg; /**< Thread message. */
#endif #endif
#if CH_USE_EVENTS #if CH_USE_EVENTS
eventmask_t p_epending; /**< Pending events mask.*/ eventmask_t p_epending; /**< Pending events mask. */
#endif #endif
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
Mutex *p_mtxlist; /**< List of the mutexes owned by this Mutex *p_mtxlist; /**< List of the mutexes owned by this
thread, @p NULL terminated.*/ thread, @p NULL terminated. */
tprio_t p_realprio; /**< Thread's own, non-inherited, tprio_t p_realprio; /**< Thread's own, non-inherited,
priority.*/ priority. */
#endif #endif
#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
void *p_mpool; /**< Memory Pool where the thread void *p_mpool; /**< Memory Pool where the thread
workspace is returned.*/ workspace is returned. */
#endif #endif
/* Extra fields defined in chconf.h */ /* Extra fields defined in chconf.h */
THREAD_EXT_FIELDS THREAD_EXT_FIELDS
}; };
/** Thread state: Ready to run, waiting on the ready list.*/ /** Thread state: Ready to run, waiting on the ready list.*/
#define PRREADY 0 #define THD_STATE_READY 0
/** Thread state: Currently running. */ /** Thread state: Currently running.*/
#define PRCURR 1 #define THD_STATE_CURRENT 1
/** Thread state: Thread created in suspended state. */ /** Thread state: Thread created in suspended state.*/
#define PRSUSPENDED 2 #define THD_STATE_SUSPENDED 2
/** Thread state: Waiting on a semaphore. */ /** Thread state: Waiting on a semaphore.*/
#define PRWTSEM 3 #define THD_STATE_WTSEM 3
/** Thread state: Waiting on a mutex. */ /** Thread state: Waiting on a mutex.*/
#define PRWTMTX 4 #define THD_STATE_WTMTX 4
/** Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil(). */ /** Thread state: Waiting in @p chCondWait().*/
#define PRWTCOND 5 #define THD_STATE_WTCOND 5
/** Thread state: Waiting in @p chCondWait(). */ /** Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/
#define PRSLEEP 6 #define THD_STATE_SLEEPING 6
/** Thread state: Waiting in @p chThdWait(). */ /** Thread state: Waiting in @p chThdWait().*/
#define PRWAIT 7 #define THD_STATE_WTEXIT 7
/** Thread state: Waiting in @p chEvtWaitOneTimeout() or /** Thread state: Waiting in @p chEvtWaitOneTimeout() or
@p chEvtWaitAnyTimeout(). */ @p chEvtWaitAnyTimeout().*/
#define PRWTOREVT 8 #define THD_STATE_WTOREVT 8
/** Thread state: Waiting in @p chEvtWaitAllTimeout(). */ /** Thread state: Waiting in @p chEvtWaitAllTimeout().*/
#define PRWTANDEVT 9 #define THD_STATE_WTANDEVT 9
/** Thread state: Waiting in @p chMsgSend(). */ /** Thread state: Waiting in @p chMsgSend().*/
#define PRSNDMSG 10 #define THD_STATE_SNDMSG 10
/** Thread state: Waiting in @p chMsgWait(). */ /** Thread state: Waiting in @p chMsgWait().*/
#define PRWTMSG 11 #define THD_STATE_WTMSG 11
/** Thread state: After termination.*/ /** Thread state: After termination.*/
#define PREXIT 12 #define THD_STATE_FINAL 12
/* /*
* Various flags into the thread p_flags field. * Various flags into the thread p_flags field.
*/ */
#define P_MEM_MODE_MASK 3 /* Thread memory mode mask. */ #define THD_MEM_MODE_MASK 3 /**< Thread memory mode mask. */
#define P_MEM_MODE_STATIC 0 /* Thread memory mode: static. */ #define THD_MEM_MODE_STATIC 0 /**< Thread memory mode: static.*/
#define P_MEM_MODE_HEAP 1 /* Thread memory mode: heap. */ #define THD_MEM_MODE_HEAP 1 /**< Thread memory mode: heap. */
#define P_MEM_MODE_MEMPOOL 2 /* Thread memory mode: mempool. */ #define THD_MEM_MODE_MEMPOOL 2 /**< Thread memory mode: pool. */
#define P_TERMINATE 4 /* Termination requested. */ #define THD_TERMINATE 4 /**< Termination requested. */
/* Not an API, don't use into the application code.*/ /* Not an API, don't use into the application code.*/
Thread *init_thread(Thread *tp, tprio_t prio); Thread *init_thread(Thread *tp, tprio_t prio);
@ -205,13 +181,13 @@ extern "C" {
#define chThdLS() (void *)(currp + 1) #define chThdLS() (void *)(currp + 1)
/** /**
* Verifies if the specified thread is in the @p PREXIT state. * Verifies if the specified thread is in the @p THD_STATE_FINAL state.
* *
* @param[in] tp the pointer to the thread * @param[in] tp the pointer to the thread
* @retval TRUE thread terminated. * @retval TRUE thread terminated.
* @retval FALSE thread not terminated. * @retval FALSE thread not terminated.
*/ */
#define chThdTerminated(tp) ((tp)->p_state == PREXIT) #define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL)
/** /**
* Verifies if the current thread has a termination request pending. * Verifies if the current thread has a termination request pending.
@ -219,7 +195,7 @@ extern "C" {
* @retval TRUE termination request pended. * @retval TRUE termination request pended.
* @retval FALSE termination request not pended. * @retval FALSE termination request not pended.
*/ */
#define chThdShouldTerminate() (currp->p_flags & P_TERMINATE) #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE)
/** /**
* Resumes a thread created with @p chThdInit(). * Resumes a thread created with @p chThdInit().
@ -240,7 +216,7 @@ extern "C" {
* specification. * specification.
* . * .
*/ */
#define chThdSleepS(time) chSchGoSleepTimeoutS(PRSLEEP, time) #define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time)
/** /**
* Delays the invoking thread for the specified number of seconds. * Delays the invoking thread for the specified number of seconds.

View File

@ -72,7 +72,7 @@ void chCondSignalI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondSignalI"); chDbgCheck(cp != NULL, "chCondSignalI");
if (notempty(&cp->c_queue)) /* any thread ? */ if (notempty(&cp->c_queue)) /* any thread ? */
chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK; chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK;
} }
/** /**
@ -97,11 +97,11 @@ void chCondBroadcastI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondBroadcastI"); chDbgCheck(cp != NULL, "chCondBroadcastI");
/* empties the condition variable queue and inserts all the Threads into the /* Empties the condition variable queue and inserts all the Threads into the
* ready list in FIFO order. The wakeup message is set to @p RDY_RESET in * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in
* order to make a chCondBroadcast() detectable from a chCondSignal(). */ * order to make a chCondBroadcast() detectable from a chCondSignal().*/
while (cp->c_queue.p_next != (void *)&cp->c_queue) while (cp->c_queue.p_next != (void *)&cp->c_queue)
chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_RESET; chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET;
} }
/** /**
@ -146,13 +146,13 @@ msg_t chCondWaitS(CondVar *cp) {
"chCondWaitS(), #1", "chCondWaitS(), #1",
"not owning a mutex"); "not owning a mutex");
mp = chMtxUnlockS(); /* unlocks the condvar mutex */ mp = chMtxUnlockS();
prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ prio_insert(currp, &cp->c_queue);
currp->p_wtcondp = cp; /* needed by the tracer */ currp->p_u.wtobjp = cp;
chSchGoSleepS(PRWTCOND); /* waits on the condvar */ chSchGoSleepS(THD_STATE_WTCOND);
msg = currp->p_rdymsg; /* fetches the wakeup message */ msg = currp->p_u.rdymsg;
chMtxLockS(mp); /* atomically relocks the mutex */ chMtxLockS(mp);
return msg; /* returns the wakeup message */ return msg;
} }
#if CH_USE_CONDVARS_TIMEOUT #if CH_USE_CONDVARS_TIMEOUT
@ -212,13 +212,13 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
"chCondWaitTimeoutS(), #1", "chCondWaitTimeoutS(), #1",
"not owning a mutex"); "not owning a mutex");
mp = chMtxUnlockS(); /* unlocks the condvar mutex */ mp = chMtxUnlockS();
prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ prio_insert(currp, &cp->c_queue);
currp->p_wtcondp = cp; /* needed by the tracer */ currp->p_u.wtobjp = cp;
chSchGoSleepTimeoutS(PRWTCOND, time); /* waits on the condvar */ chSchGoSleepTimeoutS(THD_STATE_WTCOND, time);
msg = currp->p_rdymsg; /* fetches the wakeup message */ msg = currp->p_u.rdymsg;
chMtxLockS(mp); /* atomically relocks the mutex */ chMtxLockS(mp);
return msg; /* returns the wakeup message */ return msg;
} }
#endif /* CH_USE_CONDVARS_TIMEOUT */ #endif /* CH_USE_CONDVARS_TIMEOUT */

View File

@ -137,9 +137,11 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) {
tp->p_epending |= mask; tp->p_epending |= mask;
/* Test on the AND/OR conditions wait states.*/ /* Test on the AND/OR conditions wait states.*/
if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) || if (((tp->p_state == THD_STATE_WTOREVT) &&
((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask))) ((tp->p_epending & tp->p_u.ewmask) != 0)) ||
chSchReadyI(tp)->p_rdymsg = RDY_OK; ((tp->p_state == THD_STATE_WTANDEVT) &&
((tp->p_epending & tp->p_u.ewmask) == tp->p_u.ewmask)))
chSchReadyI(tp)->p_u.rdymsg = RDY_OK;
} }
/** /**
@ -220,8 +222,8 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) {
chSysLock(); chSysLock();
if ((m = (currp->p_epending & ewmask)) == 0) { if ((m = (currp->p_epending & ewmask)) == 0) {
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
chSchGoSleepS(PRWTOREVT); chSchGoSleepS(THD_STATE_WTOREVT);
m = currp->p_epending & ewmask; m = currp->p_epending & ewmask;
} }
m &= -m; m &= -m;
@ -246,8 +248,8 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) {
chSysLock(); chSysLock();
if ((m = (currp->p_epending & ewmask)) == 0) { if ((m = (currp->p_epending & ewmask)) == 0) {
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
chSchGoSleepS(PRWTOREVT); chSchGoSleepS(THD_STATE_WTOREVT);
m = currp->p_epending & ewmask; m = currp->p_epending & ewmask;
} }
currp->p_epending &= ~m; currp->p_epending &= ~m;
@ -269,8 +271,8 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) {
chSysLock(); chSysLock();
if ((currp->p_epending & ewmask) != ewmask) { if ((currp->p_epending & ewmask) != ewmask) {
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
chSchGoSleepS(PRWTANDEVT); chSchGoSleepS(THD_STATE_WTANDEVT);
} }
currp->p_epending &= ~ewmask; currp->p_epending &= ~ewmask;
@ -308,8 +310,8 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) {
if ((m = (currp->p_epending & ewmask)) == 0) { if ((m = (currp->p_epending & ewmask)) == 0) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
m = currp->p_epending & ewmask; m = currp->p_epending & ewmask;
} }
@ -344,8 +346,8 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) {
if ((m = (currp->p_epending & ewmask)) == 0) { if ((m = (currp->p_epending & ewmask)) == 0) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
m = currp->p_epending & ewmask; m = currp->p_epending & ewmask;
} }
@ -376,8 +378,8 @@ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) {
if ((currp->p_epending & ewmask) != ewmask) { if ((currp->p_epending & ewmask) != ewmask) {
if (TIME_IMMEDIATE == time) if (TIME_IMMEDIATE == time)
return (eventmask_t)0; return (eventmask_t)0;
currp->p_ewmask = ewmask; currp->p_u.ewmask = ewmask;
if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK)
return (eventmask_t)0; return (eventmask_t)0;
} }
currp->p_epending &= ~ewmask; currp->p_epending &= ~ewmask;

View File

@ -50,11 +50,11 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
chSysLock(); chSysLock();
msg_insert(currp, &tp->p_msgqueue); msg_insert(currp, &tp->p_msgqueue);
currp->p_msg = msg; currp->p_msg = msg;
currp->p_wtthdp = tp; currp->p_u.wtobjp = tp;
if (tp->p_state == PRWTMSG) if (tp->p_state == THD_STATE_WTMSG)
chSchReadyI(tp); chSchReadyI(tp);
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(THD_STATE_SNDMSG);
msg = currp->p_rdymsg; msg = currp->p_u.rdymsg;
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -73,7 +73,7 @@ msg_t chMsgWait(void) {
chSysLock(); chSysLock();
if (!chMsgIsPendingI(currp)) if (!chMsgIsPendingI(currp))
chSchGoSleepS(PRWTMSG); chSchGoSleepS(THD_STATE_WTMSG);
msg = chMsgGetI(currp); msg = chMsgGetI(currp);
chSysUnlock(); chSysUnlock();
return msg; return msg;

View File

@ -86,31 +86,31 @@ void chMtxLockS(Mutex *mp) {
* The following states need priority queues reordering. * The following states need priority queues reordering.
*/ */
switch (tp->p_state) { switch (tp->p_state) {
case PRWTMTX: case THD_STATE_WTMTX:
/* Re-enqueues tp with its new priority on the mutex wait queue.*/ /* Re-enqueues tp with its new priority on the mutex wait queue.*/
prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp);
/* Boost the owner of this mutex if needed.*/ /* Boost the owner of this mutex if needed.*/
tp = tp->p_wtmtxp->m_owner; tp = ((Mutex *)tp->p_u.wtobjp)->m_owner;
continue; continue;
#if CH_USE_CONDVARS #if CH_USE_CONDVARS
case PRWTCOND: case THD_STATE_WTCOND:
/* Re-enqueues tp with its new priority on the condvar queue.*/ /* Re-enqueues tp with its new priority on the condvar queue.*/
prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp);
break; break;
#endif #endif
#if CH_USE_SEMAPHORES_PRIORITY #if CH_USE_SEMAPHORES_PRIORITY
case PRWTSEM: case THD_STATE_WTSEM:
/* Re-enqueues tp with its new priority on the semaphore queue.*/ /* Re-enqueues tp with its new priority on the semaphore queue.*/
prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp);
break; break;
#endif #endif
#if CH_USE_MESSAGES_PRIORITY #if CH_USE_MESSAGES_PRIORITY
case PRSNDMSG: case THD_STATE_SNDMSG:
/* Re-enqueues tp with its new priority on the server thread queue.*/ /* Re-enqueues tp with its new priority on the server thread queue.*/
prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); prio_insert(dequeue(tp), ((Thread *)tp->p_u.wtobjp)->p_msgqueue);
break; break;
#endif #endif
case PRREADY: case THD_STATE_READY:
/* Re-enqueues tp with its new priority on the ready list.*/ /* Re-enqueues tp with its new priority on the ready list.*/
chSchReadyI(dequeue(tp)); chSchReadyI(dequeue(tp));
} }
@ -118,8 +118,8 @@ void chMtxLockS(Mutex *mp) {
} }
/* Sleep on the mutex.*/ /* Sleep on the mutex.*/
prio_insert(currp, &mp->m_queue); prio_insert(currp, &mp->m_queue);
currp->p_wtmtxp = mp; currp->p_u.wtobjp = mp;
chSchGoSleepS(PRWTMTX); chSchGoSleepS(THD_STATE_WTMTX);
chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned");
} }
/* /*

View File

@ -60,7 +60,7 @@ Thread *chSchReadyI(Thread *tp) {
#endif #endif
Thread *cp; Thread *cp;
tp->p_state = PRREADY; tp->p_state = THD_STATE_READY;
cp = (Thread *)&rlist.r_queue; cp = (Thread *)&rlist.r_queue;
do { do {
cp = cp->p_next; cp = cp->p_next;
@ -82,7 +82,7 @@ void chSchGoSleepS(tstate_t newstate) {
Thread *otp; Thread *otp;
(otp = currp)->p_state = newstate; (otp = currp)->p_state = newstate;
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT;
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM; rlist.r_preempt = CH_TIME_QUANTUM;
#endif #endif
@ -99,21 +99,21 @@ static void wakeup(void *p) {
#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS #if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS
switch (tp->p_state) { switch (tp->p_state) {
#if CH_USE_SEMAPHORES #if CH_USE_SEMAPHORES
case PRWTSEM: case THD_STATE_WTSEM:
chSemFastSignalI(tp->p_wtsemp); chSemFastSignalI((Semaphore *)tp->p_u.wtobjp);
/* Falls into, intentional. */ /* Falls into, intentional. */
#endif #endif
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
case PRWTMTX: case THD_STATE_WTMTX:
#endif #endif
#if CH_USE_CONDVARS #if CH_USE_CONDVARS
case PRWTCOND: case THD_STATE_WTCOND:
#endif #endif
/* States requiring dequeuing.*/ /* States requiring dequeuing.*/
dequeue(tp); dequeue(tp);
} }
#endif #endif
chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT; chSchReadyI(tp)->p_u.rdymsg = RDY_TIMEOUT;
} }
/** /**
@ -149,7 +149,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
} }
else else
chSchGoSleepS(newstate); chSchGoSleepS(newstate);
return currp->p_rdymsg; return currp->p_u.rdymsg;
} }
/** /**
@ -166,7 +166,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
*/ */
void chSchWakeupS(Thread *ntp, msg_t msg) { void chSchWakeupS(Thread *ntp, msg_t msg) {
ntp->p_rdymsg = msg; ntp->p_u.rdymsg = msg;
/* If the waken thread has a not-greater priority than the current /* If the waken thread has a not-greater priority than the current
* one then it is just inserted in the ready list else it made * one then it is just inserted in the ready list else it made
* running immediately and the invoking thread goes in the ready * running immediately and the invoking thread goes in the ready
@ -179,7 +179,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) {
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM; rlist.r_preempt = CH_TIME_QUANTUM;
#endif #endif
(currp = ntp)->p_state = PRCURR; (currp = ntp)->p_state = THD_STATE_CURRENT;
chDbgTrace(otp, ntp); chDbgTrace(otp, ntp);
chSysSwitchI(otp, ntp); chSysSwitchI(otp, ntp);
} }
@ -195,7 +195,7 @@ void chSchDoRescheduleI(void) {
Thread *otp = currp; Thread *otp = currp;
/* Pick the first thread from the ready queue and makes it current.*/ /* Pick the first thread from the ready queue and makes it current.*/
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT;
chSchReadyI(otp); chSchReadyI(otp);
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM; rlist.r_preempt = CH_TIME_QUANTUM;
@ -258,7 +258,7 @@ void chSchDoYieldS(void) {
* ready list there is at least one thread with priority equal or higher * ready list there is at least one thread with priority equal or higher
* than the current one. * than the current one.
*/ */
otp->p_state = PRREADY; otp->p_state = THD_STATE_READY;
do { do {
cp = cp->p_prev; cp = cp->p_prev;
} while (cp->p_prio < otp->p_prio); } while (cp->p_prio < otp->p_prio);
@ -267,7 +267,7 @@ void chSchDoYieldS(void) {
otp->p_next->p_prev = cp->p_next = otp; otp->p_next->p_prev = cp->p_next = otp;
/* Pick the first thread from the ready queue and makes it current.*/ /* Pick the first thread from the ready queue and makes it current.*/
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT;
#if CH_TIME_QUANTUM > 0 #if CH_TIME_QUANTUM > 0
rlist.r_preempt = CH_TIME_QUANTUM; rlist.r_preempt = CH_TIME_QUANTUM;
#endif #endif

View File

@ -86,7 +86,7 @@ void chSemResetI(Semaphore *sp, cnt_t n) {
cnt = sp->s_cnt; cnt = sp->s_cnt;
sp->s_cnt = n; sp->s_cnt = n;
while (cnt++ < 0) while (cnt++ < 0)
chSchReadyI(lifo_remove(&sp->s_queue))->p_rdymsg = RDY_RESET; chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_RESET;
} }
/** /**
@ -120,9 +120,9 @@ msg_t chSemWaitS(Semaphore *sp) {
if (--sp->s_cnt < 0) { if (--sp->s_cnt < 0) {
sem_insert(currp, &sp->s_queue); sem_insert(currp, &sp->s_queue);
currp->p_wtsemp = sp; currp->p_u.wtobjp = sp;
chSchGoSleepS(PRWTSEM); chSchGoSleepS(THD_STATE_WTSEM);
return currp->p_rdymsg; return currp->p_u.rdymsg;
} }
return RDY_OK; return RDY_OK;
} }
@ -174,8 +174,8 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
return RDY_TIMEOUT; return RDY_TIMEOUT;
} }
sem_insert(currp, &sp->s_queue); sem_insert(currp, &sp->s_queue);
currp->p_wtsemp = sp; currp->p_u.wtobjp = sp;
return chSchGoSleepTimeoutS(PRWTSEM, time); return chSchGoSleepTimeoutS(THD_STATE_WTSEM, time);
} }
return RDY_OK; return RDY_OK;
} }
@ -213,7 +213,7 @@ void chSemSignalI(Semaphore *sp) {
/* NOTE: It is done this way in order to allow a tail call on /* NOTE: It is done this way in order to allow a tail call on
chSchReadyI().*/ chSchReadyI().*/
Thread *tp = fifo_remove(&sp->s_queue); Thread *tp = fifo_remove(&sp->s_queue);
tp->p_rdymsg = RDY_OK; tp->p_u.rdymsg = RDY_OK;
chSchReadyI(tp); chSchReadyI(tp);
} }
} }
@ -236,12 +236,12 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
chSysLock(); chSysLock();
if (sps->s_cnt++ < 0) if (sps->s_cnt++ < 0)
chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK; chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK;
if (--spw->s_cnt < 0) { if (--spw->s_cnt < 0) {
sem_insert(currp, &spw->s_queue); sem_insert(currp, &spw->s_queue);
currp->p_wtsemp = spw; currp->p_u.wtobjp = spw;
chSchGoSleepS(PRWTSEM); chSchGoSleepS(THD_STATE_WTSEM);
msg = currp->p_rdymsg; msg = currp->p_u.rdymsg;
} }
else { else {
chSchRescheduleS(); chSchRescheduleS();

View File

@ -75,7 +75,7 @@ void chSysInit(void) {
/* /*
* Now this instructions flow becomes the main thread. * Now this instructions flow becomes the main thread.
*/ */
(currp = init_thread(&mainthread, NORMALPRIO))->p_state = PRCURR; (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT;
chSysEnable(); chSysEnable();
/* /*

View File

@ -31,9 +31,9 @@
*/ */
Thread *init_thread(Thread *tp, tprio_t prio) { Thread *init_thread(Thread *tp, tprio_t prio) {
tp->p_flags = P_MEM_MODE_STATIC; tp->p_flags = THD_MEM_MODE_STATIC;
tp->p_prio = prio; tp->p_prio = prio;
tp->p_state = PRSUSPENDED; tp->p_state = THD_STATE_SUSPENDED;
#if CH_USE_NESTED_LOCKS #if CH_USE_NESTED_LOCKS
tp->p_locks = 0; tp->p_locks = 0;
#endif #endif
@ -69,7 +69,7 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
/** /**
* @brief Initializes a new thread. * @brief Initializes a new thread.
* @details The new thread is initialized but not inserted in the ready list, * @details The new thread is initialized but not inserted in the ready list,
* the initial state is @p PRSUSPENDED. * the initial state is @p THD_STATE_SUSPENDED.
* *
* @param[out] wsp pointer to a working area dedicated to the thread stack * @param[out] wsp pointer to a working area dedicated to the thread stack
* @param[in] size size of the working area * @param[in] size size of the working area
@ -150,7 +150,7 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
if (wsp == NULL) if (wsp == NULL)
return NULL; return NULL;
tp = chThdInit(wsp, size, prio, pf, arg); tp = chThdInit(wsp, size, prio, pf, arg);
tp->p_flags = P_MEM_MODE_HEAP; tp->p_flags = THD_MEM_MODE_HEAP;
return chThdResume(tp); return chThdResume(tp);
} }
#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */ #endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */
@ -187,7 +187,7 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
if (wsp == NULL) if (wsp == NULL)
return NULL; return NULL;
tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg);
tp->p_flags = P_MEM_MODE_MEMPOOL; tp->p_flags = THD_MEM_MODE_MEMPOOL;
tp->p_mpool = mp; tp->p_mpool = mp;
return chThdResume(tp); return chThdResume(tp);
} }
@ -235,9 +235,9 @@ tprio_t chThdSetPriority(tprio_t newprio) {
Thread *chThdResume(Thread *tp) { Thread *chThdResume(Thread *tp) {
chSysLock(); chSysLock();
chDbgAssert(tp->p_state == PRSUSPENDED, chDbgAssert(tp->p_state == THD_STATE_SUSPENDED,
"chThdResume(), #1", "chThdResume(), #1",
"thread not in PRSUSPENDED state"); "thread not in THD_STATE_SUSPENDED state");
chSchWakeupS(tp, RDY_OK); chSchWakeupS(tp, RDY_OK);
chSysUnlock(); chSysUnlock();
return tp; return tp;
@ -254,7 +254,7 @@ Thread *chThdResume(Thread *tp) {
void chThdTerminate(Thread *tp) { void chThdTerminate(Thread *tp) {
chSysLock(); chSysLock();
tp->p_flags |= P_TERMINATE; tp->p_flags |= THD_TERMINATE;
chSysUnlock(); chSysUnlock();
} }
@ -315,13 +315,13 @@ void chThdExit(msg_t msg) {
Thread *tp = currp; Thread *tp = currp;
chSysLock(); chSysLock();
tp->p_exitcode = msg; tp->p_u.exitcode = msg;
THREAD_EXT_EXIT(tp); THREAD_EXT_EXIT(tp);
#if CH_USE_WAITEXIT #if CH_USE_WAITEXIT
if (tp->p_waiting != NULL) if (tp->p_waiting != NULL)
chSchReadyI(tp->p_waiting); chSchReadyI(tp->p_waiting);
#endif #endif
chSchGoSleepS(PREXIT); chSchGoSleepS(THD_STATE_FINAL);
} }
#if CH_USE_WAITEXIT #if CH_USE_WAITEXIT
@ -362,28 +362,28 @@ msg_t chThdWait(Thread *tp) {
chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self");
chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting"); chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting");
if (tp->p_state != PREXIT) { if (tp->p_state != THD_STATE_FINAL) {
tp->p_waiting = currp; tp->p_waiting = currp;
chSchGoSleepS(PRWAIT); chSchGoSleepS(THD_STATE_WTEXIT);
} }
msg = tp->p_exitcode; msg = tp->p_u.exitcode;
#if !CH_USE_DYNAMIC #if !CH_USE_DYNAMIC
chSysUnlock(); chSysUnlock();
return msg; return msg;
#else /* CH_USE_DYNAMIC */ #else /* CH_USE_DYNAMIC */
/* Returning memory.*/ /* Returning memory.*/
tmode_t mode = tp->p_flags & P_MEM_MODE_MASK; tmode_t mode = tp->p_flags & THD_MEM_MODE_MASK;
chSysUnlock(); chSysUnlock();
switch (mode) { switch (mode) {
#if CH_USE_HEAP #if CH_USE_HEAP
case P_MEM_MODE_HEAP: case THD_MEM_MODE_HEAP:
chHeapFree(tp); chHeapFree(tp);
break; break;
#endif #endif
#if CH_USE_MEMPOOLS #if CH_USE_MEMPOOLS
case P_MEM_MODE_MEMPOOL: case THD_MEM_MODE_MEMPOOL:
chPoolFree(tp->p_mpool, tp); chPoolFree(tp->p_mpool, tp);
break; break;
#endif #endif

View File

@ -52,8 +52,13 @@
***************************************************************************** *****************************************************************************
*** 1.5.0 *** *** 1.5.0 ***
- FIX: Fixed parameter check in sdStart() function (bug 2932922). - FIX: Fixed parameter check in sdStart() function (bug 2932922)(backported in
- FIX: Fixed missing platform.mk file in MSP430 port (bug 2933735). 1.4.0).
- FIX: Fixed missing platform.mk file in MSP430 port (bug 2933735)(backported
in 1.4.0).
- CHANGE: Removed the unnamed union from the Thread structure some compilers
do not support this non standard construct.
- CHANGE: Modified the thread-related constant macros to have a THD_ prefix.
*** 1.3.8 *** *** 1.3.8 ***
- FIX: Fixed dequeuing in lifo_remove() function (bug 2928142). - FIX: Fixed dequeuing in lifo_remove() function (bug 2928142).

View File

@ -226,8 +226,8 @@ msg_t thread4(void *p) {
(void)p; (void)p;
chSysLock(); chSysLock();
do { do {
chSchGoSleepS(PRSUSPENDED); chSchGoSleepS(THD_STATE_SUSPENDED);
msg = self->p_rdymsg; msg = self->p_u.rdymsg;
} while (msg == RDY_OK); } while (msg == RDY_OK);
chSysUnlock(); chSysUnlock();
return 0; return 0;

View File

@ -4,30 +4,22 @@ Status:
X = In progress, some work done. X = In progress, some work done.
* = Done. * = Done.
Before 1.4.0: Before 1.6.0:
* Abstract streams interface (for MAC, USB endpoints, files, sockets etc). * Remove instances of unnamed structures/unions.
* Abstract I/O channels rather than just serial ports. - Active threads registry in the kernel.
* Add tests documentation to the general documentation via doxygen. - Debug-related features and tools.
* Static object initializers.
* Add a central memory manager offering a sbrk()-like API.
* Make the heap allocator feed memory chunks from the memory manager.
* Dedicated syscalls.c support for newlib users.
* HAL and common device drivers.
* Multiple heaps, disjoint heaps, heaps in heaps.
After 1.4.x
- I2C device driver class support. - I2C device driver class support.
- USB device support. - USB device driver class support.
- MAC driver revision in order to support copy-less operations, this will - MAC driver revision in order to support copy-less operations, this will
require changes to lwIP or a new TCP/IP stack however. require changes to lwIP or a new TCP/IP stack however.
- Objects registry in the kernel. - More code examples into the documentation.
- OSEK-style simple tasks within the idle thread.
- Code examples into the documentation.
- Update C++ wrapper (Heap, Pools, Mailboxes and any new feature). - Update C++ wrapper (Heap, Pools, Mailboxes and any new feature).
- Threads Pools manager in the library. - Threads Pools manager in the library.
? OSEK-style simple tasks within the idle thread.
After 1.6.0
? Minimal optional C-runtime library (complete enough for lwIP). ? Minimal optional C-runtime library (complete enough for lwIP).
? Think to something for threads restart. ? Think to something for threads restart.
? Remove any instance of unnamed structures/unions.
Ideas for 2.x.x: Ideas for 2.x.x:
- High resolution timers and tickless kernel. - High resolution timers and tickless kernel.