Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/cloudabi64/cloudabi64_thread.c
Show All 31 Lines | |||||
#include <contrib/cloudabi/cloudabi64_types.h> | #include <contrib/cloudabi/cloudabi64_types.h> | ||||
#include <compat/cloudabi64/cloudabi64_proto.h> | #include <compat/cloudabi64/cloudabi64_proto.h> | ||||
#include <compat/cloudabi64/cloudabi64_util.h> | #include <compat/cloudabi64/cloudabi64_util.h> | ||||
struct thread_create_args { | struct thread_create_args { | ||||
cloudabi64_threadattr_t attr; | cloudabi64_threadattr_t attr; | ||||
uint64_t tcb; | |||||
lwpid_t tid; | lwpid_t tid; | ||||
}; | }; | ||||
static int | static int | ||||
initialize_thread(struct thread *td, void *thunk) | initialize_thread(struct thread *td, void *thunk) | ||||
{ | { | ||||
struct thread_create_args *args = thunk; | struct thread_create_args *args = thunk; | ||||
/* Save the thread ID, so it can be returned. */ | /* Save the thread ID, so it can be returned. */ | ||||
args->tid = td->td_tid; | args->tid = td->td_tid; | ||||
/* Set up initial register contents. */ | /* Set up initial register contents. */ | ||||
cloudabi64_thread_setregs(td, &args->attr); | return (cloudabi64_thread_setregs(td, &args->attr, args->tcb)); | ||||
return (0); | |||||
} | } | ||||
int | int | ||||
cloudabi64_sys_thread_create(struct thread *td, | cloudabi64_sys_thread_create(struct thread *td, | ||||
struct cloudabi64_sys_thread_create_args *uap) | struct cloudabi64_sys_thread_create_args *uap) | ||||
{ | { | ||||
struct thread_create_args args; | struct thread_create_args args; | ||||
int error; | int error; | ||||
error = copyin(uap->attr, &args.attr, sizeof(args.attr)); | error = copyin(uap->attr, &args.attr, sizeof(args.attr)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* Remove some space on the top of the stack for the TCB. */ | |||||
args.tcb = rounddown(args.attr.stack + args.attr.stack_size - | |||||
sizeof(cloudabi64_tcb_t), _Alignof(cloudabi64_tcb_t)); | |||||
args.attr.stack_size = args.tcb - args.attr.stack; | |||||
error = thread_create(td, NULL, initialize_thread, &args); | error = thread_create(td, NULL, initialize_thread, &args); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
td->td_retval[0] = args.tid; | td->td_retval[0] = args.tid; | ||||
return (0); | return (0); | ||||
} | } |