commit - ac8042dfa9819f76ccfedd4aa36c1239322808b8
commit + 41b3e8b9893a8561af7e85ca98444bc284b4013d
blob - /dev/null
blob + 3afa9513d97534d4401817da869424a847af4beb (mode 644)
--- /dev/null
+++ src/libthread/386-ucontext.c
+#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
===
-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
-#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
-#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
-/* 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
{
_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
-#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
+#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
-#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
-#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
+#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
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
+/* 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
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
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
+#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;
+}