Nucleus
Barry Signals and small task functions 9d6eb50 (3 years, 2 months ago)
/*
* This file contains the clone() function/system call. It creates a new task,
* and copies most of the attributes from the parent task into it.
*/
#include <sys/types.h>
#include <sys/sched.h>
#include <nucleus/task.h>
#include <nucleus/vfs.h>
#include <io.h>
extern ObjectList *readyQueue[];
/* Clone a task */
pid_t
clone(int flags)
{
enter_critical_section();
Task *parent = current, *child = new(&taskType), *tmp;
pid_t tid = 0;
/* Clone parent's file system namespace */
if (flags & CLONE_FS)
child->fs = get(parent->fs);
else
child->fs = copy(parent->fs);
/* Clone parent's files namespace */
if (flags & CLONE_FILES)
child->files = get(parent->files);
else
child->files = copy(parent->files);
/* Clone parent's virtual memory namespace */
if (flags & CLONE_VM)
child->vm = get(parent->vm);
else
child->vm = copy(parent->vm);
/* Copy stack */
if (parent->stack)
child->stack = copy(parent->stack);
/* Clone parent's signals namespace */
if (flags & CLONE_SIGHAND)
child->signals = get(parent->signals);
else
child->signals = copy(parent->signals);
/* Get executable file */
if (parent->executable)
child->executable = get(parent->executable);
child->inSyscall = parent->inSyscall;
/* After this, anything on the stack is desynchronised */
child->pageDir = clone_dir();
/* Split tasks here */
child->eip = (uintptr_t) &&end;
asm volatile("mov %%esp, %0" : "=r" (child->esp));
asm volatile("mov %%ebp, %0" : "=r" (child->ebp));
add(readyQueue[child->priority], child);
tid = child->tid;
put(child);
exit_critical_section();
end:
if (tid && !current->inSyscall) {
outb(0x20, 0x20);
if (apic)
LAPIC(0xB0) = 0;
}
return tid;
}