[][src]Struct sunrise_kernel::process::ThreadStruct

pub struct ThreadStruct {
    pub state: Atomic<ThreadState>,
    pub kstack: KernelStack,
    pub hwcontext: SpinLockIRQ<ThreadHardwareContext>,
    pub process: Arc<ProcessStruct>,
    pub tls_region: VirtualAddress,
    pub tls_elf: SpinLock<VirtualAddress>,
    pub userspace_hwcontext: SpinLockIRQ<UserspaceHardwareContext>,
    state_event: ThreadStateEvent,
}

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.

tls_elf: SpinLock<VirtualAddress>

Userspace's elf Thread Pointer.

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]

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 pass Some(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]

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]

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 tagged killed 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]

fn drop(&mut self)[src]

Late thread death notifications:

  • notifies our process that our TLS can be re-used.

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]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.