aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2020-01-19 22:39:22 -0500
committerRuss Cox <rsc@swtch.com>2020-01-19 23:04:58 -0500
commit41b3e8b9893a8561af7e85ca98444bc284b4013d (patch)
treee9bf7fdeefbdb7d2e6c1ebc25c7888b81f0bb16b /src/libthread
parentac8042dfa9819f76ccfedd4aa36c1239322808b8 (diff)
downloadplan9port-41b3e8b9893a8561af7e85ca98444bc284b4013d.tar.gz
plan9port-41b3e8b9893a8561af7e85ca98444bc284b4013d.tar.bz2
plan9port-41b3e8b9893a8561af7e85ca98444bc284b4013d.zip
libthread: use consistent stack calculation code in makecontext
Also reduce duplication: makecontext is per-arch not per-os-arch. May fix #353.
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/386-ucontext.c (renamed from src/libthread/OpenBSD-386.c)2
-rw-r--r--src/libthread/COPYRIGHT6
-rw-r--r--src/libthread/Darwin-x86_64-swapcontext.c38
-rw-r--r--src/libthread/NetBSD.c25
-rw-r--r--src/libthread/arm-ucontext.c (renamed from src/libthread/Linux-arm-swapcontext.c)2
-rw-r--r--src/libthread/mkfile4
-rw-r--r--src/libthread/power-ucontext.c (renamed from src/libthread/OpenBSD-power.c)6
-rw-r--r--src/libthread/sparc64-ucontext.c (renamed from src/libthread/Linux-sparc64-swapcontext.c)0
-rw-r--r--src/libthread/sysofiles.sh29
-rw-r--r--src/libthread/threadimpl.h3
-rw-r--r--src/libthread/x86_64-ucontext.c (renamed from src/libthread/OpenBSD-x86_64.c)4
11 files changed, 36 insertions, 83 deletions
diff --git a/src/libthread/OpenBSD-386.c b/src/libthread/386-ucontext.c
index 89bfedcd..3afa9513 100644
--- a/src/libthread/OpenBSD-386.c
+++ b/src/libthread/386-ucontext.c
@@ -5,7 +5,7 @@ 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 = USPALIGN(ucp, 4);
sp -= argc;
memmove(sp, &argc+1, argc*sizeof(int));
*--sp = 0; /* return address */
diff --git a/src/libthread/COPYRIGHT b/src/libthread/COPYRIGHT
index f4ee354e..d0820965 100644
--- a/src/libthread/COPYRIGHT
+++ b/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.
diff --git a/src/libthread/Darwin-x86_64-swapcontext.c b/src/libthread/Darwin-x86_64-swapcontext.c
deleted file mode 100644
index c29ddb5e..00000000
--- a/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;
-}
diff --git a/src/libthread/NetBSD.c b/src/libthread/NetBSD.c
index 31577e87..2b14146b 100644
--- a/src/libthread/NetBSD.c
+++ b/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
diff --git a/src/libthread/Linux-arm-swapcontext.c b/src/libthread/arm-ucontext.c
index fc0dfdda..512ca973 100644
--- a/src/libthread/Linux-arm-swapcontext.c
+++ b/src/libthread/arm-ucontext.c
@@ -6,7 +6,7 @@ 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;
+ 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);
diff --git a/src/libthread/mkfile b/src/libthread/mkfile
index a083fd01..45b78039 100644
--- a/src/libthread/mkfile
+++ b/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
diff --git a/src/libthread/OpenBSD-power.c b/src/libthread/power-ucontext.c
index eab711f2..32a8e931 100644
--- a/src/libthread/OpenBSD-power.c
+++ b/src/libthread/power-ucontext.c
@@ -6,12 +6,14 @@ 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);
+ 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);
}
diff --git a/src/libthread/Linux-sparc64-swapcontext.c b/src/libthread/sparc64-ucontext.c
index e4800c19..e4800c19 100644
--- a/src/libthread/Linux-sparc64-swapcontext.c
+++ b/src/libthread/sparc64-ucontext.c
diff --git a/src/libthread/sysofiles.sh b/src/libthread/sysofiles.sh
index 9a7301a8..8a65d0f6 100644
--- a/src/libthread/sysofiles.sh
+++ b/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
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index 5b6d74cc..cceb1b8e 100644
--- a/src/libthread/threadimpl.h
+++ b/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))
diff --git a/src/libthread/OpenBSD-x86_64.c b/src/libthread/x86_64-ucontext.c
index 27931456..5d1aaefc 100644
--- a/src/libthread/OpenBSD-x86_64.c
+++ b/src/libthread/x86_64-ucontext.c
@@ -6,16 +6,14 @@ 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 = USPALIGN(uc, 16);
*--sp = 0; // fn's return address
*--sp = (uintptr)fn; // return address of setcontext
uc->mc.sp = (uintptr)sp;