mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 10:53:16 +01:00
Cleaned up thread_control functions
This commit is contained in:
117
src/api/thread.c
117
src/api/thread.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user