turnstile fixes

This commit is contained in:
2026-10-22 01:34:45 +02:00
parent dbb543de66
commit b83f1fe6d9
10 changed files with 419 additions and 82 deletions
+20
View File
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: ISC
#pragma once
#include <zinnia/atomic.h>
struct rwlock {
atomic_uintptr_t word;
};
void rwlock_read_lock(struct rwlock* rw);
void rwlock_read_unlock(struct rwlock* rw);
bool rwlock_try_read_lock(struct rwlock* rw);
void rwlock_write_lock(struct rwlock* rw);
void rwlock_write_unlock(struct rwlock* rw);
bool rwlock_try_write_lock(struct rwlock* rw);
void rwlock_downgrade(struct rwlock* rw);
bool rwlock_try_upgrade(struct rwlock* rw);
+5 -3
View File
@@ -60,6 +60,7 @@ struct task {
atomic_bool wake_pending;
struct spinlock lock;
_Atomic(struct spinlock*) lockp;
atomic_bool on_cpu; // Whether a CPU is still running on this task's context.
uint8_t base_prio; // Set by sched_set_priority().
@@ -68,8 +69,7 @@ struct task {
struct scheduler* last_rq; // The most recent run queue this task was scheduled on.
struct turnstile* turnstile; // Turnstile owned by this task.
_Atomic(struct turnstile*) blocked_ts; // The turnstile this task is blocked on.
_Atomic(const void*) blocked_obj; // The lock that `blocked_ts` belongs to.
struct turnstile* blocked_ts; // The turnstile this task is blocked on.
tailq_head(struct turnstile) pi_lenders; // Turnstiles of locks this task owns.
tailq_link(struct task) ts_link; // Link in the waiters of `blocked_ts`.
uint8_t ts_queue;
@@ -107,6 +107,8 @@ typedef void (*task_fn_t)(uintptr_t arg0);
errno_t task_create(const char* name, struct vma* space, task_fn_t entry, uintptr_t arg0, struct task** out);
void task_destroy(struct task* task);
void task_lock(struct task* task);
void task_unlock(struct task* task);
[[noreturn]]
void task_entry(task_fn_t entry, uintptr_t arg0, struct task* prev);
@@ -122,7 +124,7 @@ void sched_block(struct scheduler* sched);
// Makes a blocked task runnable again, or marks the wake as pending if it hasn't blocked yet.
void sched_wake(struct task* task);
// Same as sched_wake(), but `task->lock` must be held.
// Same as sched_wake(), but the task must be locked with task_lock().
void sched_wake_locked(struct task* task);
[[noreturn]]
+3
View File
@@ -22,6 +22,7 @@ struct turnstile {
// The task that inherits the priority from the waiters.
struct task* owner;
bool lending;
// Priority of the most urgent waiter in any queue.
_Atomic(uint8_t) top_priority;
@@ -55,4 +56,6 @@ struct task* turnstile_first(
void turnstile_wake(struct turnstile_chain* chain, const void* obj, struct task* task, struct task* new_owner);
void turnstile_waive(struct turnstile_chain* chain, const void* obj);
void turnstile_reprioritize(struct task* task);