Commit Diff


commit - ac8042dfa9819f76ccfedd4aa36c1239322808b8
commit + 41b3e8b9893a8561af7e85ca98444bc284b4013d
blob - /dev/null
blob + 3afa9513d97534d4401817da869424a847af4beb (mode 644)
--- /dev/null
+++ src/libthread/386-ucontext.c
@@ -0,0 +1,22 @@
+#include "threadimpl.h"
+
+void
+makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+{
+	int *sp;
+
+	sp = USPALIGN(ucp, 4);
+	sp -= argc;
+	memmove(sp, &argc+1, argc*sizeof(int));
+	*--sp = 0;		/* return address */
+	ucp->uc_mcontext.mc_eip = (long)func;
+	ucp->uc_mcontext.mc_esp = (int)sp;
+}
+
+int
+swapcontext(ucontext_t *oucp, ucontext_t *ucp)
+{
+	if(getcontext(oucp) == 0)
+		setcontext(ucp);
+	return 0;
+}
blob - f4ee354e94347f79787957d81a0db4bff135c7ea
blob + d08209658645fa4da5639b1b0c124d3d85dc2bb5
--- src/libthread/COPYRIGHT
+++ src/libthread/COPYRIGHT
@@ -45,9 +45,9 @@ Contains parts of an earlier library that has:
 
 ===
 
-The above notices do *NOT* apply to Linux-sparc64-context.S 
-or to Linux-sparc64-swapcontext.c.  Those are functions from 
+The above notices do *NOT* apply to Linux-sparc64-context.S
+or to sparc64-ucontext.c.  Those are functions from
 the GNU C library and are provided for systems that use the GNU C
-library but somehow are missing those functions.  They are 
+library but somehow are missing those functions.  They are
 distributed under the Lesser GPL; see COPYING.SPARC64-CONTEXT.
 
blob - c29ddb5ee16e74c4f549477efa7d656ee2940f15 (mode 644)
blob + /dev/null
--- src/libthread/Darwin-x86_64-swapcontext.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "threadimpl.h"
-
-void
-makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
-{
-	uintptr *sp;
-	va_list arg;
-
-//fprint(2, "makecontext %d\n", argc);
-	if(argc != 2)
-		sysfatal("libthread: makecontext misused");
-	va_start(arg, argc);
-	uc->mc.di = va_arg(arg, uint);
-	uc->mc.si = va_arg(arg, uint);
-//fprint(2, "%ux %ux\n", uc->mc.di, uc->mc.si);
-	va_end(arg);
-
-	sp = (uintptr*)((char*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size);
-	/*
-	 * Stack pointer at call instruction (before return address
-	 * gets pushed) must be 16-byte aligned.
-	 */
-	if((uintptr)sp%4)
-		abort();
-	while((uintptr)sp%16 != 0)
-		sp--;
-	*--sp = 0;  // fn's return address
-	*--sp = (uintptr)fn;  // return address of setcontext
-	uc->mc.sp = (uintptr)sp;
-}
-
-int
-swapcontext(ucontext_t *oucp, ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
blob - fc0dfddaa03cbd92f88456486f189585fc73b24f (mode 644)
blob + /dev/null
--- src/libthread/Linux-arm-swapcontext.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "threadimpl.h"
-
-void
-makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
-{
-	int i, *sp;
-	va_list arg;
-
-	sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
-	va_start(arg, argc);
-	for(i=0; i<4 && i<argc; i++)
-		(&uc->uc_mcontext.arm_r0)[i] = va_arg(arg, uint);
-	va_end(arg);
-	uc->uc_mcontext.arm_sp = (uint)sp;
-	uc->uc_mcontext.arm_lr = (uint)fn;
-}
-
-int
-swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
blob - e4800c19ccb07521c5448fefd34f52ee05519dbd (mode 644)
blob + /dev/null
--- src/libthread/Linux-sparc64-swapcontext.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <ucontext.h>
-
-#define UC_M_PC 40
-#define UC_M_NPC 48
-
-extern int __getcontext (ucontext_t *ucp);
-extern int __setcontext (const ucontext_t *ucp, int restoremask);
-
-int
-swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
-{
-  extern void __swapcontext_ret (void);
-  /* Save the current machine context to oucp.  */
-  __getcontext (oucp);
-  /* Modify oucp to skip the __setcontext call on reactivation.  */
-  *(long*)((char*)oucp+UC_M_PC) = (long)__swapcontext_ret;
-  *(long*)((char*)oucp+UC_M_NPC) = (long)__swapcontext_ret + 4;
-  /* Restore the machine context in ucp.  */
-  __setcontext (ucp, 1);
-  return 0;
-}
-
-asm ("							\n\
-	.text						\n\
-	.type	__swapcontext_ret, #function		\n\
-__swapcontext_ret:					\n\
-	return	%i7 + 8					\n\
-	 clr	%o0					\n\
-	.size	__swapcontext_ret, .-__swapcontext_ret	\n\
-     ");
blob - 31577e876dc7be7d2c6d59e67e02887eadf5c25c
blob + 2b14146b839641a7bd827ec0bf92794d6a497ce3
--- src/libthread/NetBSD.c
+++ src/libthread/NetBSD.c
@@ -435,28 +435,3 @@ _threadpexit(void)
 {
 	_exit(0);
 }
-
-#ifdef __arm__
-void
-makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
-{
-	int i, *sp;
-	va_list arg;
-
-	sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
-	va_start(arg, argc);
-	for(i=0; i<4 && i<argc; i++)
-		uc->uc_mcontext.gregs[i] = va_arg(arg, uint);
-	va_end(arg);
-	uc->uc_mcontext.gregs[13] = (uint)sp;
-	uc->uc_mcontext.gregs[14] = (uint)fn;
-}
-
-int
-swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
-#endif
blob - 89bfedcd985079d81b12d77062db6bb55de5994b (mode 644)
blob + /dev/null
--- src/libthread/OpenBSD-386.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "threadimpl.h"
-
-void
-makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
-{
-	int *sp;
-
-	sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4;
-	sp -= argc;
-	memmove(sp, &argc+1, argc*sizeof(int));
-	*--sp = 0;		/* return address */
-	ucp->uc_mcontext.mc_eip = (long)func;
-	ucp->uc_mcontext.mc_esp = (int)sp;
-}
-
-int
-swapcontext(ucontext_t *oucp, ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
blob - /dev/null
blob + 512ca973d4a491e20365d0e2cbede5a350c881ed (mode 644)
--- /dev/null
+++ src/libthread/arm-ucontext.c
@@ -0,0 +1,24 @@
+#include "threadimpl.h"
+
+void
+makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
+{
+	int i, *sp;
+	va_list arg;
+
+	sp = USPALIGN(uc, 4);
+	va_start(arg, argc);
+	for(i=0; i<4 && i<argc; i++)
+		(&uc->uc_mcontext.arm_r0)[i] = va_arg(arg, uint);
+	va_end(arg);
+	uc->uc_mcontext.arm_sp = (uint)sp;
+	uc->uc_mcontext.arm_lr = (uint)fn;
+}
+
+int
+swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+{
+	if(getcontext(oucp) == 0)
+		setcontext(ucp);
+	return 0;
+}
blob - eab711f22577a9910515ee3a005484968de34977 (mode 644)
blob + /dev/null
--- src/libthread/OpenBSD-power.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "threadimpl.h"
-
-void
-makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
-{
-	ulong *sp, *tos;
-	va_list arg;
-
-	tos = (ulong*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(ulong);
-	sp = (ulong*)((ulong)(tos-16) & ~15);
-	ucp->mc.pc = (long)func;
-	ucp->mc.sp = (long)sp;
-	va_start(arg, argc);
-	ucp->mc.r3 = va_arg(arg, long);
-	va_end(arg);
-}
-
-int
-swapcontext(ucontext_t *oucp, ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
blob - 27931456d6d0d9bf6377056fe280ef31437c4a62 (mode 644)
blob + /dev/null
--- src/libthread/OpenBSD-x86_64.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "threadimpl.h"
-
-void
-makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
-{
-	uintptr *sp;
-	va_list arg;
-
-//fprint(2, "makecontext %d\n", argc);
-	if(argc != 2)
-		sysfatal("libthread: makecontext misused");
-	va_start(arg, argc);
-	uc->mc.di = va_arg(arg, uint);
-	uc->mc.si = va_arg(arg, uint);
-//fprint(2, "%ux %ux\n", uc->mc.di, uc->mc.si);
-	va_end(arg);
-
-	sp = (uintptr*)((char*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size);
-	*--sp = 0;  // fn's return address
-	*--sp = (uintptr)fn;  // return address of setcontext
-	uc->mc.sp = (uintptr)sp;
-}
-
-int
-swapcontext(ucontext_t *oucp, ucontext_t *ucp)
-{
-	if(getcontext(oucp) == 0)
-		setcontext(ucp);
-	return 0;
-}
blob - /dev/null
blob + 32a8e931f3a1218b554ab9a2749502a6b3ceb827 (mode 644)
--- /dev/null
+++ src/libthread/power-ucontext.c
@@ -0,0 +1,26 @@
+#include "threadimpl.h"
+
+void
+makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+{
+	ulong *sp, *tos;
+	va_list arg;
+
+	if(argc != 2)
+		sysfatal("libthread: makecontext misused");
+	sp = USPALIGN(ucp, 16);
+	ucp->mc.pc = (long)func;
+	ucp->mc.sp = (long)sp;
+	va_start(arg, argc);
+	ucp->mc.r3 = va_arg(arg, long);
+	ucp->mc.r4 = va_arg(arg, long);
+	va_end(arg);
+}
+
+int
+swapcontext(ucontext_t *oucp, ucontext_t *ucp)
+{
+	if(getcontext(oucp) == 0)
+		setcontext(ucp);
+	return 0;
+}
blob - a083fd013fe9741647b61ee5888dc96d49aa5487
blob + 45b7803931535e8f2834cbe8661a8c6798ede420
--- src/libthread/mkfile
+++ src/libthread/mkfile
@@ -37,8 +37,8 @@ OpenBSD-%-asm.$O:	OpenBSD-%-asm.S
 Linux-sparc64-context.$O: Linux-sparc64-context.S
 	$CC -m64 -mcpu=v9 $CFLAGS Linux-sparc64-context.S
 
-Linux-sparc64-swapcontext.$O: Linux-sparc64-swapcontext.c
-	$CC -m64 -mcpu=v9 $CFLAGS Linux-sparc64-swapcontext.c
+sparc64-ucontext.$O: sparc64-ucontext.c
+	$CC -m64 -mcpu=v9 $CFLAGS sparc64-ucontext.c
 
 test:V: tprimes tspawn
 	primes 1 10007 >p1.txt
blob - /dev/null
blob + e4800c19ccb07521c5448fefd34f52ee05519dbd (mode 644)
--- /dev/null
+++ src/libthread/sparc64-ucontext.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <ucontext.h>
+
+#define UC_M_PC 40
+#define UC_M_NPC 48
+
+extern int __getcontext (ucontext_t *ucp);
+extern int __setcontext (const ucontext_t *ucp, int restoremask);
+
+int
+swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+  extern void __swapcontext_ret (void);
+  /* Save the current machine context to oucp.  */
+  __getcontext (oucp);
+  /* Modify oucp to skip the __setcontext call on reactivation.  */
+  *(long*)((char*)oucp+UC_M_PC) = (long)__swapcontext_ret;
+  *(long*)((char*)oucp+UC_M_NPC) = (long)__swapcontext_ret + 4;
+  /* Restore the machine context in ucp.  */
+  __setcontext (ucp, 1);
+  return 0;
+}
+
+asm ("							\n\
+	.text						\n\
+	.type	__swapcontext_ret, #function		\n\
+__swapcontext_ret:					\n\
+	return	%i7 + 8					\n\
+	 clr	%o0					\n\
+	.size	__swapcontext_ret, .-__swapcontext_ret	\n\
+     ");
blob - 9a7301a8edb2a6095ade273e2f787d80baac48c6
blob + 8a65d0f63e8d072129de86e98ef1c180e21f463e
--- src/libthread/sysofiles.sh
+++ src/libthread/sysofiles.sh
@@ -7,24 +7,37 @@ NetBSD)
 	echo ${SYSNAME}-${OBJTYPE}-asm.o $SYSNAME.o stkmalloc.o
 	;;
 OpenBSD)
-	echo ${SYSNAME}-${OBJTYPE}-asm.o ${SYSNAME}-${OBJTYPE}.o pthread.o stkmmap.o
+	echo ${SYSNAME}-${OBJTYPE}-asm.o pthread.o stkmmap.o
 	;;
 *)
 	echo pthread.o stkmalloc.o
 esac
 
+# Various libc don't supply swapcontext, makecontext, so we do.
 case "$OBJTYPE-$SYSNAME" in
-sparc64-Linux)
-	# Debian glibc doesn't supply swapcontext, makecontext
-	# so we supply our own copy from the latest glibc.
-	echo Linux-sparc64-context.o Linux-sparc64-swapcontext.o
+386-OpenBSD)
+	echo 386-ucontext.o
 	;;
 arm-Linux)
-	# ARM doesn't supply them either.
-	echo Linux-arm-context.o Linux-arm-swapcontext.o
+	echo arm-ucontext.o
+	echo Linux-arm-context.o # setcontext, getcontext
 	;;
+arm-NetBSD)
+	echo arm-ucontext.o
+	;;
+power-OpenBSD)
+	echo power-ucontext.o
+	;;
+sparc64-Linux)
+	echo sparc64-ucontext.o
+	echo Linux-sparc64-swapcontext.o # setcontext, getcontext
+	;;
 x86_64-Darwin)
-	echo Darwin-x86_64-asm.o Darwin-x86_64-swapcontext.o
+	echo x86_64-ucontext.o
+	echo Darwin-x86_64-asm.o # setcontext, getcontext
 	;;
+x86_64-OpenBSD)
+	echo x86_64-ucontext.o
+	;;
 esac
 
blob - 5b6d74cc84ba42dbb6accb5d3310c98857b59805
blob + cceb1b8e7cc0628c4aeb3f23f36fb7e582c97e33
--- src/libthread/threadimpl.h
+++ src/libthread/threadimpl.h
@@ -188,3 +188,6 @@ extern void _threadpexit(void);
 extern void _threaddaemonize(void);
 extern void *_threadstkalloc(int);
 extern void _threadstkfree(void*, int);
+
+#define USPALIGN(ucp, align) \
+	(void*)((((uintptr)(ucp)->uc_stack.ss_sp+(ucp)->uc_stack.ss_size)-(align))&~((align)-1))
blob - /dev/null
blob + 5d1aaefc152c2a723cb9b1f20e2bc9a579cb47e6 (mode 644)
--- /dev/null
+++ src/libthread/x86_64-ucontext.c
@@ -0,0 +1,28 @@
+#include "threadimpl.h"
+
+void
+makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
+{
+	uintptr *sp;
+	va_list arg;
+
+	if(argc != 2)
+		sysfatal("libthread: makecontext misused");
+	va_start(arg, argc);
+	uc->mc.di = va_arg(arg, uint);
+	uc->mc.si = va_arg(arg, uint);
+	va_end(arg);
+
+	sp = USPALIGN(uc, 16);
+	*--sp = 0;  // fn's return address
+	*--sp = (uintptr)fn;  // return address of setcontext
+	uc->mc.sp = (uintptr)sp;
+}
+
+int
+swapcontext(ucontext_t *oucp, ucontext_t *ucp)
+{
+	if(getcontext(oucp) == 0)
+		setcontext(ucp);
+	return 0;
+}