[−][src]Struct sunrise_kernel::process::ThreadStruct
The struct representing a thread. A process may own multiple threads.
Fields
state: Atomic<ThreadState>
The state of this thread.
kstack: KernelStack
The kernel stack it uses for handling syscalls/irqs.
hwcontext: SpinLockIRQ<ThreadHardwareContext>
The saved hardware context, for getting it running again on a process_switch.
process: Arc<ProcessStruct>
The process that this thread belongs to.
Description
A process has a link to its threads, and every thread has a link back to its process. The thread owns a strong reference to the process it belongs to, and the process in turn has a vec of weak references to the threads it owns. This way dropping a process is done automatically when its last thread is dropped.
The currently running process is indirectly kept alive by the CURRENT_THREAD
global in scheduler.
tls_region: VirtualAddress
Pointer to the Thread Local Storage region of this thread.
- x86_32: loaded in the
fs
segment selector. - x86_64: loaded in the
gs
segment selector.
tls_elf: SpinLock<VirtualAddress>
Userspace's elf Thread Pointer
.
- x86_32: loaded in the
gs
segment selectors. - x86_64: loaded in the
fs
segment selectors.
userspace_hwcontext: SpinLockIRQ<UserspaceHardwareContext>
Userspace hardware context of this thread.
Registers are backed up every time we enter the kernel via a syscall/exception, for debug purposes.
state_event: ThreadStateEvent
Thread state event
This is used when signaling that this thread as exited.
Implementations
impl ThreadStruct
[src]
pub fn new(
belonging_process: &Arc<ProcessStruct>,
ep: VirtualAddress,
stack: VirtualAddress,
arg: Option<usize>
) -> Result<Weak<Self>, KernelError>
[src]
belonging_process: &Arc<ProcessStruct>,
ep: VirtualAddress,
stack: VirtualAddress,
arg: Option<usize>
) -> Result<Weak<Self>, KernelError>
Creates a new thread.
Sets the entrypoint and userspace stack pointer.
Adds itself to list of threads of the belonging process.
The returned thread will be in Stopped
state.
The thread's only strong reference is stored in the process' maternity, and we return only a weak to it, that can directly be put in a thread_handle.
Argument
- When creating a new thread from
svcCreateThread
you should passSome(thread_entry_arg)
. This should be the argument provided by the userspace, and will be passed to the thread when it starts. - When creating the first thread of a process ("main thread") you should pass
None
. This function will recognise this condition, automatically push a handle to the created thread in the process' handle table, and this handle will be given as an argument to the thread itself when it starts, so that the main thread can know its thread handle.
fn new_locked(
belonging_process: &Arc<ProcessStruct>,
belonging_process_data: &mut ProcessStateData,
ep: VirtualAddress,
stack: VirtualAddress,
arg: Option<usize>
) -> Result<Weak<Self>, KernelError>
[src]
belonging_process: &Arc<ProcessStruct>,
belonging_process_data: &mut ProcessStateData,
ep: VirtualAddress,
stack: VirtualAddress,
arg: Option<usize>
) -> Result<Weak<Self>, KernelError>
See ThreadStruct::new. Takes the ProcessStruct.data pre-locked to avoid deadlocks in ProcessStruct::start().
pub unsafe fn create_first_thread() -> Arc<ThreadStruct>
[src]
Creates the very first process and thread at boot.
1: Creates a process struct that uses current page tables. 2: Creates a thread struct that uses the current KernelStack as its stack, and points to the created process. 3: Adds itself to the created process.
Thread will be in state Running.
Returns the created thread.
Safety
Use only for creating the very first process. Should never be used again after that. Must be using a valid KernelStack, a valid ActivePageTables.
Does not check that the process struct is not marked killed.
Panics
Panics if max PID has been reached, which it shouldn't have since we're the first process.
fn start_locked(
thread: &Arc<Self>,
belonging_process_data: &mut ProcessStateData
) -> Result<(), KernelError>
[src]
thread: &Arc<Self>,
belonging_process_data: &mut ProcessStateData
) -> Result<(), KernelError>
See ThreadStruct::start. Takes the ProcessStruct.data pre-locked to avoid deadlocks in ProcessStruct::start().
pub fn start(this: Weak<Self>) -> Result<(), KernelError>
[src]
Takes a reference to a thread, removes it from the maternity, and adds it to the schedule queue.
We take only a weak reference, to permit calling this function easily with a thread_handle.
Errors
ThreadAlreadyStarted
if the weak resolution failed (the thread has already been killed).ThreadAlreadyStarted
if the thread was not found in the maternity.ProcessKilled
if the process struct was taggedkilled
before we had time to start it.
pub fn exit(this: Arc<Self>)
[src]
Sets the thread to the Exited
state.
We reschedule the thread (cancelling any waiting it was doing). In this state, the thread will die when attempting to return to userspace.
If the thread was already in the Exited
state, this function is a no-op.
Trait Implementations
impl Debug for ThreadStruct
[src]
impl Drop for ThreadStruct
[src]
Auto Trait Implementations
impl !RefUnwindSafe for ThreadStruct
impl Send for ThreadStruct
impl Sync for ThreadStruct
impl Unpin for ThreadStruct
impl !UnwindSafe for ThreadStruct
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,