sched: enforce ref-counting on current task/thread pointers

This commit is contained in:
2026-04-01 18:17:05 +01:00
parent 15c2207ab9
commit 512356ac2d
28 changed files with 364 additions and 103 deletions
+4 -2
View File
@@ -215,18 +215,19 @@ void schedule_thread_on_cpu(struct thread *thr)
void start_charge_period(void)
{
struct thread *self = current_thread();
struct thread *self = get_current_thread();
if (!self) {
return;
}
self->tr_charge_period_start = get_cycles();
put_current_thread(self);
}
void end_charge_period(void)
{
preempt_disable();
struct thread *self = current_thread();
struct thread *self = get_current_thread();
if (!self) {
return;
}
@@ -244,6 +245,7 @@ void end_charge_period(void)
}
self->tr_charge_period_start = 0;
put_current_thread(self);
// printk("%llu cycles charged to %s/%u", charge,
// self->tr_parent->t_name, self->tr_parent->t_id);
+19 -5
View File
@@ -282,7 +282,7 @@ struct task *task_from_tid(tid_t id)
void task_exit(int status)
{
struct task *self = current_task();
struct task *self = get_current_task();
unsigned long flags;
task_lock_irqsave(self, &flags);
struct task *parent = self->t_parent;
@@ -295,7 +295,7 @@ void task_exit(int status)
task_unlock(parent);
}
struct thread *cur_thread = current_thread();
struct thread *cur_thread = get_current_thread();
self->t_state = TASK_STOPPED;
cur_thread->tr_state = THREAD_STOPPED;
@@ -340,6 +340,9 @@ void task_exit(int status)
self->t_base.ob_refcount);
spin_unlock_irqrestore(handles_lock, flags);
put_current_thread(cur_thread);
put_current_task(self);
while (1) {
schedule(SCHED_NORMAL);
}
@@ -410,8 +413,19 @@ struct thread *task_create_thread(struct task *parent)
return thread;
}
struct task *current_task(void)
struct task *get_current_task(void)
{
struct thread *thr = current_thread();
return thr ? thr->tr_parent : NULL;
struct thread *thr = get_current_thread();
if (!thr) {
return NULL;
}
struct task *out = task_ref(thr->tr_parent);
put_current_thread(thr);
return out;
}
void put_current_task(struct task *task)
{
task_unref(task);
}
+15 -3
View File
@@ -105,7 +105,7 @@ void thread_free(struct thread *thr)
{
}
struct thread *current_thread(void)
struct thread *get_current_thread(void)
{
struct cpu_data *cpu = get_this_cpu();
if (!cpu) {
@@ -113,13 +113,24 @@ struct thread *current_thread(void)
}
struct thread *out = cpu->c_rq.rq_cur;
object_ref(&out->tr_base);
put_cpu(cpu);
return out;
}
void put_current_thread(struct thread *thr)
{
object_unref(&thr->tr_base);
}
bool need_resched(void)
{
return (current_thread()->tr_flags & THREAD_F_NEED_RESCHED) != 0;
struct thread *thr = get_current_thread();
bool result = (thr->tr_flags & THREAD_F_NEED_RESCHED) != 0;
put_current_thread(thr);
return result;
}
int thread_priority(struct thread *thr)
@@ -143,7 +154,7 @@ void thread_awaken(struct thread *thr)
void thread_exit(void)
{
struct thread *self = current_thread();
struct thread *self = get_current_thread();
unsigned long flags;
thread_lock_irqsave(self, &flags);
self->tr_state = THREAD_STOPPED;
@@ -153,6 +164,7 @@ void thread_exit(void)
self->tr_parent->t_id,
self->tr_id);
thread_unlock_irqrestore(self, flags);
put_current_thread(self);
while (1) {
schedule(SCHED_NORMAL);
+2 -1
View File
@@ -44,7 +44,7 @@ unsigned long schedule_timeout(unsigned long ticks)
{
struct timer timer;
struct thread *self = current_thread();
struct thread *self = get_current_thread();
timer.t_entry = QUEUE_ENTRY_INIT;
timer.t_expiry = clock_ticks + ticks;
@@ -58,6 +58,7 @@ unsigned long schedule_timeout(unsigned long ticks)
schedule(SCHED_NORMAL);
remove_timer(&timer);
put_current_thread(self);
return 0;
}
+12 -2
View File
@@ -110,7 +110,7 @@ void wakeup_one(struct waitqueue *q)
void sleep_forever(void)
{
struct thread *thr = current_thread();
struct thread *thr = get_current_thread();
struct runqueue *rq = thr->tr_rq;
unsigned long flags;
@@ -121,7 +121,17 @@ void sleep_forever(void)
rq_unlock(rq, flags);
while (thr->tr_state == THREAD_SLEEPING) {
put_current_thread(thr);
while (1) {
thr = get_current_thread();
bool sleep = (thr->tr_state == THREAD_SLEEPING);
put_current_thread(thr);
if (!sleep) {
break;
}
schedule(SCHED_NORMAL);
}
}