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.
*
* @param[in] lp pointer to the list header
* @param[out] lp pointer to the list header
*
* @notapi
*/
@ -200,7 +200,7 @@ static inline ch_list_t *ch_list_pop(ch_list_t *lp) {
/**
* @brief Queue initialization.
*
* @param[in] qp pointer to the queue header
* @param[out] qp pointer to the queue header
*
* @notapi
*/
@ -239,7 +239,7 @@ static inline bool ch_queue_notempty(const ch_queue_t *qp) {
/**
* @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
*
* @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
* 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.
*
* @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) {
ch_queue_t *p = qp->next;
qp->next = p->next;
qp->next = p->next;
qp->next->prev = qp;
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
* 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.
*
* @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
* 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.
*
* @notapi
@ -308,6 +308,99 @@ static inline ch_queue_t *ch_queue_dequeue(ch_queue_t *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 */
/** @} */

View File

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

View File

@ -127,7 +127,7 @@
*
* @notapi
*/
#define firstprio(rlp) (((thread_t *)(rlp)->next)->prio)
#define firstprio(rlp) ((rlp)->next->prio)
/**
* @brief Current thread pointer get macro.
@ -164,13 +164,7 @@ extern "C" {
void chSchDoYieldS(void);
thread_t *chSchSelectFirstI(void);
#if CH_CFG_OPTIMIZE_SPEED == FALSE
void queue_prio_insert(thread_t *tp, threads_queue_t *tqp);
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);
void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp);
#endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */
#ifdef __cplusplus
}
@ -183,16 +177,17 @@ extern "C" {
/* If the performance code path has been chosen then all the following
functions are inlined into the various kernel modules.*/
#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 {
cp = (thread_t *)cp->hdr.queue.next;
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
tp->hdr.queue.next = (ch_queue_t *)cp;
tp->hdr.queue.prev = cp->hdr.queue.prev;
tp->hdr.queue.prev->next = (ch_queue_t *)tp;
cp->hdr.queue.prev = (ch_queue_t *)tp;
cp = cp->next;
} while ((cp != qp) &&
(((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
tp->next = cp;
tp->prev = cp->prev;
tp->prev->next = tp;
cp->prev = tp;
}
#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
that the current thread has a lower priority than the next thread in
the ready list.*/
chDbgAssert((currcore->rlist.queue.next == &currcore->rlist.queue) ||
(currcore->rlist.current->prio >= ((thread_t *)currcore->rlist.queue.next)->prio),
chDbgAssert((currcore->rlist.pqueue.next == &currcore->rlist.pqueue) ||
(currcore->rlist.current->hdr.pqueue.prio >= currcore->rlist.pqueue.next->prio),
"priority order violation");
port_unlock();
@ -477,7 +477,7 @@ static inline void chSysUnconditionalUnlock(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 */

View File

@ -287,7 +287,7 @@ static inline thread_t *chThdGetSelfX(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
again.*/
currtp->u.wtobjp = cp;
queue_prio_insert(currtp, &cp->queue);
ch_sch_prio_insert(&currtp->hdr.queue, &cp->queue);
chSchGoSleepS(CH_STATE_WTCOND);
msg = currtp->u.rdymsg;
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
again.*/
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);
if (msg != MSG_TIMEOUT) {
chMtxLockS(mp);

View File

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

View File

@ -90,7 +90,7 @@ ROMCONST chdebug_t ch_debug = {
(uint8_t)sizeof (void *),
(uint8_t)sizeof (systime_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, newer),
(uint8_t)_offsetof(thread_t, older),

View File

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

View File

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

View File

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

View File

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