Esempio n. 1
0
void 
wake_up(struct wait_queue *queue)
{
	assert(queue);

	struct task_struct *task;

	task = wait_queue_del(queue);

	if (!task) return;

	task->task_status = TASK_RUNNING;

	schedule_add_task(task);
}
Esempio n. 2
0
int exit_notify(struct task_struct *t)
{
	struct task_struct *p;
	int ret;
	if (!t)
		return 0;
	

	if (t->pwait) {
		p = task_pidmap[t->ppid];
		//ret = pid2task(t->ppid, &p, 0);
		//assert(ret == 0);
		p->task_status = TASK_RUNNING;
		schedule_add_task(p);
	}
	return 0;
}
Esempio n. 3
0
int32_t fork() {

	if (kernel_thread == current_thread)
		panic("SCHED: no forking from kernel thread.");

	// TODO: change to kernel locking
	asm volatile("cli");

	// we will fork current thread and clone current task address space
	thread_t* new_thread = kmalloc(sizeof(thread_t));
	new_thread->tid = next_tid++;
	new_thread->state = THREAD_RUNNING;
	new_thread->esp0 = current_thread->esp0;
	new_thread->stack_size = current_thread->stack_size;

	page_directory_t* page_dir = clone_directory(current_directory);

	// NOTE: this is allocated in kernel address space so shouldn't be copied,
	// take care of properly (fully) linking kernel page tables
	task_t* new_task = create_task(new_thread, page_dir);

	// NOTE: we copy whole address space -- it means that we copy the
	// new stack (no in case when forking from kernel)

	// add to run queue
	schedule_add_task(new_task);

	// after this will be entry point
	save_thread_state(new_thread);
	// NEW TASK ENTRY POINT

	// decide if we're in child or parent
	if (current_thread == new_thread) {
		// we're in child
		return 0;
	} else {
		// we're in parent

		// TODO: change to kernel locking
		asm volatile("sti");

		// by convention return child's pid
		return new_task->pid;
	}
}
Esempio n. 4
0
uint32_t exec_elf(const char* name) {
	fs_node_t* file = finddir(fs_root, name);
	open(file, 1, 0);

	// disable interrupts
	asm volatile("cli");

	// save directory and create one for new task
	page_directory_t* old_dir = current_directory;
	page_directory_t* new_dir = clone_directory(old_dir);

	// switch to new directory (this is where we set up process)
	switch_page_directory(new_dir);

	// load elf and get entry point
	uint32_t entry = load_elf_binary(file);

	// setup stack
	uint32_t stack = (uint32_t) allocate_stack(THREAD_STACK_SIZE);

	// create scheduling structures
	thread_t* new_thread = create_thread((int(*)(void*)) entry, 0,
			(uint32_t*) stack, THREAD_STACK_SIZE);
	task_t* new_task = create_task(new_thread, new_dir);
	schedule_add_task(new_task);

	// switch back to parents directory
	switch_page_directory(old_dir);

	// close executable image
	close(file);

	// reenable interrupts
	asm volatile("sti");

	// like in fork return child pid
	return new_task->pid;
}