mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
libthread: use consistent stack calculation code in makecontext
Also reduce duplication: makecontext is per-arch not per-os-arch. May fix #353.
This commit is contained in:
parent
ac8042dfa9
commit
41b3e8b989
11 changed files with 36 additions and 83 deletions
|
@ -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 */
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
Loading…
Reference in a new issue