[][src]Function sunrise_kernel::i386::process_switch::process_switch

pub unsafe extern "C" fn process_switch(
    thread_b: Arc<ThreadStruct>,
    thread_current: Arc<ThreadStruct>
) -> Arc<ThreadStruct>

Performs the process switch, switching from currently running process A, to process B.

The process switch is composed of two parts :

Schedule out:

The schedule-out code performs the following steps:

  1. change A's state from Running to Scheduled
  2. change B's state from Scheduled to Running
  3. switch to using B's memory space. KernelLand of A is copied to B at this point.
  4. save registers of A on its stack
  5. save special "hardware_context" registers of A in its ProcessStruct. This is only the register containing the pointer to the top of the stack where all other registers are saved.
  6. load B's special hardware_contexts registers. This is where the process switch actually happens. Now we are running on B's stack, and Program Counter was moved to B's schedule-in routine

Schedule in:

  1. restore the registers that it had saved on the stack
  2. return to what it was doing before

Switching to a fresh process:

In the special case where B is a newly born process, and it's its first time being scheduled (Owww, so cute), it hasn't been scheduled out before, and doesn't have anything on the stack yet. We choose to use the same schedule-in method for both cases, that means the schedule-in will expect the new process to have a bunch of values on the stack that will be pop'ed into registers, and finally ret' to a saved program counter on the stack. This program counter can be used to control where the process will end-up on it's first schedule, likely just a function that will jump straight to userspace.

The stack can be prepared for schedule-in by the function prepare_for_first_schedule().

Return

Returns an Arc to the current ProcessSwitch after the switch, which was passed on during the switch.

Panics

Panics if the locks protecting the ProcessStruct of current or B process cannot be obtained. Panics if the locks protecting the MAIN_TASK TSS or DOUBLE_FAULT_TSS cannot be obtained.

Safety

Interrupts definitely must be masked when calling this function