diff --git a/conts/posix/mm0/mm/clone.c b/conts/posix/mm0/mm/clone.c index 61b001f..eec8453 100644 --- a/conts/posix/mm0/mm/clone.c +++ b/conts/posix/mm0/mm/clone.c @@ -22,11 +22,6 @@ int sys_fork(struct tcb *parent) struct tcb *child; struct exregs_data exregs; 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 */ vm_freeze_shadows(parent); @@ -36,8 +31,8 @@ int sys_fork(struct tcb *parent) * kernel stack and kernel-side tcb copied */ if (IS_ERR(child = task_create(parent, &ids, - THREAD_COPY_SPACE, - TCB_NO_SHARING))) + TCB_NO_SHARING, + TC_COPY_SPACE))) return (int)child; /* Set child's fork return value to 0 */ @@ -64,27 +59,17 @@ int sys_fork(struct tcb *parent) return child->tid; } -int do_clone(struct tcb *parent, - unsigned long child_stack, - unsigned int flags) +int do_clone(struct tcb *parent, unsigned long child_stack, + unsigned int flags, unsigned int sysflags) { struct exregs_data exregs; struct task_ids ids; struct tcb *child; 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, - THREAD_SAME_SPACE, - flags))) + flags, + sysflags))) return (int)child; /* 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 flags = 0; + unsigned int sysflags = 0; if (!child_stack) return -EINVAL; - if (clone_flags & CLONE_VM) + if (clone_flags & CLONE_VM) { flags |= TCB_SHARED_VM; + sysflags |= TC_SHARE_SPACE; + } if (clone_flags & CLONE_FS) flags |= TCB_SHARED_FS; if (clone_flags & CLONE_FILES) flags |= TCB_SHARED_FILES; - if (clone_flags & CLONE_THREAD) + if (clone_flags & CLONE_THREAD) { flags |= TCB_SHARED_TGROUP; + sysflags |= TC_SHARE_GROUP; + } if (clone_flags & CLONE_PARENT) flags |= TCB_SHARED_PARENT; return do_clone(parent, (unsigned long)child_stack, - flags); + flags, sysflags); } diff --git a/conts/posix/mm0/mm/execve.c b/conts/posix/mm0/mm/execve.c index 5da170d..93dcd99 100644 --- a/conts/posix/mm0/mm/execve.c +++ b/conts/posix/mm0/mm/execve.c @@ -79,8 +79,8 @@ int init_execve(char *filepath) vmfile = self->files->fd[fd].vmfile; 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); return (int)new_task; } diff --git a/conts/posix/mm0/mm/task.c b/conts/posix/mm0/mm/task.c index 4255e84..29e8342 100644 --- a/conts/posix/mm0/mm/task.c +++ b/conts/posix/mm0/mm/task.c @@ -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, - unsigned int ctrl_flags, unsigned int share_flags) + unsigned int share_flags, unsigned int ctrl_flags) { struct tcb *task; int err; @@ -354,15 +354,7 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, if (parent) { ids->tid = parent->tid; ids->spid = parent->spid; - - /* - * 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; + ids->tgid = parent->tgid; } /* Create the thread structures and address space */ diff --git a/include/l4/api/thread.h b/include/l4/api/thread.h index 0c5eb45..f885abc 100644 --- a/include/l4/api/thread.h +++ b/include/l4/api/thread.h @@ -1,30 +1,21 @@ #ifndef __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_NEW_SPACE 0x0010 - -/* Create new thread, copy given space */ -#define THREAD_COPY_SPACE 0x0020 - -/* Create new thread, use given space */ -#define THREAD_SAME_SPACE 0x0030 - -/* 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 +#define THREAD_CREATE_MASK 0x03F0 +#define TC_SHARE_CAPS 0x0010 /* Share all thread capabilities */ +#define TC_SHARE_UTCB 0x0020 /* Share utcb location (same space */ +#define TC_SHARE_GROUP 0x0040 /* Share thread group id */ +#define TC_SHARE_SPACE 0x0080 /* New thread, use given space */ +#define TC_COPY_SPACE 0x0100 /* New thread, copy given space */ +#define TC_NEW_SPACE 0x0200 /* New thread, new space */ +#define TC_SHARE_PAGER 0x0400 /* New thread, shared pager */ #endif /* __THREAD_H__ */ diff --git a/src/api/thread.c b/src/api/thread.c index 24c28ab..c84956b 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -242,19 +242,19 @@ int arch_setup_new_thread(struct ktcb *new, struct ktcb *orig, unsigned int flags) { /* New threads just need their mode set up */ - if ((flags & THREAD_CREATE_MASK) == THREAD_NEW_SPACE) { + if (flags & TC_NEW_SPACE) { BUG_ON(orig); new->context.spsr = ARM_MODE_USR; return 0; } + BUG_ON(!orig); /* * For duplicated threads pre-syscall context is saved on * the kernel stack. We copy this context of original * into the duplicate thread's current context structure * - * We don't lock for context modification because the - * thread is not known to the system yet. + * No locks needed as the thread is not known to the system yet. */ BUG_ON(!(new->context.spsr = orig->syscall_regs->spsr)); /* User mode */ new->context.r0 = orig->syscall_regs->r0; @@ -281,37 +281,18 @@ int arch_setup_new_thread(struct ktcb *new, struct ktcb *orig, return 0; } -/* - * Sets up the thread, thread group and space id of newly created thread - * according to supplied flags. - */ -int thread_setup_new_ids(struct task_ids *ids, unsigned int flags, - struct ktcb *new, struct ktcb *orig) +static inline void +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; - - /* - * 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; + ids->tgid = new->tgid; } 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(); - if (flags == THREAD_SAME_SPACE) { + if (flags & TC_SHARE_SPACE) { if (!(space = address_space_find(ids->spid))) { ret = -ESRCH; goto out; } address_space_attach(tcb, space); } - if (flags == THREAD_COPY_SPACE) { + if (flags & TC_COPY_SPACE) { if (!(space = address_space_find(ids->spid))) { ret = -ESRCH; 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_add(new); } - if (flags == THREAD_NEW_SPACE) { + if (flags & TC_NEW_SPACE) { if (IS_ERR(new = address_space_create(0))) { ret = (int)new; goto out; @@ -364,8 +345,22 @@ int thread_create(struct task_ids *ids, unsigned int flags) struct ktcb *parent = 0; int err; + /* Clear flags to just include creation flags */ 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())) return -ENOMEM; @@ -374,8 +369,7 @@ int thread_create(struct task_ids *ids, unsigned int flags) goto out_err; /* Obtain parent thread if there is one */ - if (flags == THREAD_SAME_SPACE || - flags == THREAD_COPY_SPACE) { + if (flags & TC_SHARE_SPACE || flags & TC_COPY_SPACE) { if (!(parent = tcb_find(ids->tid))) { err = -EINVAL; goto out_err;