Cleaned up thread_control functions

This commit is contained in:
Bahadir Balban
2009-05-26 17:29:10 +03:00
parent 93c7cf1995
commit 19c71cc658

View File

@@ -229,9 +229,8 @@ int arch_setup_new_thread(struct ktcb *new, struct ktcb *orig,
int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
struct ktcb *new, struct ktcb *orig)
{
/* For tid, allocate requested id if it's available, else a new one */
if ((ids->tid = id_get(thread_id_pool, ids->tid)) < 0)
ids->tid = id_new(thread_id_pool);
/* Allocate a new id */
ids->tid = id_new(thread_id_pool);
/*
* If thread space is new or copied,
@@ -279,7 +278,8 @@ int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flag
ret = (int)new;
goto out;
}
ids->spid = new->spid; /* Returned back to caller */
/* New space id to be returned back to caller */
ids->spid = new->spid;
address_space_attach(tcb, new);
address_space_add(new);
}
@@ -288,7 +288,8 @@ int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flag
ret = (int)new;
goto out;
}
ids->spid = new->spid; /* Returned back to caller */
/* New space id to be returned back to caller */
ids->spid = new->spid;
address_space_attach(tcb, new);
address_space_add(new);
}
@@ -300,107 +301,43 @@ out:
int thread_create(struct task_ids *ids, unsigned int flags)
{
struct ktcb *new, *orig_task = 0;
struct ktcb *new;
struct ktcb *parent;
int err;
flags &= THREAD_CREATE_MASK;
parent = 0;
if (!(new = tcb_alloc_init()))
return -ENOMEM;
if (flags == THREAD_SAME_SPACE || flags == THREAD_COPY_SPACE) {
if (!(orig_task = tcb_find(ids->tid))) {
/* Pre-mature tcb needs freeing by free_page */
free_page(new);
return -EINVAL;
/* Set up new thread space by using space id and flags */
if ((err = thread_setup_space(new, ids, flags)) < 0)
goto out_err;
/* Obtain parent thread if there is one */
if (flags == THREAD_SAME_SPACE ||
flags == THREAD_COPY_SPACE) {
if (!(parent = tcb_find(ids->tid))) {
err = -EINVAL;
goto out_err;
}
}
if ((err = thread_setup_space(new, ids, flags)) < 0) {
/* Pre-mature tcb needs freeing by free_page */
free_page(new);
return err;
}
/* Set up ids and context using original tcb or from scratch */
thread_setup_new_ids(ids, flags, new, orig_task);
arch_setup_new_thread(new, orig_task, flags);
/* Set up new thread context by using parent ids and flags */
thread_setup_new_ids(ids, flags, new, parent);
arch_setup_new_thread(new, parent, flags);
tcb_add(new);
return 0;
out_err:
/* Pre-mature tcb needs freeing by free_page */
free_page(new);
return err;
}
#if 0
/*
* Creates a thread, with a new thread id, and depending on the flags,
* either creates a new space, uses the same space as another thread,
* or creates a new space copying the space of another thread. These
* are respectively used when creating a brand new task, creating a
* new thread in an existing address space, or forking a task.
*/
int thread_create_old(struct task_ids *ids, unsigned int flags)
{
struct ktcb *task = 0;
struct ktcb *new = (struct ktcb *)zalloc_page();
unsigned int create_flags = flags & THREAD_CREATE_MASK;
int err;
if (!new)
return -ENOMEM;
/* Determine space allocation */
if (create_flags == THREAD_NEW_SPACE) {
/* Allocate new pgd and copy all kernel areas */
if (!(TASK_PGD(new) = alloc_pgd())) {
free_page(new);
return -ENOMEM;
}
copy_pgd_kern_all(TASK_PGD(new));
} else {
/* Existing space will be used, find it from all tasks */
list_for_each_entry(task, &global_task_list, task_list) {
/* Space ids match, can use existing space */
if (task->spid == ids->spid) {
if (flags == THREAD_SAME_SPACE) {
TASK_PGD(new) = TASK_PGD(task);
} else {
TASK_PGD(new) = copy_page_tables(TASK_PGD(task));
if (IS_ERR(TASK_PGD(new))) {
err = (int)TASK_PGD(new);
free_page(new);
return err;
}
}
goto out;
}
}
printk("Could not find given space, is "
"SAMESPC/COPYSPC the right flag?\n");
BUG();
}
out:
/* Set up new thread's tid, spid, tgid according to flags */
thread_setup_new_ids(ids, create_flags, new, task);
/* Initialise task's scheduling state and parameters. */
sched_init_task(new, TASK_PRIO_NORMAL);
/* Initialise ipc waitqueues */
waitqueue_head_init(&new->wqh_send);
waitqueue_head_init(&new->wqh_recv);
waitqueue_head_init(&new->wqh_pager);
arch_setup_new_thread(new, task, flags);
/* Add task to global hlist of tasks */
add_task_global(new);
return 0;
}
#endif
/*
* Creates, destroys and modifies threads. Also implicitly creates an address
* space for a thread that doesn't already have one, or destroys it if the last