sched: add a thread flag to indicate when a thread is scheduled on a runqueue
this prevents runqueue corruption that can occur if rq_enqueue is called on a thread that's already on a runqueue.
This commit is contained in:
@@ -14,8 +14,11 @@ enum thread_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum thread_flags {
|
enum thread_flags {
|
||||||
|
/* this thread has exhausted its quantum and is due to be re-scheduled.
|
||||||
|
*/
|
||||||
THREAD_F_NEED_RESCHED = 0x01u,
|
THREAD_F_NEED_RESCHED = 0x01u,
|
||||||
THREAD_F_NO_PREEMPT = 0x02u,
|
/* this thread is currently scheduled (i.e. is present on a runqueue) */
|
||||||
|
THREAD_F_SCHEDULED = 0x04u,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct thread {
|
struct thread {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <kernel/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <kernel/percpu.h>
|
#include <kernel/percpu.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/task.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
|
|
||||||
#define PRIO_MASK(p) (((uint32_t)1) << (p))
|
#define PRIO_MASK(p) (((uint32_t)1) << (p))
|
||||||
@@ -20,6 +21,7 @@ struct thread *rq_dequeue(struct runqueue *rq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct queue *q = &rq->rq_queues[prio];
|
struct queue *q = &rq->rq_queues[prio];
|
||||||
|
|
||||||
struct queue_entry *qe = queue_pop_front(q);
|
struct queue_entry *qe = queue_pop_front(q);
|
||||||
if (!qe) {
|
if (!qe) {
|
||||||
rq->rq_readybits &= ~PRIO_MASK(prio);
|
rq->rq_readybits &= ~PRIO_MASK(prio);
|
||||||
@@ -27,6 +29,7 @@ struct thread *rq_dequeue(struct runqueue *rq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct thread *thr = QUEUE_CONTAINER(struct thread, tr_rqentry, qe);
|
struct thread *thr = QUEUE_CONTAINER(struct thread, tr_rqentry, qe);
|
||||||
|
thr->tr_flags &= ~THREAD_F_SCHEDULED;
|
||||||
|
|
||||||
if (rq->rq_nthreads > 0) {
|
if (rq->rq_nthreads > 0) {
|
||||||
rq->rq_nthreads--;
|
rq->rq_nthreads--;
|
||||||
@@ -41,17 +44,24 @@ struct thread *rq_dequeue(struct runqueue *rq)
|
|||||||
|
|
||||||
void rq_enqueue(struct runqueue *rq, struct thread *thr)
|
void rq_enqueue(struct runqueue *rq, struct thread *thr)
|
||||||
{
|
{
|
||||||
|
if (thr->tr_flags & THREAD_F_SCHEDULED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int prio = thread_priority(thr);
|
int prio = thread_priority(thr);
|
||||||
if (prio < 0 || prio > PRIO_MAX) {
|
if (prio < 0 || prio > PRIO_MAX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct queue *q = &rq->rq_queues[prio];
|
struct queue *q = &rq->rq_queues[prio];
|
||||||
|
|
||||||
queue_push_back(q, &thr->tr_rqentry);
|
queue_push_back(q, &thr->tr_rqentry);
|
||||||
|
|
||||||
rq->rq_nthreads++;
|
rq->rq_nthreads++;
|
||||||
|
|
||||||
rq->rq_readybits |= PRIO_MASK(thread_priority(thr));
|
rq->rq_readybits |= PRIO_MASK(thread_priority(thr));
|
||||||
thr->tr_rq = rq;
|
thr->tr_rq = rq;
|
||||||
|
thr->tr_flags |= THREAD_F_SCHEDULED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct runqueue *cpu_rq(unsigned int cpu)
|
struct runqueue *cpu_rq(unsigned int cpu)
|
||||||
@@ -65,6 +75,10 @@ struct runqueue *cpu_rq(unsigned int cpu)
|
|||||||
|
|
||||||
void rq_remove_thread(struct runqueue *rq, struct thread *thr)
|
void rq_remove_thread(struct runqueue *rq, struct thread *thr)
|
||||||
{
|
{
|
||||||
|
if (!(thr->tr_flags & THREAD_F_SCHEDULED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int prio = thread_priority(thr);
|
int prio = thread_priority(thr);
|
||||||
if (prio < 0 || prio > PRIO_MAX) {
|
if (prio < 0 || prio > PRIO_MAX) {
|
||||||
return;
|
return;
|
||||||
@@ -72,6 +86,7 @@ void rq_remove_thread(struct runqueue *rq, struct thread *thr)
|
|||||||
|
|
||||||
struct queue *q = &rq->rq_queues[prio];
|
struct queue *q = &rq->rq_queues[prio];
|
||||||
queue_delete(q, &thr->tr_rqentry);
|
queue_delete(q, &thr->tr_rqentry);
|
||||||
|
thr->tr_flags &= ~THREAD_F_SCHEDULED;
|
||||||
|
|
||||||
if (rq->rq_nthreads > 0) {
|
if (rq->rq_nthreads > 0) {
|
||||||
rq->rq_nthreads--;
|
rq->rq_nthreads--;
|
||||||
|
|||||||
Reference in New Issue
Block a user