diff options
author | gallatin <gallatin@FreeBSD.org> | 2000-11-10 23:04:31 +0000 |
---|---|---|
committer | gallatin <gallatin@FreeBSD.org> | 2000-11-10 23:04:31 +0000 |
commit | fd17851060a93753f322c9e45673f13bb2c85d2a (patch) | |
tree | ec8dd39103c738c43188be0dd5d349c8b5b69ff0 /sys | |
parent | c03313d48cad747472e8ec6dccd9fed36cb91db7 (diff) | |
download | FreeBSD-src-fd17851060a93753f322c9e45673f13bb2c85d2a.zip FreeBSD-src-fd17851060a93753f322c9e45673f13bb2c85d2a.tar.gz |
Enable linux thread support on the alpha. The guts of linux_clone was
mainly cut-n-pasted from the i386 port, except for the method of setting
the child's stack which is the only MD part of this function.
I've tested with the example apps shipped with the linux threads source
code (ex1-ex6) and with several binary builds of Mozilla.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/linux/linux_machdep.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/sys/alpha/linux/linux_machdep.c b/sys/alpha/linux/linux_machdep.c index fc8f96f..3e51d89 100644 --- a/sys/alpha/linux/linux_machdep.c +++ b/sys/alpha/linux/linux_machdep.c @@ -33,6 +33,7 @@ #include <sys/mount.h> #include <sys/sysproto.h> #include <sys/systm.h> +#include <sys/unistd.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -115,7 +116,62 @@ linux_vfork(struct proc *p, struct linux_vfork_args *args) int linux_clone(struct proc *p, struct linux_clone_args *args) { - return ENOSYS; + int error, ff = RFPROC; + struct proc *p2; + int exit_signal; + vm_offset_t start; + struct rfork_args rf_args; + +#ifdef DEBUG + if (args->flags & CLONE_PID) + printf("linux_clone(%ld): CLONE_PID not yet supported\n", + (long)p->p_pid); + uprintf("linux_clone(%ld): invoked with flags 0x%x and stack %p\n", + (long)p->p_pid, (unsigned int)args->flags, + args->stack); +#endif + + if (!args->stack) + return (EINVAL); + + exit_signal = args->flags & 0x000000ff; + if (exit_signal >= LINUX_NSIG) + return (EINVAL); + +/* if (exit_signal <= LINUX_SIGTBLSZ) + exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; +*/ + /* RFTHREAD probably not necessary here, but it shouldn't hurt */ + ff |= RFTHREAD; + + if (args->flags & CLONE_VM) + ff |= RFMEM; + if (args->flags & CLONE_SIGHAND) + ff |= RFSIGSHARE; + if (!(args->flags & CLONE_FILES)) + ff |= RFFDG; + + error = 0; + start = 0; + + rf_args.flags = ff; + if ((error = rfork(p, &rf_args)) != 0) + return (error); + + p2 = pfind(p->p_retval[0]); + if (p2 == 0) + return (ESRCH); + + p2->p_sigparent = exit_signal; + p2->p_addr->u_pcb.pcb_hw.apcb_usp = (unsigned long)args->stack; + +#ifdef DEBUG + uprintf ("linux_clone(%ld): successful rfork to %ld, stack %p, sig = %d\n", +(long)p->p_pid, (long)p2->p_pid, args->stack, exit_signal); +#endif + + return (0); + } #define STACK_SIZE (2 * 1024 * 1024) |