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:
parent
be8557f2cb
commit
fb5e29f1c8
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ static inline thread_t *chThdGetSelfX(void) {
|
|||
*/
|
||||
static inline tprio_t chThdGetPriorityX(void) {
|
||||
|
||||
return chThdGetSelfX()->prio;
|
||||
return chThdGetSelfX()->hdr.pqueue.prio;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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.*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue