mirror of
https://github.com/drasko/codezero.git
synced 2026-07-12 18:34:11 +02: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,
|
int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
||||||
struct ktcb *new, struct ktcb *orig)
|
struct ktcb *new, struct ktcb *orig)
|
||||||
{
|
{
|
||||||
/* For tid, allocate requested id if it's available, else a new one */
|
/* Allocate a new id */
|
||||||
if ((ids->tid = id_get(thread_id_pool, ids->tid)) < 0)
|
ids->tid = id_new(thread_id_pool);
|
||||||
ids->tid = id_new(thread_id_pool);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If thread space is new or copied,
|
* 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;
|
ret = (int)new;
|
||||||
goto out;
|
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_attach(tcb, new);
|
||||||
address_space_add(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;
|
ret = (int)new;
|
||||||
goto out;
|
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_attach(tcb, new);
|
||||||
address_space_add(new);
|
address_space_add(new);
|
||||||
}
|
}
|
||||||
@@ -300,107 +301,43 @@ out:
|
|||||||
|
|
||||||
int thread_create(struct task_ids *ids, unsigned int flags)
|
int thread_create(struct task_ids *ids, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct ktcb *new, *orig_task = 0;
|
struct ktcb *new;
|
||||||
|
struct ktcb *parent;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
flags &= THREAD_CREATE_MASK;
|
flags &= THREAD_CREATE_MASK;
|
||||||
|
parent = 0;
|
||||||
|
|
||||||
if (!(new = tcb_alloc_init()))
|
if (!(new = tcb_alloc_init()))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (flags == THREAD_SAME_SPACE || flags == THREAD_COPY_SPACE) {
|
/* Set up new thread space by using space id and flags */
|
||||||
if (!(orig_task = tcb_find(ids->tid))) {
|
if ((err = thread_setup_space(new, ids, flags)) < 0)
|
||||||
/* Pre-mature tcb needs freeing by free_page */
|
goto out_err;
|
||||||
free_page(new);
|
|
||||||
return -EINVAL;
|
/* 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) {
|
/* Set up new thread context by using parent ids and flags */
|
||||||
/* Pre-mature tcb needs freeing by free_page */
|
thread_setup_new_ids(ids, flags, new, parent);
|
||||||
free_page(new);
|
arch_setup_new_thread(new, parent, flags);
|
||||||
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);
|
|
||||||
|
|
||||||
tcb_add(new);
|
tcb_add(new);
|
||||||
|
|
||||||
return 0;
|
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
|
* 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
|
* space for a thread that doesn't already have one, or destroys it if the last
|
||||||
|
|||||||
Reference in New Issue
Block a user