libthread: context switching for arm, still not complete

This commit is contained in:
Russ Cox 2009-11-18 04:12:17 -05:00
parent 778ec84c9c
commit ba940ae61c
4 changed files with 78 additions and 4 deletions

View file

@ -0,0 +1,41 @@
.globl mygetmcontext
mygetmcontext:
str r1, [r0,#4]
str r2, [r0,#8]
str r3, [r0,#12]
str r4, [r0,#16]
str r5, [r0,#20]
str r6, [r0,#24]
str r7, [r0,#28]
str r8, [r0,#32]
str r9, [r0,#36]
str r10, [r0,#40]
str r11, [r0,#44]
str r12, [r0,#48]
str r13, [r0,#52]
str r14, [r0,#56]
/* store 1 as r0-to-restore */
mov r1, #1
str r1, [r0]
/* return 0 */
mov r0, #0
mov pc, lr
.globl mysetmcontext
mysetmcontext:
ldr r1, [r0,#4]
ldr r2, [r0,#8]
ldr r3, [r0,#12]
ldr r4, [r0,#16]
ldr r5, [r0,#20]
ldr r6, [r0,#24]
ldr r7, [r0,#28]
ldr r8, [r0,#32]
ldr r9, [r0,#36]
ldr r10, [r0,#40]
ldr r11, [r0,#44]
ldr r12, [r0,#48]
ldr r13, [r0,#52]
ldr r14, [r0,#56]
ldr r0, [r0]
mov pc, lr

View file

@ -0,0 +1,26 @@
#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.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;
}

View file

@ -4,6 +4,9 @@ test -f $PLAN9/config && . $PLAN9/config
tag="$OBJTYPE-$SYSNAME-${SYSVERSION:-`uname -r`}-${CC9:-cc}"
case "$tag" in
arm-Linux-*)
echo ${SYSNAME}-${OBJTYPE}-asm.o $SYSNAME.o
;;
*-Linux-2.6.*)
echo pthread.o
;;
@ -36,5 +39,9 @@ sparc64-Linux)
# so we supply our own copy from the latest glibc.
echo Linux-sparc64-context.o Linux-sparc64-swapcontext.o
;;
arm-Linux)
# ARM doesn't supply them either.
echo Linux-arm-context.o Linux-arm-swapcontext.o
;;
esac

View file

@ -73,10 +73,10 @@ but surely the latter would be defined(__sparc__).
*/
#if defined(__arm__)
int getmcontext(mcontext_t*);
void setmcontext(const mcontext_t*);
#define setcontext(u) setmcontext(&(u)->uc_mcontext)
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
int mygetmcontext(mcontext_t*);
void mysetmcontext(const mcontext_t*);
#define setcontext(u) mysetmcontext(&(u)->uc_mcontext)
#define getcontext(u) mygetmcontext(&(u)->uc_mcontext)
#endif