diff options
Diffstat (limited to 'src/libthread')
-rw-r--r-- | src/libthread/asm-OpenBSD-386.s | 49 | ||||
-rw-r--r-- | src/libthread/exec-unix.c | 41 | ||||
-rw-r--r-- | src/libthread/label.h | 2 |
3 files changed, 88 insertions, 4 deletions
diff --git a/src/libthread/asm-OpenBSD-386.s b/src/libthread/asm-OpenBSD-386.s new file mode 100644 index 00000000..35e2ab6f --- /dev/null +++ b/src/libthread/asm-OpenBSD-386.s @@ -0,0 +1,49 @@ +.globl _setlabel +.type _setlabel,@function + +_setlabel: + movl 4(%esp), %eax + movl 0(%esp), %edx + movl %edx, 0(%eax) + movl %ebx, 4(%eax) + movl %esp, 8(%eax) + movl %ebp, 12(%eax) + movl %esi, 16(%eax) + movl %edi, 20(%eax) + xorl %eax, %eax + ret + +.globl _gotolabel +.type _gotolabel,@function + +_gotolabel: + movl 4(%esp), %edx + movl 0(%edx), %ecx + movl 4(%edx), %ebx + movl 8(%edx), %esp + movl 12(%edx), %ebp + movl 16(%edx), %esi + movl 20(%edx), %edi + xorl %eax, %eax + incl %eax + movl %ecx, 0(%esp) + ret + + +# .globl _xinc +# _xinc: +# movl 4(%esp), %eax +# lock incl 0(%eax) +# ret +# +# .globl _xdec +# _xdec: +# movl 4(%esp), %eax +# lock decl 0(%eax) +# jz iszero +# movl $1, %eax +# ret +# iszero: +# movl $0, %eax +# ret +# diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c index bfffa14d..eb31e99e 100644 --- a/src/libthread/exec-unix.c +++ b/src/libthread/exec-unix.c @@ -3,8 +3,8 @@ #include "threadimpl.h" static void efork(int[3], int[2], char*, char**); -void -threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) +static void +_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs) { int pfd[2]; int n, pid; @@ -40,6 +40,8 @@ threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) efork(fd, pfd, prog, args); _exit(0); default: + if(freeargs) + free(args); break; } @@ -69,9 +71,42 @@ Bad: } void +threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) +{ + _threadexec(pidc, fd, prog, args, 0); +} + +/* + * The &f+1 trick doesn't work on SunOS, so we might + * as well bite the bullet and do this correctly. + */ +void threadexecl(Channel *pidc, int fd[3], char *f, ...) { - threadexec(pidc, fd, f, &f+1); + char **args, *s; + int n; + va_list arg; + + va_start(arg, f); + for(n=0; va_arg(arg, char*) != 0; n++) + ; + n++; + va_end(arg); + + args = malloc(n*sizeof(args[0])); + if(args == nil){ + if(pidc) + sendul(pidc, ~0); + return; + } + + va_start(arg, f); + for(n=0; (s=va_arg(arg, char*)) != 0; n++) + args[n] = s; + args[n] = 0; + va_end(arg); + + _threadexec(pidc, fd, f, args, 1); } static void diff --git a/src/libthread/label.h b/src/libthread/label.h index 874fb070..5161e373 100644 --- a/src/libthread/label.h +++ b/src/libthread/label.h @@ -7,7 +7,7 @@ typedef struct Label Label; #define LABELDPC 0 -#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__)) +#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__) || defined(__OpenBSD__)) struct Label { ulong pc; |