void init_multitasking() { printk(KERN_DEBUG, "[sched]: Starting multitasking system...\n"); /* make the kernel task */ task_t *task = task_create(); task->pid = next_pid++; task->pd = (page_dir_t *)kernel_dir; task->stack_end=STACK_LOCATION; task->priority = 1; task->cpu = primary_cpu; task->thread = thread_data_create(); /* alarm_mutex is aquired inside a kernel tick, so we may not schedule. */ alarm_mutex = mutex_create(0, MT_NOSCHED); kill_queue = ll_create(0); primary_queue = tqueue_create(0, 0); primary_cpu->active_queue = tqueue_create(0, 0); tqueue_insert(primary_queue, (void *)task, task->listnode); tqueue_insert(primary_cpu->active_queue, (void *)task, task->activenode); primary_cpu->cur = task; primary_cpu->ktask = task; primary_cpu->numtasks=1; /* make this the "current_task" by assigning a specific location * in the page directory as the pointer to the task. */ arch_specific_set_current_task((addr_t *)kernel_dir, (addr_t)task); kernel_task = task; /* this is the final thing to allow the system to begin scheduling * once interrupts are enabled */ primary_cpu->flags |= CPU_TASK; add_atomic(&running_processes, 1); #if CONFIG_MODULES add_kernel_symbol(delay); add_kernel_symbol(delay_sleep); add_kernel_symbol(schedule); add_kernel_symbol(run_scheduler); add_kernel_symbol(exit); add_kernel_symbol(sys_setsid); add_kernel_symbol(do_fork); add_kernel_symbol(kill_task); add_kernel_symbol(do_send_signal); add_kernel_symbol(dosyscall); add_kernel_symbol(task_pause); add_kernel_symbol(task_resume); add_kernel_symbol(got_signal); #if CONFIG_SMP add_kernel_symbol(get_cpu); #endif _add_kernel_symbol((addr_t)(task_t **)&kernel_task, "kernel_task"); #endif }
void tm_init_multitasking(void) { printk(KERN_DEBUG, "[sched]: Starting multitasking system...\n"); sysgate_page = mm_physical_allocate(PAGE_SIZE, true); mm_physical_memcpy((void *)sysgate_page, (void *)signal_return_injector, MEMMAP_SYSGATE_ADDRESS_SIZE, PHYS_MEMCPY_MODE_DEST); process_table = hash_create(0, 0, 128); process_list = linkedlist_create(0, LINKEDLIST_MUTEX); mutex_create(&process_refs_lock, 0); mutex_create(&thread_refs_lock, 0); thread_table = hash_create(0, 0, 128); struct thread *thread = kmalloc(sizeof(struct thread)); struct process *proc = kernel_process = kmalloc(sizeof(struct process)); proc->refs = 2; thread->refs = 1; hash_insert(process_table, &proc->pid, sizeof(proc->pid), &proc->hash_elem, proc); hash_insert(thread_table, &thread->tid, sizeof(thread->tid), &thread->hash_elem, thread); linkedlist_insert(process_list, &proc->listnode, proc); valloc_create(&proc->mmf_valloc, MEMMAP_MMAP_BEGIN, MEMMAP_MMAP_END, PAGE_SIZE, 0); linkedlist_create(&proc->threadlist, 0); mutex_create(&proc->map_lock, 0); mutex_create(&proc->stacks_lock, 0); mutex_create(&proc->fdlock, 0); hash_create(&proc->files, HASH_LOCKLESS, 64); proc->magic = PROCESS_MAGIC; blocklist_create(&proc->waitlist, 0, "process-waitlist"); mutex_create(&proc->fdlock, 0); memcpy(&proc->vmm_context, &kernel_context, sizeof(kernel_context)); thread->process = proc; /* we have to do this early, so that the vmm system can use the lock... */ thread->state = THREADSTATE_RUNNING; thread->magic = THREAD_MAGIC; workqueue_create(&thread->resume_work, 0); thread->kernel_stack = (addr_t)&initial_kernel_stack; spinlock_create(&thread->status_lock); primary_cpu->active_queue = tqueue_create(0, 0); primary_cpu->idle_thread = thread; primary_cpu->numtasks=1; ticker_create(&primary_cpu->ticker, 0); workqueue_create(&primary_cpu->work, 0); tm_thread_add_to_process(thread, proc); tm_thread_add_to_cpu(thread, primary_cpu); atomic_fetch_add_explicit(&running_processes, 1, memory_order_relaxed); atomic_fetch_add_explicit(&running_threads, 1, memory_order_relaxed); set_ksf(KSF_THREADING); *(struct thread **)(thread->kernel_stack) = thread; primary_cpu->flags |= CPU_RUNNING; #if CONFIG_MODULES loader_add_kernel_symbol(tm_thread_delay_sleep); loader_add_kernel_symbol(tm_thread_delay); loader_add_kernel_symbol(tm_timing_get_microseconds); loader_add_kernel_symbol(tm_thread_set_state); loader_add_kernel_symbol(tm_thread_exit); loader_add_kernel_symbol(tm_thread_poke); loader_add_kernel_symbol(tm_thread_block); loader_add_kernel_symbol(tm_thread_got_signal); loader_add_kernel_symbol(tm_thread_unblock); loader_add_kernel_symbol(tm_blocklist_wakeall); loader_add_kernel_symbol(kthread_create); loader_add_kernel_symbol(kthread_wait); loader_add_kernel_symbol(kthread_join); loader_add_kernel_symbol(kthread_kill); loader_add_kernel_symbol(tm_schedule); loader_add_kernel_symbol(arch_tm_get_current_thread); #endif }