From 04e0a9bb81356b6713e634b4d950c524f0abf15c Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 13 Oct 2011 23:57:54 -0400 Subject: libthread: Lion context routines --- src/libthread/Darwin-x86_64-asm.s | 44 +++++++++++++++++++++++++++++++ src/libthread/Darwin-x86_64-swapcontext.c | 32 ++++++++++++++++++++++ src/libthread/sysofiles.sh | 3 +++ src/libthread/thread.c | 4 ++- src/libthread/threadimpl.h | 6 +++-- src/libthread/x86_64-ucontext.h | 43 ++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 src/libthread/Darwin-x86_64-asm.s create mode 100644 src/libthread/Darwin-x86_64-swapcontext.c create mode 100644 src/libthread/x86_64-ucontext.h (limited to 'src/libthread') diff --git a/src/libthread/Darwin-x86_64-asm.s b/src/libthread/Darwin-x86_64-asm.s new file mode 100644 index 00000000..d50d3b6d --- /dev/null +++ b/src/libthread/Darwin-x86_64-asm.s @@ -0,0 +1,44 @@ +.text +.align 8 + +.globl _libthread_getmcontext +_libthread_getmcontext: + movq $1, 0*8(%rdi) // rax + movq %rbx, 1*8(%rdi) + movq %rcx, 2*8(%rdi) + movq %rdx, 3*8(%rdi) + movq %rsi, 4*8(%rdi) + movq %rdi, 5*8(%rdi) + movq %rbp, 6*8(%rdi) + movq %rsp, 7*8(%rdi) + movq %r8, 8*8(%rdi) + movq %r9, 9*8(%rdi) + movq %r10, 10*8(%rdi) + movq %r11, 11*8(%rdi) + movq %r12, 12*8(%rdi) + movq %r13, 13*8(%rdi) + movq %r14, 14*8(%rdi) + movq %r15, 15*8(%rdi) + movq $0, %rax + ret + +.globl _libthread_setmcontext +_libthread_setmcontext: + movq 0*8(%rdi), %rax + movq 1*8(%rdi), %rbx + movq 2*8(%rdi), %rcx + movq 3*8(%rdi), %rdx + movq 4*8(%rdi), %rsi + // %rdi later + movq 6*8(%rdi), %rbp + movq 7*8(%rdi), %rsp + movq 8*8(%rdi), %r8 + movq 9*8(%rdi), %r9 + movq 10*8(%rdi), %r10 + movq 11*8(%rdi), %r11 + movq 12*8(%rdi), %r12 + movq 13*8(%rdi), %r13 + movq 14*8(%rdi), %r14 + movq 15*8(%rdi), %r15 + movq 5*8(%rdi), %rdi + ret diff --git a/src/libthread/Darwin-x86_64-swapcontext.c b/src/libthread/Darwin-x86_64-swapcontext.c new file mode 100644 index 00000000..0593e481 --- /dev/null +++ b/src/libthread/Darwin-x86_64-swapcontext.c @@ -0,0 +1,32 @@ +#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; +} + + diff --git a/src/libthread/sysofiles.sh b/src/libthread/sysofiles.sh index b136bcf9..ffe0e2d3 100644 --- a/src/libthread/sysofiles.sh +++ b/src/libthread/sysofiles.sh @@ -34,5 +34,8 @@ arm-Linux) # ARM doesn't supply them either. echo Linux-arm-context.o Linux-arm-swapcontext.o ;; +x86_64-Darwin) + echo Darwin-x86_64-asm.o Darwin-x86_64-swapcontext.o + ;; esac diff --git a/src/libthread/thread.c b/src/libthread/thread.c index 731a68cb..542a2437 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -86,6 +86,7 @@ threadstart(uint y, uint x) _Thread *t; ulong z; +//print("threadstart\n"); z = (ulong)x << 16; /* hide undefined 32-bit shift from 32-bit compilers */ z <<= 16; z |= y; @@ -317,7 +318,7 @@ procscheduler(Proc *p) setproc(p); _threaddebug("scheduler enter"); -/* print("s %p\n", p); */ +//print("s %p\n", p); lock(&p->lock); for(;;){ if((t = p->pinthread) != nil){ @@ -354,6 +355,7 @@ procscheduler(Proc *p) p->thread = t; p->nswitch++; _threaddebug("run %d (%s)", t->id, t->name); +//print("run %p %p %p %p\n", t, *(uintptr*)(t->context.uc.mc.sp), t->context.uc.mc.di, t->context.uc.mc.si); contextswitch(&p->schedcontext, &t->context); /*print("back in scheduler\n"); */ p->thread = nil; diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 0352d755..e4220dbf 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -24,7 +24,7 @@ extern int swapcontext(ucontext_t*, ucontext_t*); extern void makecontext(ucontext_t*, void(*)(), int, ...); #endif -#if defined(__APPLE__) && !defined(__x86_64__) +#if defined(__APPLE__) /* * OS X before 10.5 (Leopard) does not provide * swapcontext nor makecontext, so we have to use our own. @@ -40,6 +40,8 @@ extern void makecontext(ucontext_t*, void(*)(), int, ...); # define makecontext libthread_makecontext # if defined(__i386__) # include "386-ucontext.h" +# elif defined(__x86_64__) +# include "x86_64-ucontext.h" # elif defined(__power__) # include "power-ucontext.h" # else @@ -108,7 +110,7 @@ struct Context * end of the ucontext_t. Sigh. We put some extra * scratch space here for them. */ - uchar buf[512]; + uchar buf[1024]; #endif }; diff --git a/src/libthread/x86_64-ucontext.h b/src/libthread/x86_64-ucontext.h new file mode 100644 index 00000000..08c6d9a8 --- /dev/null +++ b/src/libthread/x86_64-ucontext.h @@ -0,0 +1,43 @@ +#define setcontext(u) libthread_setmcontext(&(u)->mc) +#define getcontext(u) libthread_getmcontext(&(u)->mc) +typedef struct mcontext mcontext_t; +typedef struct ucontext ucontext_t; + +struct mcontext +{ + uintptr ax; + uintptr bx; + uintptr cx; + uintptr dx; + uintptr si; + uintptr di; + uintptr bp; + uintptr sp; + uintptr r8; + uintptr r9; + uintptr r10; + uintptr r11; + uintptr r12; + uintptr r13; + uintptr r14; + uintptr r15; +/* +// XXX: currently do not save vector registers or floating-point state +*/ +}; + +struct ucontext +{ + struct { + void *ss_sp; + uint ss_size; + } uc_stack; + sigset_t uc_sigmask; + mcontext_t mc; +}; + +void makecontext(ucontext_t*, void(*)(void), int, ...); +int swapcontext(ucontext_t*, ucontext_t*); +int libthread_getmcontext(mcontext_t*); +void libthread_setmcontext(mcontext_t*); + -- cgit v1.2.3