threads: name the TLS thread pointer arch-neutrally (not fs.base)
The M10 TLS work leaked x86 naming into the generic kernel: Task.fs_base, PerCpu.loaded_fs_base, and architecture.setFsBase. The *mechanism* was already abstracted (the generic scheduler calls through the architecture layer; the wrmsr IA32_FS_BASE lives in architecture/x86_64/cpu.zig), but the *names* would force an aarch64 port to implement a 'setFsBase' that writes TPIDR_EL0. Rename to the neutral concept: Task.thread_pointer, PerCpu.loaded_thread_pointer, architecture.setThreadPointer (x86_64 impl writes IA32_FS_BASE; aarch64 -> TPIDR_EL0). Also neutralise the user_arg comment (first argument register, rdi on x86_64). No behaviour change; thread-tls/thread-mutex/smp/process-kill + host tests pass.
This commit is contained in:
+17
-17
@@ -81,18 +81,19 @@ pub const Task = struct {
|
||||
aspace: u64 = 0,
|
||||
user_ip: u64 = 0, // user-mode entry point (user task only)
|
||||
user_sp: u64 = 0, // user-mode stack pointer (user task only)
|
||||
user_arg: u64 = 0, // value delivered in the user's rdi at first entry: 0 for a
|
||||
// process (its _start ignores it), the closure pointer for a thread (docs/threading.md)
|
||||
user_arg: u64 = 0, // value delivered in the user's first argument register at first entry
|
||||
// (rdi on x86_64, via architecture.jumpToUserArg): 0 for a process (its _start ignores
|
||||
// it), the closure pointer for a thread (docs/threading.md)
|
||||
// The user address this task is blocked on in futex_wait (0 = not futex-waiting).
|
||||
// Cleared to 0 by futexWakeLocked as the "woken, not timed out" signal (docs/threading.md).
|
||||
futex_addr: u64 = 0,
|
||||
// The task id this task is blocked in `thread_join` on (0 = not joining). Woken by
|
||||
// `wakeJoinersLocked` when that task exits (docs/threading-plan.md M9).
|
||||
join_target: u32 = 0,
|
||||
// The FS-base (x86_64 thread pointer) for this task's user-space TLS — 0 until the
|
||||
// task sets it via `set_thread_pointer`. Restored on every context switch to this task
|
||||
// (docs/threading-plan.md M10).
|
||||
fs_base: u64 = 0,
|
||||
// This task's user-space TLS thread pointer — 0 until set via `set_thread_pointer`.
|
||||
// Architecture-neutral: the arch layer maps it to the FS base on x86_64, `TPIDR_EL0` on
|
||||
// aarch64. Restored on every context switch to this task (docs/threading-plan.md M10).
|
||||
thread_pointer: u64 = 0,
|
||||
// The mmap / MMIO grant-arena cursors moved from Task to the per-address-space object
|
||||
// (`AspaceRef`, below) so threads sharing one address space hand out disjoint grants
|
||||
// — see aspaceMmapNextPtr / aspaceDeviceMapNextPtr (docs/threading-plan.md M7).
|
||||
@@ -288,7 +289,7 @@ pub const PerCpu = struct {
|
||||
index: u32 = 0, // dense 0-based core index
|
||||
online: bool = false, // has this core finished bring-up?
|
||||
loaded_aspace: u64 = 0, // the address-space root currently loaded on this core
|
||||
loaded_fs_base: u64 = 0, // the FS base currently loaded on this core (docs/threading-plan.md M10)
|
||||
loaded_thread_pointer: u64 = 0, // the TLS thread pointer currently loaded on this core (docs/threading-plan.md M10)
|
||||
// Tasks pinned to this core (affinity == index), per priority level + bitmap.
|
||||
pinned_head: [number_priorities]?*Task = .{null} ** number_priorities,
|
||||
pinned_tail: [number_priorities]?*Task = .{null} ** number_priorities,
|
||||
@@ -573,11 +574,11 @@ fn switchTo(pc: *PerCpu, save_sp: *usize, next: *Task) void {
|
||||
architecture.loadPageTable(want);
|
||||
pc.loaded_aspace = want;
|
||||
}
|
||||
// Restore the next task's user TLS thread pointer (FS base) — only on change, the same
|
||||
// Restore the next task's user TLS thread pointer — only on change, the same
|
||||
// conditional-load discipline as CR3 above (docs/threading-plan.md M10).
|
||||
if (next.fs_base != pc.loaded_fs_base) {
|
||||
architecture.setFsBase(next.fs_base);
|
||||
pc.loaded_fs_base = next.fs_base;
|
||||
if (next.thread_pointer != pc.loaded_thread_pointer) {
|
||||
architecture.setThreadPointer(next.thread_pointer);
|
||||
pc.loaded_thread_pointer = next.thread_pointer;
|
||||
}
|
||||
architecture.switchContext(save_sp, next.sp);
|
||||
// Resumed now (switchContext returned into our own switchTo frame). Re-fetch the core
|
||||
@@ -678,14 +679,13 @@ pub fn joinThreadLocked(tid: u32) void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the calling task's user TLS thread pointer (FS base) and load it now. Persisted on
|
||||
/// the Task so context switches restore it (docs/threading-plan.md M10). Caller holds the
|
||||
/// kernel lock.
|
||||
/// Set the calling task's user TLS thread pointer and load it now. Persisted on the Task so
|
||||
/// context switches restore it (docs/threading-plan.md M10). Caller holds the kernel lock.
|
||||
pub fn setThreadPointerLocked(addr: u64) void {
|
||||
const pc = thisCpu();
|
||||
pc.current.fs_base = addr;
|
||||
architecture.setFsBase(addr);
|
||||
pc.loaded_fs_base = addr;
|
||||
pc.current.thread_pointer = addr;
|
||||
architecture.setThreadPointer(addr);
|
||||
pc.loaded_thread_pointer = addr;
|
||||
}
|
||||
|
||||
/// Wake every task blocked in `thread_join` on `tid` — called from the exit paths once the
|
||||
|
||||
Reference in New Issue
Block a user