mirror of
https://github.com/drasko/codezero.git
synced 2026-04-18 01:39:05 +02:00
Neater thread creation flags.
This commit is contained in:
@@ -22,11 +22,6 @@ int sys_fork(struct tcb *parent)
|
|||||||
struct tcb *child;
|
struct tcb *child;
|
||||||
struct exregs_data exregs;
|
struct exregs_data exregs;
|
||||||
struct task_ids ids;
|
struct task_ids ids;
|
||||||
// = {
|
|
||||||
// .tid = TASK_ID_INVALID,
|
|
||||||
// .spid = parent->spid, /* spid to copy from */
|
|
||||||
// .tgid = TASK_ID_INVALID, /* FIXME: !!! FIX THIS */
|
|
||||||
// };
|
|
||||||
|
|
||||||
/* Make all shadows in this task read-only */
|
/* Make all shadows in this task read-only */
|
||||||
vm_freeze_shadows(parent);
|
vm_freeze_shadows(parent);
|
||||||
@@ -36,8 +31,8 @@ int sys_fork(struct tcb *parent)
|
|||||||
* kernel stack and kernel-side tcb copied
|
* kernel stack and kernel-side tcb copied
|
||||||
*/
|
*/
|
||||||
if (IS_ERR(child = task_create(parent, &ids,
|
if (IS_ERR(child = task_create(parent, &ids,
|
||||||
THREAD_COPY_SPACE,
|
TCB_NO_SHARING,
|
||||||
TCB_NO_SHARING)))
|
TC_COPY_SPACE)))
|
||||||
return (int)child;
|
return (int)child;
|
||||||
|
|
||||||
/* Set child's fork return value to 0 */
|
/* Set child's fork return value to 0 */
|
||||||
@@ -64,27 +59,17 @@ int sys_fork(struct tcb *parent)
|
|||||||
return child->tid;
|
return child->tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_clone(struct tcb *parent,
|
int do_clone(struct tcb *parent, unsigned long child_stack,
|
||||||
unsigned long child_stack,
|
unsigned int flags, unsigned int sysflags)
|
||||||
unsigned int flags)
|
|
||||||
{
|
{
|
||||||
struct exregs_data exregs;
|
struct exregs_data exregs;
|
||||||
struct task_ids ids;
|
struct task_ids ids;
|
||||||
struct tcb *child;
|
struct tcb *child;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine whether the cloned
|
|
||||||
* thread is in parent's thread group
|
|
||||||
*/
|
|
||||||
if (flags & TCB_SHARED_TGROUP)
|
|
||||||
ids.tgid = parent->tgid;
|
|
||||||
else
|
|
||||||
ids.tgid = TASK_ID_INVALID;
|
|
||||||
|
|
||||||
if (IS_ERR(child = task_create(parent, &ids,
|
if (IS_ERR(child = task_create(parent, &ids,
|
||||||
THREAD_SAME_SPACE,
|
flags,
|
||||||
flags)))
|
sysflags)))
|
||||||
return (int)child;
|
return (int)child;
|
||||||
|
|
||||||
/* Set up child stack marks with given stack argument */
|
/* Set up child stack marks with given stack argument */
|
||||||
@@ -122,23 +107,28 @@ int sys_clone(struct tcb *parent,
|
|||||||
unsigned int clone_flags)
|
unsigned int clone_flags)
|
||||||
{
|
{
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
|
unsigned int sysflags = 0;
|
||||||
|
|
||||||
if (!child_stack)
|
if (!child_stack)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (clone_flags & CLONE_VM)
|
if (clone_flags & CLONE_VM) {
|
||||||
flags |= TCB_SHARED_VM;
|
flags |= TCB_SHARED_VM;
|
||||||
|
sysflags |= TC_SHARE_SPACE;
|
||||||
|
}
|
||||||
if (clone_flags & CLONE_FS)
|
if (clone_flags & CLONE_FS)
|
||||||
flags |= TCB_SHARED_FS;
|
flags |= TCB_SHARED_FS;
|
||||||
if (clone_flags & CLONE_FILES)
|
if (clone_flags & CLONE_FILES)
|
||||||
flags |= TCB_SHARED_FILES;
|
flags |= TCB_SHARED_FILES;
|
||||||
if (clone_flags & CLONE_THREAD)
|
if (clone_flags & CLONE_THREAD) {
|
||||||
flags |= TCB_SHARED_TGROUP;
|
flags |= TCB_SHARED_TGROUP;
|
||||||
|
sysflags |= TC_SHARE_GROUP;
|
||||||
|
}
|
||||||
if (clone_flags & CLONE_PARENT)
|
if (clone_flags & CLONE_PARENT)
|
||||||
flags |= TCB_SHARED_PARENT;
|
flags |= TCB_SHARED_PARENT;
|
||||||
|
|
||||||
return do_clone(parent,
|
return do_clone(parent,
|
||||||
(unsigned long)child_stack,
|
(unsigned long)child_stack,
|
||||||
flags);
|
flags, sysflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ int init_execve(char *filepath)
|
|||||||
vmfile = self->files->fd[fd].vmfile;
|
vmfile = self->files->fd[fd].vmfile;
|
||||||
|
|
||||||
if (IS_ERR(new_task = task_create(0, &ids,
|
if (IS_ERR(new_task = task_create(0, &ids,
|
||||||
THREAD_NEW_SPACE,
|
TCB_NO_SHARING,
|
||||||
TCB_NO_SHARING))) {
|
TC_NEW_SPACE))) {
|
||||||
sys_close(self, fd);
|
sys_close(self, fd);
|
||||||
return (int)new_task;
|
return (int)new_task;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int share_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
|
struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
|
||||||
unsigned int ctrl_flags, unsigned int share_flags)
|
unsigned int share_flags, unsigned int ctrl_flags)
|
||||||
{
|
{
|
||||||
struct tcb *task;
|
struct tcb *task;
|
||||||
int err;
|
int err;
|
||||||
@@ -354,15 +354,7 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
|
|||||||
if (parent) {
|
if (parent) {
|
||||||
ids->tid = parent->tid;
|
ids->tid = parent->tid;
|
||||||
ids->spid = parent->spid;
|
ids->spid = parent->spid;
|
||||||
|
ids->tgid = parent->tgid;
|
||||||
/*
|
|
||||||
* Determine whether the cloned thread
|
|
||||||
* is in parent's thread group
|
|
||||||
*/
|
|
||||||
if (share_flags & TCB_SHARED_TGROUP)
|
|
||||||
ids->tgid = parent->tgid;
|
|
||||||
else
|
|
||||||
ids->tgid = TASK_ID_INVALID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the thread structures and address space */
|
/* Create the thread structures and address space */
|
||||||
|
|||||||
@@ -1,30 +1,21 @@
|
|||||||
#ifndef __THREAD_H__
|
#ifndef __THREAD_H__
|
||||||
#define __THREAD_H__
|
#define __THREAD_H__
|
||||||
|
|
||||||
#define THREAD_CREATE_MASK 0x0030
|
#define THREAD_ACTION_MASK 0x000F
|
||||||
|
#define THREAD_CREATE 0x0000
|
||||||
|
#define THREAD_RUN 0x0001
|
||||||
|
#define THREAD_SUSPEND 0x0002
|
||||||
|
#define THREAD_RESUME 0x0003
|
||||||
|
#define THREAD_DESTROY 0x0004
|
||||||
|
#define THREAD_RECYCLE 0x0005
|
||||||
|
|
||||||
/* Create new thread and new space */
|
#define THREAD_CREATE_MASK 0x03F0
|
||||||
#define THREAD_NEW_SPACE 0x0010
|
#define TC_SHARE_CAPS 0x0010 /* Share all thread capabilities */
|
||||||
|
#define TC_SHARE_UTCB 0x0020 /* Share utcb location (same space */
|
||||||
/* Create new thread, copy given space */
|
#define TC_SHARE_GROUP 0x0040 /* Share thread group id */
|
||||||
#define THREAD_COPY_SPACE 0x0020
|
#define TC_SHARE_SPACE 0x0080 /* New thread, use given space */
|
||||||
|
#define TC_COPY_SPACE 0x0100 /* New thread, copy given space */
|
||||||
/* Create new thread, use given space */
|
#define TC_NEW_SPACE 0x0200 /* New thread, new space */
|
||||||
#define THREAD_SAME_SPACE 0x0030
|
#define TC_SHARE_PAGER 0x0400 /* New thread, shared pager */
|
||||||
|
|
||||||
/* Shared UTCB, New UTCB, No UTCB */
|
|
||||||
#define THREAD_UTCB_MASK 0x00C0
|
|
||||||
#define THREAD_UTCB_NEW 0x0040
|
|
||||||
#define THREAD_UTCB_SAME 0x0080
|
|
||||||
#define THREAD_UTCB_NONE 0x00C0
|
|
||||||
|
|
||||||
|
|
||||||
#define THREAD_ACTION_MASK 0x000F
|
|
||||||
#define THREAD_CREATE 0x0000
|
|
||||||
#define THREAD_RUN 0x0001
|
|
||||||
#define THREAD_SUSPEND 0x0002
|
|
||||||
#define THREAD_RESUME 0x0003
|
|
||||||
#define THREAD_DESTROY 0x0004
|
|
||||||
#define THREAD_RECYCLE 0x0005
|
|
||||||
|
|
||||||
#endif /* __THREAD_H__ */
|
#endif /* __THREAD_H__ */
|
||||||
|
|||||||
@@ -242,19 +242,19 @@ int arch_setup_new_thread(struct ktcb *new, struct ktcb *orig,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
/* New threads just need their mode set up */
|
/* New threads just need their mode set up */
|
||||||
if ((flags & THREAD_CREATE_MASK) == THREAD_NEW_SPACE) {
|
if (flags & TC_NEW_SPACE) {
|
||||||
BUG_ON(orig);
|
BUG_ON(orig);
|
||||||
new->context.spsr = ARM_MODE_USR;
|
new->context.spsr = ARM_MODE_USR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUG_ON(!orig);
|
||||||
/*
|
/*
|
||||||
* For duplicated threads pre-syscall context is saved on
|
* For duplicated threads pre-syscall context is saved on
|
||||||
* the kernel stack. We copy this context of original
|
* the kernel stack. We copy this context of original
|
||||||
* into the duplicate thread's current context structure
|
* into the duplicate thread's current context structure
|
||||||
*
|
*
|
||||||
* We don't lock for context modification because the
|
* No locks needed as the thread is not known to the system yet.
|
||||||
* thread is not known to the system yet.
|
|
||||||
*/
|
*/
|
||||||
BUG_ON(!(new->context.spsr = orig->syscall_regs->spsr)); /* User mode */
|
BUG_ON(!(new->context.spsr = orig->syscall_regs->spsr)); /* User mode */
|
||||||
new->context.r0 = orig->syscall_regs->r0;
|
new->context.r0 = orig->syscall_regs->r0;
|
||||||
@@ -281,37 +281,18 @@ int arch_setup_new_thread(struct ktcb *new, struct ktcb *orig,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static inline void
|
||||||
* Sets up the thread, thread group and space id of newly created thread
|
thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
||||||
* according to supplied flags.
|
struct ktcb *new, struct ktcb *orig)
|
||||||
*/
|
|
||||||
int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
|
||||||
struct ktcb *new, struct ktcb *orig)
|
|
||||||
{
|
{
|
||||||
|
if (flags & TC_SHARE_GROUP)
|
||||||
|
new->tgid = orig->tgid;
|
||||||
|
else
|
||||||
|
new->tgid = new->tid;
|
||||||
|
|
||||||
|
/* Update ids to be returned back to caller */
|
||||||
ids->tid = new->tid;
|
ids->tid = new->tid;
|
||||||
|
ids->tgid = new->tgid;
|
||||||
/*
|
|
||||||
* If thread space is new or copied,
|
|
||||||
* thread gets same group id as its thread id
|
|
||||||
*/
|
|
||||||
if (flags == THREAD_NEW_SPACE ||
|
|
||||||
flags == THREAD_COPY_SPACE) {
|
|
||||||
ids->tgid = ids->tid;
|
|
||||||
new->tgid = new->tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the tgid of original thread is supplied, that implies the
|
|
||||||
* new thread wants to be in the same group, and we leave it as
|
|
||||||
* it is. Otherwise the thread gets the same group id as its
|
|
||||||
* unique thread id.
|
|
||||||
*/
|
|
||||||
if (flags == THREAD_SAME_SPACE && ids->tgid != orig->tgid) {
|
|
||||||
ids->tgid = ids->tid;
|
|
||||||
new->tgid = new->tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flags)
|
int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flags)
|
||||||
@@ -321,14 +302,14 @@ int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flag
|
|||||||
|
|
||||||
address_space_reference_lock();
|
address_space_reference_lock();
|
||||||
|
|
||||||
if (flags == THREAD_SAME_SPACE) {
|
if (flags & TC_SHARE_SPACE) {
|
||||||
if (!(space = address_space_find(ids->spid))) {
|
if (!(space = address_space_find(ids->spid))) {
|
||||||
ret = -ESRCH;
|
ret = -ESRCH;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
address_space_attach(tcb, space);
|
address_space_attach(tcb, space);
|
||||||
}
|
}
|
||||||
if (flags == THREAD_COPY_SPACE) {
|
if (flags & TC_COPY_SPACE) {
|
||||||
if (!(space = address_space_find(ids->spid))) {
|
if (!(space = address_space_find(ids->spid))) {
|
||||||
ret = -ESRCH;
|
ret = -ESRCH;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -342,7 +323,7 @@ int thread_setup_space(struct ktcb *tcb, struct task_ids *ids, unsigned int flag
|
|||||||
address_space_attach(tcb, new);
|
address_space_attach(tcb, new);
|
||||||
address_space_add(new);
|
address_space_add(new);
|
||||||
}
|
}
|
||||||
if (flags == THREAD_NEW_SPACE) {
|
if (flags & TC_NEW_SPACE) {
|
||||||
if (IS_ERR(new = address_space_create(0))) {
|
if (IS_ERR(new = address_space_create(0))) {
|
||||||
ret = (int)new;
|
ret = (int)new;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -364,8 +345,22 @@ int thread_create(struct task_ids *ids, unsigned int flags)
|
|||||||
struct ktcb *parent = 0;
|
struct ktcb *parent = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* Clear flags to just include creation flags */
|
||||||
flags &= THREAD_CREATE_MASK;
|
flags &= THREAD_CREATE_MASK;
|
||||||
|
|
||||||
|
/* Can't have multiple space directives in flags */
|
||||||
|
if ((flags & TC_SHARE_SPACE & TC_COPY_SPACE & TC_NEW_SPACE)
|
||||||
|
|| !flags)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Can't request shared utcb or tgid without shared space */
|
||||||
|
if (!(flags & TC_SHARE_SPACE)) {
|
||||||
|
if ((flags & TC_SHARE_UTCB) ||
|
||||||
|
(flags & TC_SHARE_GROUP)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(new = tcb_alloc_init()))
|
if (!(new = tcb_alloc_init()))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -374,8 +369,7 @@ int thread_create(struct task_ids *ids, unsigned int flags)
|
|||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
/* Obtain parent thread if there is one */
|
/* Obtain parent thread if there is one */
|
||||||
if (flags == THREAD_SAME_SPACE ||
|
if (flags & TC_SHARE_SPACE || flags & TC_COPY_SPACE) {
|
||||||
flags == THREAD_COPY_SPACE) {
|
|
||||||
if (!(parent = tcb_find(ids->tid))) {
|
if (!(parent = tcb_find(ids->tid))) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|||||||
Reference in New Issue
Block a user