More queues reorganization.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13963 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2020-12-19 09:24:14 +00:00
parent be8557f2cb
commit fb5e29f1c8
12 changed files with 217 additions and 135 deletions

View File

@ -131,7 +131,7 @@ extern "C" {
/** /**
* @brief List initialization. * @brief List initialization.
* *
* @param[in] lp pointer to the list header * @param[out] lp pointer to the list header
* *
* @notapi * @notapi
*/ */
@ -200,7 +200,7 @@ static inline ch_list_t *ch_list_pop(ch_list_t *lp) {
/** /**
* @brief Queue initialization. * @brief Queue initialization.
* *
* @param[in] qp pointer to the queue header * @param[out] qp pointer to the queue header
* *
* @notapi * @notapi
*/ */
@ -239,7 +239,7 @@ static inline bool ch_queue_notempty(const ch_queue_t *qp) {
/** /**
* @brief Inserts an element into a queue. * @brief Inserts an element into a queue.
* *
* @param[in] p the pointer to the element to be inserted in the list * @param[in] p the pointer to the element to be inserted in the queue
* @param[in] qp the pointer to the queue header * @param[in] qp the pointer to the queue header
* *
* @notapi * @notapi
@ -257,7 +257,7 @@ static inline void ch_queue_insert(ch_queue_t *p, ch_queue_t *qp) {
* @note If the queue is priority ordered then this function returns the * @note If the queue is priority ordered then this function returns the
* element with the highest priority. * element with the highest priority.
* *
* @param[in] tqp the pointer to the queue list header * @param[in] qp the pointer to the queue list header
* @return The removed element pointer. * @return The removed element pointer.
* *
* @notapi * @notapi
@ -265,7 +265,7 @@ static inline void ch_queue_insert(ch_queue_t *p, ch_queue_t *qp) {
static inline ch_queue_t *ch_queue_fifo_remove(ch_queue_t *qp) { static inline ch_queue_t *ch_queue_fifo_remove(ch_queue_t *qp) {
ch_queue_t *p = qp->next; ch_queue_t *p = qp->next;
qp->next = p->next; qp->next = p->next;
qp->next->prev = qp; qp->next->prev = qp;
return p; return p;
@ -276,7 +276,7 @@ static inline ch_queue_t *ch_queue_fifo_remove(ch_queue_t *qp) {
* @note If the queue is priority ordered then this function returns the * @note If the queue is priority ordered then this function returns the
* element with the lowest priority. * element with the lowest priority.
* *
* @param[in] tqp the pointer to the queue list header * @param[in] qp the pointer to the queue list header
* @return The removed element pointer. * @return The removed element pointer.
* *
* @notapi * @notapi
@ -295,7 +295,7 @@ static inline ch_queue_t *ch_queue_lifo_remove(ch_queue_t *qp) {
* @details The element is removed from the queue regardless of its relative * @details The element is removed from the queue regardless of its relative
* position and regardless the used insertion method. * position and regardless the used insertion method.
* *
* @param[in] tp the pointer to the element to be removed from the queue * @param[in] p the pointer to the element to be removed from the queue
* @return The removed element pointer. * @return The removed element pointer.
* *
* @notapi * @notapi
@ -308,6 +308,99 @@ static inline ch_queue_t *ch_queue_dequeue(ch_queue_t *p) {
return p; return p;
} }
/**
* @brief Priority queue initialization.
* @note The queue header priority is initialized to zero, all other
* elements in the queue are assumed to have priority greater
* than zero.
*
* @param[out] pqp pointer to the priority queue header
*
* @notapi
*/
static inline void ch_pqueue_init(ch_priority_queue_t *pqp) {
pqp->next = pqp;
pqp->prev = pqp;
pqp->prio = (tprio_t)0;
}
/**
* @brief Removes the highest priority element from a priority queue and
* returns it.
*
* @param[in] pqp the pointer to the priority queue list header
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_remove_highest(ch_priority_queue_t *pqp) {
ch_priority_queue_t *p = pqp->next;
pqp->next = p->next;
pqp->next->prev = pqp;
return p;
}
/**
* @brief Inserts an element in the priority queue placing it behind
* its peers.
* @details The element is positioned behind all elements with higher or
* equal priority.
*
* @param[in] pqp the pointer to the priority queue list header
* @param[in] p the pointer to the element to be inserted in the queue
* @return The inserted element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_insert_behind(ch_priority_queue_t *pqp,
ch_priority_queue_t *p) {
/* Scanning priority queue.*/
do {
pqp = pqp->next;
} while (pqp->prio >= p->prio);
/* Insertion on prev.*/
p->next = pqp;
p->prev = pqp->prev;
p->prev->next = p;
pqp->prev = p;
return p;
}
/**
* @brief Inserts an element in the priority queue placing it ahead of
* its peers.
* @details The element is positioned ahead of all elements with higher or
* equal priority.
*
* @param[in] pqp the pointer to the priority queue list header
* @param[in] p the pointer to the element to be inserted in the queue
* @return The inserted element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_insert_ahead(ch_priority_queue_t *pqp,
ch_priority_queue_t *p) {
/* Scanning priority queue.*/
do {
pqp = pqp->next;
} while (pqp->prio > p->prio);
/* Insertion on prev.*/
p->next = pqp;
p->prev = pqp->prev;
p->prev->next = p;
pqp->prev = p;
return p;
}
#endif /* CHLISTS_H */ #endif /* CHLISTS_H */
/** @} */ /** @} */

View File

@ -117,10 +117,11 @@ typedef struct ch_threads_queue {
*/ */
struct ch_thread { struct ch_thread {
union { union {
ch_list_t list; /**< @brief Threads list header. */ ch_list_t list; /**< @brief Threads lists element. */
ch_queue_t queue; /**< @brief Threads queue header. */ ch_queue_t queue; /**< @brief Threads queues element. */
ch_priority_queue_t pqueue; /**< @brief Threads ordered queues
element. */
} hdr; } hdr;
tprio_t prio; /**< @brief Thread priority. */
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
thread_t *newer; /**< @brief Newer registry element. */ thread_t *newer; /**< @brief Newer registry element. */
thread_t *older; /**< @brief Older registry element. */ thread_t *older; /**< @brief Older registry element. */
@ -293,16 +294,26 @@ struct ch_thread {
* @brief Type of a ready list header. * @brief Type of a ready list header.
*/ */
typedef struct ch_ready_list { typedef struct ch_ready_list {
ch_queue_t queue; /**< @brief Threads queue. */ /**
tprio_t prio; /**< @brief This field must be * @brief Threads ordered queues header.
initialized to zero. */ * @note The priority field must be initialized to zero.
*/
ch_priority_queue_t pqueue;
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
thread_t *newer; /**< @brief Newer registry element. */ /**
thread_t *older; /**< @brief Older registry element. */ * @brief Newer registry element.
*/
thread_t *newer;
/**
* @brief Older registry element.
*/
thread_t *older;
#endif #endif
/* End of the fields shared with the thread_t structure.*/ /* End of the fields shared with the thread_t structure.*/
thread_t *current; /**< @brief The currently running /**
thread. */ * @brief The currently running thread.
*/
thread_t *current;
} ready_list_t; } ready_list_t;
/** /**

View File

@ -127,7 +127,7 @@
* *
* @notapi * @notapi
*/ */
#define firstprio(rlp) (((thread_t *)(rlp)->next)->prio) #define firstprio(rlp) ((rlp)->next->prio)
/** /**
* @brief Current thread pointer get macro. * @brief Current thread pointer get macro.
@ -164,13 +164,7 @@ extern "C" {
void chSchDoYieldS(void); void chSchDoYieldS(void);
thread_t *chSchSelectFirstI(void); thread_t *chSchSelectFirstI(void);
#if CH_CFG_OPTIMIZE_SPEED == FALSE #if CH_CFG_OPTIMIZE_SPEED == FALSE
void queue_prio_insert(thread_t *tp, threads_queue_t *tqp); void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp);
void queue_insert(thread_t *tp, threads_queue_t *tqp);
thread_t *queue_fifo_remove(threads_queue_t *tqp);
thread_t *queue_lifo_remove(threads_queue_t *tqp);
thread_t *queue_dequeue(thread_t *tp);
void list_insert(thread_t *tp, threads_list_t *tlp);
thread_t *list_remove(threads_list_t *tlp);
#endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */ #endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -183,16 +177,17 @@ extern "C" {
/* If the performance code path has been chosen then all the following /* If the performance code path has been chosen then all the following
functions are inlined into the various kernel modules.*/ functions are inlined into the various kernel modules.*/
#if CH_CFG_OPTIMIZE_SPEED == TRUE #if CH_CFG_OPTIMIZE_SPEED == TRUE
static inline void queue_prio_insert(thread_t *tp, ch_queue_t *tqp) { static inline void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp) {
thread_t *cp = (thread_t *)tqp; ch_queue_t *cp = qp;
do { do {
cp = (thread_t *)cp->hdr.queue.next; cp = cp->next;
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio)); } while ((cp != qp) &&
tp->hdr.queue.next = (ch_queue_t *)cp; (((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
tp->hdr.queue.prev = cp->hdr.queue.prev; tp->next = cp;
tp->hdr.queue.prev->next = (ch_queue_t *)tp; tp->prev = cp->prev;
cp->hdr.queue.prev = (ch_queue_t *)tp; tp->prev->next = tp;
cp->prev = tp;
} }
#endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */ #endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */

View File

@ -384,8 +384,8 @@ static inline void chSysUnlock(void) {
in a critical section not followed by a chSchRescheduleS(), this means in a critical section not followed by a chSchRescheduleS(), this means
that the current thread has a lower priority than the next thread in that the current thread has a lower priority than the next thread in
the ready list.*/ the ready list.*/
chDbgAssert((currcore->rlist.queue.next == &currcore->rlist.queue) || chDbgAssert((currcore->rlist.pqueue.next == &currcore->rlist.pqueue) ||
(currcore->rlist.current->prio >= ((thread_t *)currcore->rlist.queue.next)->prio), (currcore->rlist.current->hdr.pqueue.prio >= currcore->rlist.pqueue.next->prio),
"priority order violation"); "priority order violation");
port_unlock(); port_unlock();
@ -477,7 +477,7 @@ static inline void chSysUnconditionalUnlock(void) {
*/ */
static inline thread_t *chSysGetIdleThreadX(void) { static inline thread_t *chSysGetIdleThreadX(void) {
return (thread_t *)currcore->rlist.queue.prev; return (thread_t *)currcore->rlist.pqueue.prev;
} }
#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */ #endif /* CH_CFG_NO_IDLE_THREAD == FALSE */

View File

@ -287,7 +287,7 @@ static inline thread_t *chThdGetSelfX(void) {
*/ */
static inline tprio_t chThdGetPriorityX(void) { static inline tprio_t chThdGetPriorityX(void) {
return chThdGetSelfX()->prio; return chThdGetSelfX()->hdr.pqueue.prio;
} }
/** /**

View File

@ -217,7 +217,7 @@ msg_t chCondWaitS(condition_variable_t *cp) {
/* Start waiting on the condition variable, on exit the mutex is taken /* Start waiting on the condition variable, on exit the mutex is taken
again.*/ again.*/
currtp->u.wtobjp = cp; currtp->u.wtobjp = cp;
queue_prio_insert(currtp, &cp->queue); ch_sch_prio_insert(&currtp->hdr.queue, &cp->queue);
chSchGoSleepS(CH_STATE_WTCOND); chSchGoSleepS(CH_STATE_WTCOND);
msg = currtp->u.rdymsg; msg = currtp->u.rdymsg;
chMtxLockS(mp); chMtxLockS(mp);
@ -307,7 +307,7 @@ msg_t chCondWaitTimeoutS(condition_variable_t *cp, sysinterval_t timeout) {
/* Start waiting on the condition variable, on exit the mutex is taken /* Start waiting on the condition variable, on exit the mutex is taken
again.*/ again.*/
currtp->u.wtobjp = cp; currtp->u.wtobjp = cp;
queue_prio_insert(currtp, &cp->queue); ch_sch_prio_insert(&currtp->hdr.queue, &cp->queue);
msg = chSchGoSleepTimeoutS(CH_STATE_WTCOND, timeout); msg = chSchGoSleepTimeoutS(CH_STATE_WTCOND, timeout);
if (msg != MSG_TIMEOUT) { if (msg != MSG_TIMEOUT) {
chMtxLockS(mp); chMtxLockS(mp);

View File

@ -162,16 +162,16 @@ void chMtxLockS(mutex_t *mp) {
/* Does the running thread have higher priority than the mutex /* Does the running thread have higher priority than the mutex
owning thread? */ owning thread? */
while (tp->prio < currtp->prio) { while (tp->hdr.pqueue.prio < currtp->hdr.pqueue.prio) {
/* Make priority of thread tp match the running thread's priority.*/ /* Make priority of thread tp match the running thread's priority.*/
tp->prio = currtp->prio; tp->hdr.pqueue.prio = currtp->hdr.pqueue.prio;
/* The following states need priority queues reordering.*/ /* The following states need priority queues reordering.*/
switch (tp->state) { switch (tp->state) {
case CH_STATE_WTMTX: case CH_STATE_WTMTX:
/* Re-enqueues the mutex owner with its new priority.*/ /* Re-enqueues the mutex owner with its new priority.*/
queue_prio_insert((thread_t *)ch_queue_dequeue(&tp->hdr.queue), ch_sch_prio_insert(ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue); &tp->u.wtmtxp->queue);
tp = tp->u.wtmtxp->owner; tp = tp->u.wtmtxp->owner;
/*lint -e{9042} [16.1] Continues the while.*/ /*lint -e{9042} [16.1] Continues the while.*/
continue; continue;
@ -191,8 +191,8 @@ void chMtxLockS(mutex_t *mp) {
case CH_STATE_SNDMSGQ: case CH_STATE_SNDMSGQ:
#endif #endif
/* Re-enqueues tp with its new priority on the queue.*/ /* Re-enqueues tp with its new priority on the queue.*/
queue_prio_insert((thread_t *)ch_queue_dequeue(&tp->hdr.queue), ch_sch_prio_insert(ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue); &tp->u.wtmtxp->queue);
break; break;
#endif #endif
case CH_STATE_READY: case CH_STATE_READY:
@ -211,7 +211,7 @@ void chMtxLockS(mutex_t *mp) {
} }
/* Sleep on the mutex.*/ /* Sleep on the mutex.*/
queue_prio_insert(currtp, &mp->queue); ch_sch_prio_insert(&currtp->hdr.queue, &mp->queue);
currtp->u.wtmtxp = mp; currtp->u.wtmtxp = mp;
chSchGoSleepS(CH_STATE_WTMTX); chSchGoSleepS(CH_STATE_WTMTX);
@ -359,15 +359,15 @@ void chMtxUnlock(mutex_t *mp) {
greater priority than the current thread base priority then the greater priority than the current thread base priority then the
final priority will have at least that priority.*/ final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) && if (chMtxQueueNotEmptyS(lmp) &&
(((thread_t *)lmp->queue.next)->prio > newprio)) { (((thread_t *)lmp->queue.next)->hdr.pqueue.prio > newprio)) {
newprio = ((thread_t *)lmp->queue.next)->prio; newprio = ((thread_t *)lmp->queue.next)->hdr.pqueue.prio;
} }
lmp = lmp->next; lmp = lmp->next;
} }
/* Assigns to the current thread the highest priority among all the /* Assigns to the current thread the highest priority among all the
waiting threads.*/ waiting threads.*/
currtp->prio = newprio; currtp->hdr.pqueue.prio = newprio;
/* Awakens the highest priority thread waiting for the unlocked mutex and /* Awakens the highest priority thread waiting for the unlocked mutex and
assigns the mutex to it.*/ assigns the mutex to it.*/
@ -445,15 +445,15 @@ void chMtxUnlockS(mutex_t *mp) {
greater priority than the current thread base priority then the greater priority than the current thread base priority then the
final priority will have at least that priority.*/ final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) && if (chMtxQueueNotEmptyS(lmp) &&
(((thread_t *)lmp->queue.next)->prio > newprio)) { (((thread_t *)lmp->queue.next)->hdr.pqueue.prio > newprio)) {
newprio = ((thread_t *)lmp->queue.next)->prio; newprio = ((thread_t *)lmp->queue.next)->hdr.pqueue.prio;
} }
lmp = lmp->next; lmp = lmp->next;
} }
/* Assigns to the current thread the highest priority among all the /* Assigns to the current thread the highest priority among all the
waiting threads.*/ waiting threads.*/
currtp->prio = newprio; currtp->hdr.pqueue.prio = newprio;
/* Awakens the highest priority thread waiting for the unlocked mutex and /* Awakens the highest priority thread waiting for the unlocked mutex and
assigns the mutex to it.*/ assigns the mutex to it.*/
@ -512,7 +512,7 @@ void chMtxUnlockAllS(void) {
mp->owner = NULL; mp->owner = NULL;
} }
} while (currtp->mtxlist != NULL); } while (currtp->mtxlist != NULL);
currtp->prio = currtp->realprio; currtp->hdr.pqueue.prio = currtp->realprio;
chSchRescheduleS(); chSchRescheduleS();
} }
} }

View File

@ -90,7 +90,7 @@ ROMCONST chdebug_t ch_debug = {
(uint8_t)sizeof (void *), (uint8_t)sizeof (void *),
(uint8_t)sizeof (systime_t), (uint8_t)sizeof (systime_t),
(uint8_t)sizeof (thread_t), (uint8_t)sizeof (thread_t),
(uint8_t)_offsetof(thread_t, prio), (uint8_t)_offsetof(thread_t, hdr.pqueue.prio),
(uint8_t)_offsetof(thread_t, ctx), (uint8_t)_offsetof(thread_t, ctx),
(uint8_t)_offsetof(thread_t, newer), (uint8_t)_offsetof(thread_t, newer),
(uint8_t)_offsetof(thread_t, older), (uint8_t)_offsetof(thread_t, older),

View File

@ -90,8 +90,8 @@ static void __idle_thread(void *p) {
* *
* @notapi * @notapi
*/ */
__attribute__((noinline))
static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) { static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
ch_queue_t *cqp, *tqp;
chDbgAssert((tp->state != CH_STATE_READY) && chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL), (tp->state != CH_STATE_FINAL),
@ -100,21 +100,12 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
/* Tracing the event.*/ /* Tracing the event.*/
__trace_ready(tp, tp->u.rdymsg); __trace_ready(tp, tp->u.rdymsg);
/* Scanning ready list.*/ /* The thread is marked ready.*/
tp->state = CH_STATE_READY; tp->state = CH_STATE_READY;
tqp = &tp->hdr.queue;
cqp = &oip->rlist.queue;
do {
cqp = cqp->next;
} while (((thread_t *)cqp)->prio >= tp->prio);
/* Insertion on prev.*/ /* Insertion in the priority queue.*/
tqp->next = cqp; return (thread_t *)ch_pqueue_insert_behind(&oip->rlist.pqueue,
tqp->prev = cqp->prev; &tp->hdr.pqueue);
tqp->prev->next = &tp->hdr.queue;
cqp->prev = tqp;
return tp;
} }
/** /**
@ -134,8 +125,8 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
* *
* @notapi * @notapi
*/ */
__attribute__((noinline))
static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) { static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
ch_queue_t *cqp, *tqp;
chDbgAssert((tp->state != CH_STATE_READY) && chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL), (tp->state != CH_STATE_FINAL),
@ -144,21 +135,12 @@ static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
/* Tracing the event.*/ /* Tracing the event.*/
__trace_ready(tp, tp->u.rdymsg); __trace_ready(tp, tp->u.rdymsg);
/* Scanning ready list.*/ /* The thread is marked ready.*/
tp->state = CH_STATE_READY; tp->state = CH_STATE_READY;
tqp = &tp->hdr.queue;
cqp = &oip->rlist.queue;
do {
cqp = cqp->next;
} while (((thread_t *)cqp)->prio > tp->prio);
/* Insertion on prev.*/ /* Insertion in the priority queue.*/
tqp->next = cqp; return (thread_t *)ch_pqueue_insert_ahead(&oip->rlist.pqueue,
tqp->prev = cqp->prev; &tp->hdr.pqueue);
tqp->prev->next = tqp;
cqp->prev = tqp;
return tp;
} }
/** /**
@ -178,12 +160,12 @@ static void __sch_reschedule_behind(os_instance_t *oip) {
thread_t *ntp; thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue); ntp = (thread_t *)ch_pqueue_remove_highest(&oip->rlist.pqueue);
ntp->state = CH_STATE_CURRENT; ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp); __sch_set_currthread(oip, ntp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -215,12 +197,12 @@ static void __sch_reschedule_ahead(os_instance_t *oip) {
thread_t *ntp; thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue); ntp = (thread_t *)ch_pqueue_remove_highest(&oip->rlist.pqueue);
ntp->state = CH_STATE_CURRENT; ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp); __sch_set_currthread(oip, ntp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -288,16 +270,17 @@ static void __sch_wakeup(void *p) {
* *
* @notapi * @notapi
*/ */
void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) { void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp) {
thread_t *cp = (thread_t *)tqp; ch_queue_t *cp = qp;
do { do {
cp = cp->queue.next; cp = cp->next;
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio)); } while ((cp != qp) &&
tp->queue.next = cp; (((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
tp->queue.prev = cp->queue.prev; tp->next = cp;
tp->queue.prev->queue.next = tp; tp->prev = cp->prev;
cp->queue.prev = tp; tp->prev->next = tp;
cp->prev = tp;
} }
#endif /* CH_CFG_OPTIMIZE_SPEED */ #endif /* CH_CFG_OPTIMIZE_SPEED */
@ -317,8 +300,7 @@ void chSchObjectInit(os_instance_t *oip,
port_init(oip); port_init(oip);
/* Ready list initialization.*/ /* Ready list initialization.*/
ch_queue_init(&oip->rlist.queue); ch_pqueue_init(&oip->rlist.pqueue);
oip->rlist.prio = NOPRIO;
/* Registry initialization.*/ /* Registry initialization.*/
#if CH_CFG_USE_REGISTRY == TRUE #if CH_CFG_USE_REGISTRY == TRUE
@ -443,12 +425,12 @@ void chSchGoSleepS(tstate_t newstate) {
#endif #endif
/* Next thread in ready list becomes current.*/ /* Next thread in ready list becomes current.*/
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue); ntp = (thread_t *)ch_pqueue_remove_highest(&oip->rlist.pqueue);
ntp->state = CH_STATE_CURRENT; ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp); __sch_set_currthread(oip, ntp);
/* Handling idle-enter hook.*/ /* Handling idle-enter hook.*/
if (ntp->prio == IDLEPRIO) { if (ntp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_ENTER_HOOK(); CH_CFG_IDLE_ENTER_HOOK();
} }
@ -521,8 +503,8 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
chDbgCheckClassS(); chDbgCheckClassS();
chDbgAssert((oip->rlist.queue.next == &oip->rlist.queue) || chDbgAssert((oip->rlist.pqueue.next == &oip->rlist.pqueue) ||
(oip->rlist.current->prio >= ((thread_t *)oip->rlist.queue.next)->prio), (oip->rlist.current->hdr.pqueue.prio >= oip->rlist.pqueue.next->prio),
"priority order violation"); "priority order violation");
/* Storing the message to be retrieved by the target thread when it will /* Storing the message to be retrieved by the target thread when it will
@ -533,7 +515,7 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
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
list instead.*/ list instead.*/
if (ntp->prio <= otp->prio) { if (ntp->hdr.pqueue.prio <= otp->hdr.pqueue.prio) {
(void) __sch_ready_behind(oip, ntp); (void) __sch_ready_behind(oip, ntp);
} }
else { else {
@ -542,7 +524,7 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
otp = __sch_ready_ahead(oip, otp); otp = __sch_ready_ahead(oip, otp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -570,7 +552,7 @@ void chSchRescheduleS(void) {
chDbgCheckClassS(); chDbgCheckClassS();
if (firstprio(&oip->rlist.queue) > tp->prio) { if (firstprio(&oip->rlist.pqueue) > tp->hdr.pqueue.prio) {
__sch_reschedule_ahead(oip); __sch_reschedule_ahead(oip);
} }
} }
@ -593,8 +575,8 @@ bool chSchIsPreemptionRequired(void) {
os_instance_t *oip = currcore; os_instance_t *oip = currcore;
thread_t *tp = __sch_get_currthread(oip); thread_t *tp = __sch_get_currthread(oip);
tprio_t p1 = firstprio(&oip->rlist.queue); tprio_t p1 = firstprio(&oip->rlist.pqueue);
tprio_t p2 = tp->prio; tprio_t p2 = tp->hdr.pqueue.prio;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
/* If the running thread has not reached its time quantum, reschedule only /* If the running thread has not reached its time quantum, reschedule only
@ -627,12 +609,12 @@ void chSchDoPreemption(void) {
thread_t *ntp; thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue); ntp = (thread_t *)ch_pqueue_remove_highest(&oip->rlist.pqueue);
ntp->state = CH_STATE_CURRENT; ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp); __sch_set_currthread(oip, ntp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -675,8 +657,8 @@ void chSchDoPreemption(void) {
void chSchPreemption(void) { void chSchPreemption(void) {
os_instance_t *oip = currcore; os_instance_t *oip = currcore;
thread_t *tp = __sch_get_currthread(oip); thread_t *tp = __sch_get_currthread(oip);
tprio_t p1 = firstprio(&oip->rlist.queue); tprio_t p1 = firstprio(&oip->rlist.pqueue);
tprio_t p2 = tp->prio; tprio_t p2 = tp->hdr.pqueue.prio;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
if (tp->ticks > (tslices_t)0) { if (tp->ticks > (tslices_t)0) {
@ -710,7 +692,7 @@ void chSchDoYieldS(void) {
chDbgCheckClassS(); chDbgCheckClassS();
if (firstprio(&oip->rlist.queue) >= tp->prio) { if (firstprio(&oip->rlist.pqueue) >= tp->hdr.pqueue.prio) {
__sch_reschedule_behind(oip); __sch_reschedule_behind(oip);
} }
} }
@ -733,12 +715,12 @@ thread_t *chSchSelectFirstI(void) {
thread_t *ntp; thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue); ntp = (thread_t *)ch_pqueue_remove_highest(&oip->rlist.pqueue);
ntp->state = CH_STATE_CURRENT; ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp); __sch_set_currthread(oip, ntp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }

View File

@ -172,21 +172,21 @@ bool chSysIntegrityCheckI(unsigned testmask) {
/* Ready List integrity check.*/ /* Ready List integrity check.*/
if ((testmask & CH_INTEGRITY_RLIST) != 0U) { if ((testmask & CH_INTEGRITY_RLIST) != 0U) {
ch_queue_t *qp; ch_priority_queue_t *pqp;
/* Scanning the ready list forward.*/ /* Scanning the ready list forward.*/
n = (cnt_t)0; n = (cnt_t)0;
qp = oip->rlist.queue.next; pqp = oip->rlist.pqueue.next;
while (qp != &oip->rlist.queue) { while (pqp != &oip->rlist.pqueue) {
n++; n++;
qp = qp->next; pqp = pqp->next;
} }
/* Scanning the ready list backward.*/ /* Scanning the ready list backward.*/
qp = oip->rlist.queue.prev; pqp = oip->rlist.pqueue.prev;
while (qp != &oip->rlist.queue) { while (pqp != &oip->rlist.pqueue) {
n--; n--;
qp = qp->prev; pqp = pqp->prev;
} }
/* The number of elements must match.*/ /* The number of elements must match.*/

View File

@ -91,28 +91,28 @@ thread_t *__thd_object_init(os_instance_t *oip,
const char *name, const char *name,
tprio_t prio) { tprio_t prio) {
tp->prio = prio; tp->hdr.pqueue.prio = prio;
tp->state = CH_STATE_WTSTART; tp->state = CH_STATE_WTSTART;
tp->flags = CH_FLAG_MODE_STATIC; tp->flags = CH_FLAG_MODE_STATIC;
(void)oip; (void)oip;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
tp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM; tp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
#endif #endif
#if CH_CFG_USE_MUTEXES == TRUE #if CH_CFG_USE_MUTEXES == TRUE
tp->realprio = prio; tp->realprio = prio;
tp->mtxlist = NULL; tp->mtxlist = NULL;
#endif #endif
#if CH_CFG_USE_EVENTS == TRUE #if CH_CFG_USE_EVENTS == TRUE
tp->epending = (eventmask_t)0; tp->epending = (eventmask_t)0;
#endif #endif
#if CH_DBG_THREADS_PROFILING == TRUE #if CH_DBG_THREADS_PROFILING == TRUE
tp->time = (systime_t)0; tp->time = (systime_t)0;
#endif #endif
#if CH_CFG_USE_REGISTRY == TRUE #if CH_CFG_USE_REGISTRY == TRUE
tp->refs = (trefs_t)1; tp->refs = (trefs_t)1;
tp->name = name; tp->name = name;
REG_INSERT(oip, tp); REG_INSERT(oip, tp);
#else #else
(void)name; (void)name;
@ -611,8 +611,9 @@ tprio_t chThdSetPriority(tprio_t newprio) {
chSysLock(); chSysLock();
#if CH_CFG_USE_MUTEXES == TRUE #if CH_CFG_USE_MUTEXES == TRUE
oldprio = currtp->realprio; oldprio = currtp->realprio;
if ((currtp->prio == currtp->realprio) || (newprio > currtp->prio)) { if ((currtp->hdr.pqueue.prio == currtp->realprio) ||
currtp->prio = newprio; (newprio > currtp->hdr.pqueue.prio)) {
currtp->hdr.pqueue.prio = newprio;
} }
currtp->realprio = newprio; currtp->realprio = newprio;
#else #else

View File

@ -294,7 +294,7 @@ static void rt_test_005_004_execute(void) {
test_set_step(1); test_set_step(1);
{ {
prio = chThdGetPriorityX(); prio = chThdGetPriorityX();
chThdGetSelfX()->prio += 2; chThdGetSelfX()->hdr.pqueue.prio += 2;
test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level"); test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");
} }
test_end_step(1); test_end_step(1);
@ -305,7 +305,7 @@ static void rt_test_005_004_execute(void) {
{ {
p1 = chThdSetPriority(prio + 1); p1 = chThdSetPriority(prio + 1);
test_assert(p1 == prio, "unexpected returned priority level"); test_assert(p1 == prio, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 2, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 2, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level"); test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level");
} }
test_end_step(2); test_end_step(2);
@ -315,7 +315,7 @@ static void rt_test_005_004_execute(void) {
{ {
p1 = chThdSetPriority(prio + 3); p1 = chThdSetPriority(prio + 3);
test_assert(p1 == prio + 1, "unexpected returned priority level"); test_assert(p1 == prio + 1, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 3, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 3, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level"); test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level");
} }
test_end_step(3); test_end_step(3);
@ -324,7 +324,7 @@ static void rt_test_005_004_execute(void) {
test_set_step(4); test_set_step(4);
{ {
chSysLock(); chSysLock();
chThdGetSelfX()->prio = prio; chThdGetSelfX()->hdr.pqueue.prio = prio;
chThdGetSelfX()->realprio = prio; chThdGetSelfX()->realprio = prio;
chSysUnlock(); chSysUnlock();
} }