From cea10000c59882b43525e4fd4fb17a55b7dba1c1 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 1 May 2005 18:38:12 +0000 Subject: OpenBSD/power support. --- src/libthread/BSD.c | 384 ++++++++++++++++++++++++++++++++++++++ src/libthread/Darwin-ucontext.h | 35 ---- src/libthread/FreeBSD.c | 364 +----------------------------------- src/libthread/OpenBSD-power-asm.S | 125 +++++++++++++ src/libthread/OpenBSD-power.c | 38 ++++ src/libthread/OpenBSD.c | 4 + src/libthread/mkfile | 7 +- src/libthread/power-ucontext.h | 35 ++++ src/libthread/sysofiles.sh | 3 + src/libthread/threadimpl.h | 11 +- 10 files changed, 602 insertions(+), 404 deletions(-) create mode 100644 src/libthread/BSD.c delete mode 100644 src/libthread/Darwin-ucontext.h create mode 100644 src/libthread/OpenBSD-power-asm.S create mode 100644 src/libthread/OpenBSD-power.c create mode 100644 src/libthread/OpenBSD.c create mode 100644 src/libthread/power-ucontext.h diff --git a/src/libthread/BSD.c b/src/libthread/BSD.c new file mode 100644 index 00000000..2679cd21 --- /dev/null +++ b/src/libthread/BSD.c @@ -0,0 +1,384 @@ +#undef exits +#undef _exits + +extern int __isthreaded; + +/* + * spin locks + */ +extern int _tas(int*); + +void +_threadunlock(Lock *l, ulong pc) +{ + USED(pc); + + l->held = 0; +} + +int +_threadlock(Lock *l, int block, ulong pc) +{ + int i; + + USED(pc); + + /* once fast */ + if(!_tas(&l->held)) + return 1; + if(!block) + return 0; + + /* a thousand times pretty fast */ + for(i=0; i<1000; i++){ + if(!_tas(&l->held)) + return 1; + sched_yield(); + } + /* increasingly slow */ + for(i=0; i<10; i++){ + if(!_tas(&l->held)) + return 1; + usleep(1); + } + for(i=0; i<10; i++){ + if(!_tas(&l->held)) + return 1; + usleep(10); + } + for(i=0; i<10; i++){ + if(!_tas(&l->held)) + return 1; + usleep(100); + } + for(i=0; i<10; i++){ + if(!_tas(&l->held)) + return 1; + usleep(1000); + } + for(i=0; i<10; i++){ + if(!_tas(&l->held)) + return 1; + usleep(10*1000); + } + /* now nice and slow */ + for(i=0; i<1000; i++){ + if(!_tas(&l->held)) + return 1; + usleep(100*1000); + } + /* take your time */ + while(_tas(&l->held)) + usleep(1000*1000); + return 1; +} + +/* + * For libc. + */ + +typedef struct { + volatile long access_lock; + volatile long lock_owner; + volatile char *fname; + volatile int lineno; +} spinlock_t; + +void +_spinlock(spinlock_t *lk) +{ + lock((Lock*)&lk->access_lock); +} + +/* + * sleep and wakeup + */ +static void +ign(int x) +{ + USED(x); +} + +static void /*__attribute__((constructor))*/ +ignusr1(int restart) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = ign; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGUSR1); + if(restart) + sa.sa_flags = SA_RESTART; + sigaction(SIGUSR1, &sa, nil); +} + +void +_procsleep(_Procrendez *r) +{ + sigset_t mask; + + /* + * Go to sleep. + * + * Block USR1, set the handler to interrupt system calls, + * unlock the vouslock so our waker can wake us, + * and then suspend. + */ +again: + r->asleep = 1; + r->pid = getpid(); + + sigprocmask(SIG_SETMASK, nil, &mask); + sigaddset(&mask, SIGUSR1); + sigprocmask(SIG_SETMASK, &mask, nil); + ignusr1(0); + unlock(r->l); + sigdelset(&mask, SIGUSR1); + sigsuspend(&mask); + + /* + * We're awake. Make USR1 not interrupt system calls. + */ + lock(r->l); + ignusr1(1); + if(r->asleep && r->pid == getpid()){ + /* Didn't really wake up - signal from something else */ + goto again; + } +} + +void +_procwakeup(_Procrendez *r) +{ + if(r->asleep){ + r->asleep = 0; + assert(r->pid >= 1); + kill(r->pid, SIGUSR1); + } +} + +void +_procwakeupandunlock(_Procrendez *r) +{ + _procwakeup(r); + unlock(r->l); +} + + +/* + * process creation and exit + */ +typedef struct Stackfree Stackfree; +struct Stackfree +{ + Stackfree *next; + int pid; +}; +static Lock stacklock; +static Stackfree *stackfree; + +static void +delayfreestack(uchar *stk) +{ + Stackfree *sf; + + sf = (Stackfree*)stk; + sf->pid = getpid(); + lock(&stacklock); + sf->next = stackfree; + stackfree = sf; + unlock(&stacklock); +} + +static void +dofreestacks(void) +{ + Stackfree *sf, *last, *next; + + if(stackfree==nil || !canlock(&stacklock)) + return; + + for(last=nil,sf=stackfree; sf; last=sf,sf=next){ + next = sf->next; + if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){ + free(sf); + if(last) + last->next = next; + else + stackfree = next; + sf = last; + } + } + unlock(&stacklock); +} + +static int +startprocfn(void *v) +{ + void **a; + uchar *stk; + void (*fn)(void*); + Proc *p; + + a = (void**)v; + fn = a[0]; + p = a[1]; + stk = a[2]; + free(a); + p->osprocid = getpid(); + + (*fn)(p); + + delayfreestack(stk); + _exit(0); + return 0; +} + +void +_procstart(Proc *p, void (*fn)(Proc*)) +{ + void **a; + uchar *stk; + int pid; + + dofreestacks(); + a = malloc(3*sizeof a[0]); + if(a == nil) + sysfatal("_procstart malloc: %r"); + stk = malloc(65536); + if(stk == nil) + sysfatal("_procstart malloc stack: %r"); + + a[0] = fn; + a[1] = p; + a[2] = stk; + + pid = rfork_thread(RFPROC|RFMEM|RFNOWAIT, stk+65536-64, startprocfn, a); + if(pid < 0){ + fprint(2, "_procstart rfork_thread: %r\n"); + abort(); + } +} + +static char *threadexitsmsg; +void +sigusr2handler(int s) +{ +/* fprint(2, "%d usr2 %d\n", time(0), getpid()); */ + if(threadexitsmsg) + _exits(threadexitsmsg); +} + +void +threadexitsall(char *msg) +{ + static int pid[1024]; + int i, npid, mypid; + Proc *p; + + if(msg == nil) + msg = ""; + mypid = getpid(); + lock(&_threadprocslock); + threadexitsmsg = msg; + npid = 0; + for(p=_threadprocs; p; p=p->next) + if(p->osprocid != mypid && p->osprocid >= 1) + pid[npid++] = p->osprocid; + for(i=0; ipid == pid) + return p; + if(p->pid == 0){ + print("found 0 at %d (h=%d)\n", (i+h)%nelem(perproc), h); + break; + } + } + fprint(2, "myperproc %d: cannot find self\n", pid); + abort(); + return nil; +} + +static Perproc* +newperproc(void) +{ + int i, pid, h; + Perproc *p; + + lock(&perlock); + pid = getpid(); + h = pid%nelem(perproc); + for(i=0; ipid == pid || p->pid == -1 || p->pid == 0){ + p->pid = pid; + unlock(&perlock); + return p; + } + } + fprint(2, "newperproc %d: out of procs\n", pid); + abort(); + return nil; +} + +Proc* +_threadproc(void) +{ + return myperproc()->proc; +} + +void +_threadsetproc(Proc *p) +{ + Perproc *pp; + + if(p) + p->osprocid = getpid(); + pp = newperproc(); + pp->proc = p; + if(p == nil) + pp->pid = -1; +} + +void +_pthreadinit(void) +{ + __isthreaded = 1; + signal(SIGUSR2, sigusr2handler); +} + +void +_threadpexit(void) +{ + _exit(0); +} + diff --git a/src/libthread/Darwin-ucontext.h b/src/libthread/Darwin-ucontext.h deleted file mode 100644 index a39be28a..00000000 --- a/src/libthread/Darwin-ucontext.h +++ /dev/null @@ -1,35 +0,0 @@ -typedef struct mcontext mcontext_t; -typedef struct ucontext ucontext_t; -struct mcontext -{ - ulong pc; /* lr */ - ulong cr; /* mfcr */ - ulong ctr; /* mfcr */ - ulong xer; /* mfcr */ - ulong sp; /* callee saved: r1 */ - ulong toc; /* callee saved: r2 */ - ulong r3; /* first arg to function, return register: r3 */ - ulong gpr[19]; /* callee saved: r13-r31 */ -// XXX: currently do not save vector registers or floating-point state -// ulong pad; -// uvlong fpr[18]; /* callee saved: f14-f31 */ -// ulong vr[4*12]; /* callee saved: v20-v31, 256-bits each */ -}; - -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 getcontext(ucontext_t*); -int setcontext(ucontext_t*); -int swapcontext(ucontext_t*, ucontext_t*); -int _getmcontext(mcontext_t*); -void _setmcontext(mcontext_t*); - diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c index d80aaec9..e6ce09b2 100644 --- a/src/libthread/FreeBSD.c +++ b/src/libthread/FreeBSD.c @@ -1,368 +1,6 @@ #include "threadimpl.h" -#undef exits -#undef _exits - -extern int __isthreaded; - -/* - * spin locks - */ -extern int _tas(int*); - -void -_threadunlock(Lock *l, ulong pc) -{ - USED(pc); - - l->held = 0; -} - -int -_threadlock(Lock *l, int block, ulong pc) -{ - int i; - - USED(pc); - - /* once fast */ - if(!_tas(&l->held)) - return 1; - if(!block) - return 0; - - /* a thousand times pretty fast */ - for(i=0; i<1000; i++){ - if(!_tas(&l->held)) - return 1; - sched_yield(); - } - /* now nice and slow */ - for(i=0; i<1000; i++){ - if(!_tas(&l->held)) - return 1; - usleep(100*1000); - } - /* take your time */ - while(_tas(&l->held)) - usleep(1000*1000); - return 1; -} - -/* - * For FreeBSD libc. - */ - -typedef struct { - volatile long access_lock; - volatile long lock_owner; - volatile char *fname; - volatile int lineno; -} spinlock_t; - -void -_spinlock(spinlock_t *lk) -{ - lock((Lock*)&lk->access_lock); -} - -/* - * sleep and wakeup - */ -static void -ign(int x) -{ - USED(x); -} - -static void /*__attribute__((constructor))*/ -ignusr1(int restart) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_handler = ign; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGUSR1); - if(restart) - sa.sa_flags = SA_RESTART; - sigaction(SIGUSR1, &sa, nil); -} - -void -_procsleep(_Procrendez *r) -{ - sigset_t mask; - - /* - * Go to sleep. - * - * Block USR1, set the handler to interrupt system calls, - * unlock the vouslock so our waker can wake us, - * and then suspend. - */ -again: - r->asleep = 1; - r->pid = getpid(); - - sigprocmask(SIG_SETMASK, nil, &mask); - sigaddset(&mask, SIGUSR1); - sigprocmask(SIG_SETMASK, &mask, nil); - ignusr1(0); - unlock(r->l); - sigdelset(&mask, SIGUSR1); - sigsuspend(&mask); - - /* - * We're awake. Make USR1 not interrupt system calls. - */ - lock(r->l); - ignusr1(1); - if(r->asleep && r->pid == getpid()){ - /* Didn't really wake up - signal from something else */ - goto again; - } -} - -void -_procwakeup(_Procrendez *r) -{ - if(r->asleep){ - r->asleep = 0; - assert(r->pid >= 1); - kill(r->pid, SIGUSR1); - } -} - -void -_procwakeupandunlock(_Procrendez *r) -{ - _procwakeup(r); - unlock(r->l); -} - - -/* - * process creation and exit - */ -typedef struct Stackfree Stackfree; -struct Stackfree -{ - Stackfree *next; - int pid; -}; -static Lock stacklock; -static Stackfree *stackfree; - -static void -delayfreestack(uchar *stk) -{ - Stackfree *sf; - - sf = (Stackfree*)stk; - sf->pid = getpid(); - lock(&stacklock); - sf->next = stackfree; - stackfree = sf; - unlock(&stacklock); -} - -static void -dofreestacks(void) -{ - Stackfree *sf, *last, *next; - - if(stackfree==nil || !canlock(&stacklock)) - return; - - for(last=nil,sf=stackfree; sf; last=sf,sf=next){ - next = sf->next; - if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){ - free(sf); - if(last) - last->next = next; - else - stackfree = next; - sf = last; - } - } - unlock(&stacklock); -} - -static int -startprocfn(void *v) -{ - void **a; - uchar *stk; - void (*fn)(void*); - Proc *p; - - a = (void**)v; - fn = a[0]; - p = a[1]; - stk = a[2]; - free(a); - p->osprocid = getpid(); - - (*fn)(p); - - delayfreestack(stk); - _exit(0); - return 0; -} - -void -_procstart(Proc *p, void (*fn)(Proc*)) -{ - void **a; - uchar *stk; - int pid; - - dofreestacks(); - a = malloc(3*sizeof a[0]); - if(a == nil) - sysfatal("_procstart malloc: %r"); - stk = malloc(65536); - if(stk == nil) - sysfatal("_procstart malloc stack: %r"); - - a[0] = fn; - a[1] = p; - a[2] = stk; - - pid = rfork_thread(RFPROC|RFMEM|RFNOWAIT, stk+65536-64, startprocfn, a); - if(pid < 0){ - fprint(2, "_procstart rfork_thread: %r\n"); - abort(); - } -} - -static char *threadexitsmsg; -void -sigusr2handler(int s) -{ -/* fprint(2, "%d usr2 %d\n", time(0), getpid()); */ - if(threadexitsmsg) - _exits(threadexitsmsg); -} - -void -threadexitsall(char *msg) -{ - static int pid[1024]; - int i, npid, mypid; - Proc *p; - - if(msg == nil) - msg = ""; - mypid = getpid(); - lock(&_threadprocslock); - threadexitsmsg = msg; - npid = 0; - for(p=_threadprocs; p; p=p->next) - if(p->osprocid != mypid && p->osprocid >= 1) - pid[npid++] = p->osprocid; - for(i=0; ipid == pid) - return p; - if(p->pid == 0){ - print("found 0 at %d (h=%d)\n", (i+h)%nelem(perproc), h); - break; - } - } - fprint(2, "myperproc %d: cannot find self\n", pid); - abort(); - return nil; -} - -static Perproc* -newperproc(void) -{ - int i, pid, h; - Perproc *p; - - lock(&perlock); - pid = getpid(); - h = pid%nelem(perproc); - for(i=0; ipid == pid || p->pid == -1 || p->pid == 0){ - p->pid = pid; - unlock(&perlock); - return p; - } - } - fprint(2, "newperproc %d: out of procs\n", pid); - abort(); - return nil; -} - -Proc* -_threadproc(void) -{ - return myperproc()->proc; -} - -void -_threadsetproc(Proc *p) -{ - Perproc *pp; - - if(p) - p->osprocid = getpid(); - pp = newperproc(); - pp->proc = p; - if(p == nil) - pp->pid = -1; -} - -void -_pthreadinit(void) -{ - __isthreaded = 1; - signal(SIGUSR2, sigusr2handler); -} - -void -_threadpexit(void) -{ - _exit(0); -} - +#include "BSD.c" /* * FreeBSD 4 and earlier needs the context functions. diff --git a/src/libthread/OpenBSD-power-asm.S b/src/libthread/OpenBSD-power-asm.S new file mode 100644 index 00000000..25ceb45c --- /dev/null +++ b/src/libthread/OpenBSD-power-asm.S @@ -0,0 +1,125 @@ +#include +#include + +ENTRY(_tas) + li %r0, 0 + mr %r4, %r3 + lis %r5, 0xcafe + ori %r5, %r5, 0xbabe +1: + lwarx %r3, %r0, %r4 + cmpwi %r3, 0 + bne 2f + stwcx. %r5, %r0, %r4 + bne- 1b +2: + sync + blr + +ENTRY(_getmcontext) /* xxx: instruction scheduling */ + mflr %r0 + mfcr %r5 + mfctr %r6 + mfxer %r7 + stw %r0, 0*4(%r3) + stw %r5, 1*4(%r3) + stw %r6, 2*4(%r3) + stw %r7, 3*4(%r3) + + stw %r1, 4*4(%r3) + stw %r2, 5*4(%r3) + li %r5, 1 /* return value for setmcontext */ + stw %r5, 6*4(%r3) + + stw %r13, (0+7)*4(%r3) /* callee-save GPRs */ + stw %r14, (1+7)*4(%r3) /* xxx: block move */ + stw %r15, (2+7)*4(%r3) + stw %r16, (3+7)*4(%r3) + stw %r17, (4+7)*4(%r3) + stw %r18, (5+7)*4(%r3) + stw %r19, (6+7)*4(%r3) + stw %r20, (7+7)*4(%r3) + stw %r21, (8+7)*4(%r3) + stw %r22, (9+7)*4(%r3) + stw %r23, (10+7)*4(%r3) + stw %r24, (11+7)*4(%r3) + stw %r25, (12+7)*4(%r3) + stw %r26, (13+7)*4(%r3) + stw %r27, (14+7)*4(%r3) + stw %r28, (15+7)*4(%r3) + stw %r29, (16+7)*4(%r3) + stw %r30, (17+7)*4(%r3) + stw %r31, (18+7)*4(%r3) + + li %r3, 0 /* return */ + blr + +ENTRY(_setmcontext) + lwz %r13, (0+7)*4(%r3) /* callee-save GPRs */ + lwz %r14, (1+7)*4(%r3) /* xxx: block move */ + lwz %r15, (2+7)*4(%r3) + lwz %r16, (3+7)*4(%r3) + lwz %r17, (4+7)*4(%r3) + lwz %r18, (5+7)*4(%r3) + lwz %r19, (6+7)*4(%r3) + lwz %r20, (7+7)*4(%r3) + lwz %r21, (8+7)*4(%r3) + lwz %r22, (9+7)*4(%r3) + lwz %r23, (10+7)*4(%r3) + lwz %r24, (11+7)*4(%r3) + lwz %r25, (12+7)*4(%r3) + lwz %r26, (13+7)*4(%r3) + lwz %r27, (14+7)*4(%r3) + lwz %r28, (15+7)*4(%r3) + lwz %r29, (16+7)*4(%r3) + lwz %r30, (17+7)*4(%r3) + lwz %r31, (18+7)*4(%r3) + + lwz %r1, 4*4(%r3) + lwz %r2, 5*4(%r3) + + lwz %r0, 0*4(%r3) + mtlr %r0 + lwz %r0, 1*4(%r3) + mtcr %r0 /* mtcrf 0xFF, %r0 */ + lwz %r0, 2*4(%r3) + mtctr %r0 + lwz %r0, 3*4(%r3) + mtxer %r0 + + lwz %r3, 6*4(%r3) + blr + +ENTRY(rfork_thread) + /* sanity check */ + cmpwi %r4, 0 + beq 1f + cmpwi %r5, 0 + beq 1f + + mr %r7,%r4 + + /* call rfork */ + li %r0, SYS_rfork + sc + cmpwi %r0, 0 + bne 2f + + /* check if we are parent or child */ + cmpwi %r3, 0 + bnelr + + /* child */ + mtlr %r5 /* fp */ + mr %r3, %r6 /* arg */ + mr %r1, %r7 /* new sp */ + blrl + + /* child returned, call _exit */ + li %r0, SYS_exit + sc +1: + li %r3, -1 +2: + b PIC_PLT(_C_LABEL(__cerror)) + diff --git a/src/libthread/OpenBSD-power.c b/src/libthread/OpenBSD-power.c new file mode 100644 index 00000000..c3c7e72b --- /dev/null +++ b/src/libthread/OpenBSD-power.c @@ -0,0 +1,38 @@ +#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 +getcontext(ucontext_t *uc) +{ + return _getmcontext(&uc->mc); +} + +int +setcontext(ucontext_t *uc) +{ + _setmcontext(&uc->mc); + return 0; +} + +int +swapcontext(ucontext_t *oucp, ucontext_t *ucp) +{ + if(getcontext(oucp) == 0) + setcontext(ucp); + return 0; +} + diff --git a/src/libthread/OpenBSD.c b/src/libthread/OpenBSD.c new file mode 100644 index 00000000..9aaa28cb --- /dev/null +++ b/src/libthread/OpenBSD.c @@ -0,0 +1,4 @@ +#include "threadimpl.h" + +#include "BSD.c" + diff --git a/src/libthread/mkfile b/src/libthread/mkfile index b1bf3ccf..3750c796 100644 --- a/src/libthread/mkfile +++ b/src/libthread/mkfile @@ -15,6 +15,8 @@ OFILES=\ <$PLAN9/src/mksyslib HFILES=thread.h threadimpl.h +OpenBSD.$O FreeBSD.$O: BSD.c +NetBSD.$O: Linux.c tprimes: tprimes.$O 9l -o $target $target.$O $PLAN9/lib/$LIB -l9 -lpthread @@ -24,9 +26,8 @@ tspawnloop: tspawnloop.$O 9l -o $target $target.$O $PLAN9/lib/$LIB -l9 -lpthread %.$O: %.c - $CC -I. $stem.c + $CC $CFLAGS -I. $stem.c -NetBSD.$O: Linux.c test:V: tprimes tspawn primes 1 10007 >p1.txt @@ -40,5 +41,3 @@ test:V: tprimes tspawn CLEANFILES=p1.txt p2.txt tp1.txt tp2.txt - - diff --git a/src/libthread/power-ucontext.h b/src/libthread/power-ucontext.h new file mode 100644 index 00000000..a39be28a --- /dev/null +++ b/src/libthread/power-ucontext.h @@ -0,0 +1,35 @@ +typedef struct mcontext mcontext_t; +typedef struct ucontext ucontext_t; +struct mcontext +{ + ulong pc; /* lr */ + ulong cr; /* mfcr */ + ulong ctr; /* mfcr */ + ulong xer; /* mfcr */ + ulong sp; /* callee saved: r1 */ + ulong toc; /* callee saved: r2 */ + ulong r3; /* first arg to function, return register: r3 */ + ulong gpr[19]; /* callee saved: r13-r31 */ +// XXX: currently do not save vector registers or floating-point state +// ulong pad; +// uvlong fpr[18]; /* callee saved: f14-f31 */ +// ulong vr[4*12]; /* callee saved: v20-v31, 256-bits each */ +}; + +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 getcontext(ucontext_t*); +int setcontext(ucontext_t*); +int swapcontext(ucontext_t*, ucontext_t*); +int _getmcontext(mcontext_t*); +void _setmcontext(mcontext_t*); + diff --git a/src/libthread/sysofiles.sh b/src/libthread/sysofiles.sh index 37ab6eb5..4832145b 100644 --- a/src/libthread/sysofiles.sh +++ b/src/libthread/sysofiles.sh @@ -23,6 +23,9 @@ case "$tag" in *-Darwin-*) echo ${SYSNAME}-${OBJTYPE}-asm.o ${SYSNAME}-${OBJTYPE}.o pthread.o ;; +*-OpenBSD-*) + echo ${SYSNAME}-${OBJTYPE}-asm.o ${SYSNAME}-${OBJTYPE}.o $SYSNAME.o + ;; *) echo pthread.o esac diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 346288de..fff874d8 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -5,7 +5,9 @@ #include #include #include -#include +#if !defined(_OpenBSD__) +# include +#endif #include #include "libc.h" #include "thread.h" @@ -22,7 +24,12 @@ extern void makecontext(ucontext_t*, void(*)(), int, ...); # define mcontext_t libthread_mcontext_t # define ucontext libthread_ucontext # define ucontext_t libthread_ucontext_t -# include "Darwin-ucontext.h" +# include "power-ucontext.h" +#endif + +#if defined(__OpenBSD__) +# include "power-ucontext.h" +extern pid_t rfork_thread(int, void*, int(*)(void*), void*); #endif typedef struct Context Context; -- cgit v1.2.3