BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / e4c4dfe6cc8f70e0d4919a434e62f1d061477add / task / clone.c

// Related

Nucleus

Barry Virtual Memory Regions and namespace 381dc7b (3 years, 3 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->fs);
	else
		child->fs = copy(parent->fs);

	/* 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) {
		outb(0x20, 0x20);
		if (apic)
			LAPIC(0xB0) = 0;
	}

	return tid;
}