commit 04e0a9bb81356b6713e634b4d950c524f0abf15c from: Russ Cox date: Fri Oct 14 03:57:54 2011 UTC libthread: Lion context routines commit - f1825251e73ffd1c750ab14950bd1e5374991ae5 commit + 04e0a9bb81356b6713e634b4d950c524f0abf15c blob - /dev/null blob + d50d3b6d9534dc67c1736fb2a4f5bbbd59fba21f (mode 644) --- /dev/null +++ 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 blob - /dev/null blob + 0593e481dd6399d10b6a8e11df4d17bcc2295b94 (mode 644) --- /dev/null +++ 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; +} + + blob - b136bcf99f189f40be22ff71ed3f443d62073d36 blob + ffe0e2d3ef6ff6be6ece8fab4343567537c45e4b --- src/libthread/sysofiles.sh +++ 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 blob - 731a68cbe05f861cd66b5d4e019f8b156e8d6855 blob + 542a2437a4f03c6c18cfad5af890e7731594b870 --- src/libthread/thread.c +++ 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; blob - 0352d755490329cbcbccf4eb94c90e407e743e68 blob + e4220dbfd3be4dd99d7330065fa00a31deafe990 --- src/libthread/threadimpl.h +++ 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 }; blob - /dev/null blob + 08c6d9a8e8396cc5a3ad21872eb02af021a315cb (mode 644) --- /dev/null +++ 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*); +