aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/asm-OpenBSD-386.s49
-rw-r--r--src/libthread/exec-unix.c41
-rw-r--r--src/libthread/label.h2
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;