summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2000-11-10 23:04:31 +0000
committergallatin <gallatin@FreeBSD.org>2000-11-10 23:04:31 +0000
commitfd17851060a93753f322c9e45673f13bb2c85d2a (patch)
treeec8dd39103c738c43188be0dd5d349c8b5b69ff0 /sys/alpha
parentc03313d48cad747472e8ec6dccd9fed36cb91db7 (diff)
downloadFreeBSD-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/alpha')
-rw-r--r--sys/alpha/linux/linux_machdep.c58
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)
OpenPOWER on IntegriCloud