thread_t *sched_choose() { thread_t *td = runq_choose(&runq); if (td) { sched_remove(td); return td; } return PCPU_GET(idle_thread); }
/* syscall: exit - terminate execution of the current process */ void syscall_do_exit(int_registers_block *regs) { SYSCALL_DEBUG("[sys:%i] SYSCALL_EXIT called by process %i (%p) (thread %i)\n", CPU_ID, cpu_table[CPU_ID].current->proc->pid, cpu_table[CPU_ID].current->proc, cpu_table[CPU_ID].current->tid); /* request to be killed by the system executive */ msg_send_signal(proc_role_lookup(DIOSIX_ROLE_SYSTEM_EXECUTIVE), NULL, SIGXPROCEXIT, cpu_table[CPU_ID].current->proc->pid); /* remove from the run queue and mark as dying */ sched_remove(cpu_table[CPU_ID].current, dead); }
void scheduler() { for (;;) { struct process *proc = current_proc ? current_proc->next : list_head.next; /* Find a runnable process */ while (proc == &list_head || proc->state != PROC_STATE_RUNNING) { if (proc != &list_head && proc->state == PROC_STATE_DEAD) { /* Release the dead process */ struct process *dead = proc; proc = proc->next; sched_remove(dead); proc_free(dead); } else { proc = proc->next; } } close_int(); current_proc = proc; /* Update TSS */ tss.ss0 = KERNEL_DATA_SELECTOR; tss.esp0 = proc->kernel_stack; flush_tss(); /* Change to process virtual address space */ set_cr3(CAST_VIRTUAL_TO_PHYSICAL(proc->page_dir)); if (!proc->context) init_context(proc); switch_kcontext(&sched_context, proc->context); /* Call schedule task */ if (sched_task) { sched_task(current_proc); sched_task = NULL; } } }
/* syscall thread_exit - end termination of the currently running thread. if it's the only thread in the process, the whole process will exit */ void syscall_do_thread_exit(int_registers_block *regs) { SYSCALL_DEBUG("[sys:%i] SYSCALL_THREAD_EXIT called by process %i (%p) (thread %i threads %i)\n", CPU_ID, cpu_table[CPU_ID].current->proc->pid, cpu_table[CPU_ID].current->proc, cpu_table[CPU_ID].current->tid, cpu_table[CPU_ID].current->proc->thread_count); /* check to see if this process has only one thread */ if(cpu_table[CPU_ID].current->proc->thread_count < 2) { syscall_do_exit(regs); return; } /* request to be killed by the system executive */ msg_send_signal(proc_role_lookup(DIOSIX_ROLE_SYSTEM_EXECUTIVE), NULL, SIGXTHREADEXIT, cpu_table[CPU_ID].current->proc->pid); /* remove from the run queue and mark as dying */ sched_remove(cpu_table[CPU_ID].current, dead); }