topenbsd - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit bea4b9f7246169ee1bd2a64a4b2be2c02ffcec8b | |
parent 9d654ebc8c4824a46483e0d5cf37a3e0181fe552 | |
Author: rsc <devnull@localhost> | |
Date: Tue, 19 Jul 2005 11:48:01 +0000 | |
openbsd | |
Diffstat: | |
A src/libthread/OpenBSD-386-asm.s | 54 +++++++++++++++++++++++++++++… | |
A src/libthread/OpenBSD-386.c | 38 +++++++++++++++++++++++++++++… | |
2 files changed, 92 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/src/libthread/OpenBSD-386-asm.s b/src/libthread/OpenBSD-386-asm.s | |
t@@ -0,0 +1,54 @@ | |
+.globl _tas | |
+_tas: | |
+ movl $0xCAFEBABE, %eax | |
+ movl 4(%esp), %ecx | |
+ xchgl %eax, 0(%ecx) | |
+ ret | |
+ | |
+.globl setmcontext | |
+setmcontext: | |
+ movl 4(%esp), %edx | |
+ movl 8(%edx), %fs | |
+ movl 12(%edx), %es | |
+ movl 16(%edx), %ds | |
+ movl 76(%edx), %ss | |
+ movl 20(%edx), %edi | |
+ movl 24(%edx), %esi | |
+ movl 28(%edx), %ebp | |
+ movl %esp, %ecx | |
+ movl 72(%edx), %esp | |
+ pushl 60(%edx) /* eip */ | |
+ pushl 44(%edx) /* ecx */ | |
+ pushl 48(%edx) /* eax */ | |
+ movl 36(%edx), %ebx | |
+ movl 40(%edx), %edx | |
+ movl 12(%ecx), %eax | |
+ popl %eax | |
+ popl %ecx | |
+ ret | |
+ | |
+.globl getmcontext | |
+getmcontext: | |
+ pushl %edx | |
+ movl 8(%esp), %edx | |
+ movl %fs, 8(%edx) | |
+ movl %es, 12(%edx) | |
+ movl %ds, 16(%edx) | |
+ movl %ss, 76(%edx) | |
+ movl %edi, 20(%edx) | |
+ movl %esi, 24(%edx) | |
+ movl %ebp, 28(%edx) | |
+ movl %ebx, 36(%edx) | |
+ movl $1, 48(%edx) | |
+ popl %eax | |
+ movl %eax, 40(%edx) | |
+ movl %ecx, 44(%edx) | |
+ movl (%esp), %eax /* eip */ | |
+ movl %eax, 60(%edx) | |
+ movl %esp, %eax | |
+ addl $4, %eax /* setmcontext will re-push the eip */ … | |
+ movl %eax, 72(%edx) | |
+ movl 40(%edx), %edx | |
+ xorl %eax, %eax | |
+ ret | |
+ | |
diff --git a/src/libthread/OpenBSD-386.c b/src/libthread/OpenBSD-386.c | |
t@@ -0,0 +1,38 @@ | |
+#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; | |
+} | |
+ | |
+extern int getmcontext(mcontext_t*); | |
+extern int setmcontext(mcontext_t*); | |
+ | |
+int | |
+getcontext(ucontext_t *uc) | |
+{ | |
+ return getmcontext(&uc->uc_mcontext); | |
+} | |
+ | |
+void | |
+setcontext(ucontext_t *uc) | |
+{ | |
+ setmcontext(&uc->uc_mcontext); | |
+} | |
+ | |
+int | |
+swapcontext(ucontext_t *oucp, ucontext_t *ucp) | |
+{ | |
+ if(getcontext(oucp) == 0) | |
+ setcontext(ucp); | |
+ return 0; | |
+} | |
+ |