kernel/sys/process.c
/**
 * @brief Restore the context of the next available process's kernel thread.
 *
 * Loads the next ready process from the scheduler queue and resumes it.
 *
 * If no processes are available, the local idle task will be run from the beginning
 * of its function entry.
 *
 * If the next process in the queue has been marked as finished, it will be discard
 * until a non-finished process is found.
 *
 * If the next process is new, it will be marked as started, and its entry point
 * jumped to.
 *
 * For all other cases, the process's stored kernel thread state will be restored
 * and execution will contain in @ref switch_task with a return value of 1.
 *
 * Note that switch_next does not return and should be called only when the current
 * process has been properly added to a scheduling queue, or marked as awaiting cleanup,
 * otherwise its return state if resumed is undefined and generally whatever the state
 * was when that process last entered switch_task.
 *
 * @returns never.
 */
@brief Restore the context of the next available process's kernel thread.
Loads the next ready process from the scheduler queue and resumes it.

If no processes are available, the local idle task will be run from the beginning
of its function entry.

If the next process in the queue has been marked as finished, it will be discard
until a non-finished process is found.

If the next process is new, it will be marked as started, and its entry point
jumped to.

For all other cases, the process's stored kernel thread state will be restored
and execution will contain in @ref switch_task with a return value of 1.

Note that switch_next does not return and should be called only when the current
process has been properly added to a scheduling queue, or marked as awaiting cleanup,
otherwise its return state if resumed is undefined and generally whatever the state
was when that process last entered switch_task.

@returns never.
@brief Restore the context of the next available process ' s kernel thread . Loads the next ready process from the scheduler queue and resumes it . If no processes are available the local idle task will be run from the beginning of its function entry . If the next process in the queue has been marked as finished it will be discard until a non - finished process is found . If the next process is new it will be marked as started and its entry point jumped to . For all other cases the process ' s stored kernel thread state will be restored and execution will contain in @ref switch_task with a return value of 1 . Note that switch_next does not return and should be called only when the current process has been properly added to a scheduling queue or marked as awaiting cleanup otherwise its return state if resumed is undefined and generally whatever the state was when that process last entered switch_task . @returns never .
void switch_next(void) {
	this_core->previous_process = this_core->current_process;
	update_process_times(1);
	do {
		this_core->current_process = next_ready_process();
	} while (this_core->current_process->flags & PROC_FLAG_FINISHED);
	this_core->current_process->time_in = arch_perf_timer();
	this_core->current_process->time_switch = this_core->current_process->time_in;
	mmu_set_directory(this_core->current_process->thread.page_directory->directory);
	arch_set_kernel_stack(this_core->current_process->image.stack);
	if ((this_core->current_process->flags & PROC_FLAG_FINISHED) ||  (!this_core->current_process->signal_queue)) {
		arch_fatal_prepare();
		printf("Should not have this process...\n");
		if (this_core->current_process->flags & PROC_FLAG_FINISHED) printf("It is marked finished.\n");
		if (!this_core->current_process->signal_queue) printf("It doesn't have a signal queue.\n");
		arch_dump_traceback();
		arch_fatal();
		__builtin_unreachable();
	}
	if (this_core->current_process->flags & PROC_FLAG_STARTED) {
		if (!this_core->current_process->signal_kstack) {
			if (this_core->current_process->signal_queue->length > 0) {
				this_core->current_process->signal_kstack = malloc(KERNEL_STACK_SIZE);
				memcpy(this_core->current_process->signal_kstack, (void*)(this_core->current_process->image.stack - KERNEL_STACK_SIZE), KERNEL_STACK_SIZE);
				memcpy((thread_t*)&this_core->current_process->signal_state, (thread_t*)&this_core->current_process->thread, sizeof(thread_t));
			}
		}
	}
	__sync_or_and_fetch(&this_core->current_process->flags, PROC_FLAG_STARTED);
	arch_restore_context(&this_core->current_process->thread);
	__builtin_unreachable();
}
void switch_next ( void ) { this_core -> previous_process = this_core -> current_process ; update_process_times ( 1 ) ; do { this_core -> current_process = next_ready_process ( ) ; } while ( this_core -> current_process -> flags & PROC_FLAG_FINISHED ) ; this_core -> current_process -> time_in = arch_perf_timer ( ) ; this_core -> current_process -> time_switch = this_core -> current_process -> time_in ; mmu_set_directory ( this_core -> current_process -> thread . page_directory -> directory ) ; arch_set_kernel_stack ( this_core -> current_process -> image . stack ) ; if ( ( this_core -> current_process -> flags & PROC_FLAG_FINISHED ) || ( ! this_core -> current_process -> signal_queue ) ) { arch_fatal_prepare ( ) ; printf ( " \n " ) ; if ( this_core -> current_process -> flags & PROC_FLAG_FINISHED ) printf ( " \n " ) ; if ( ! this_core -> current_process -> signal_queue ) printf ( " \n " ) ; arch_dump_traceback ( ) ; arch_fatal ( ) ; __builtin_unreachable ( ) ; } if ( this_core -> current_process -> flags & PROC_FLAG_STARTED ) { if ( ! this_core -> current_process -> signal_kstack ) { if ( this_core -> current_process -> signal_queue -> length > 0 ) { this_core -> current_process -> signal_kstack = malloc ( KERNEL_STACK_SIZE ) ; memcpy ( this_core -> current_process -> signal_kstack , ( void * ) ( this_core -> current_process -> image . stack - KERNEL_STACK_SIZE ) , KERNEL_STACK_SIZE ) ; memcpy ( ( thread_t * ) & this_core -> current_process -> signal_state , ( thread_t * ) & this_core -> current_process -> thread , sizeof ( thread_t ) ) ; } } } __sync_or_and_fetch ( & this_core -> current_process -> flags , PROC_FLAG_STARTED ) ; arch_restore_context ( & this_core -> current_process -> thread ) ; __builtin_unreachable ( ) ; }
@brief Restore the context of the next available process's kernel thread.
@brief Restore the context of the next available process ' s kernel thread .
/* Get the next available process, discarded anything in the queue
	 * marked as finished. */ /* Restore paging and task switch context. */ /* If this process has a signal pending, we save its current context - including
		 * the entire kernel stack - before resuming switch_task. */ /* Mark the process as running and started. */ /* Jump to next */