diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-02-24 17:31:46 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-02-24 17:31:46 +0000 |
commit | 48fef6654cc90e05004648423cb5dd7c6f7770f0 (patch) | |
tree | c61d52b4dddfb64e28de98bf402b96706f0be418 /src/os/unix/rfork_thread.S | |
parent | b54698b5798b7f1a54226274347ce1faee5a92a4 (diff) | |
download | nginx-48fef6654cc90e05004648423cb5dd7c6f7770f0.tar.gz nginx-48fef6654cc90e05004648423cb5dd7c6f7770f0.zip |
nginx-0.0.2-2004-02-24-20:31:46 import
Diffstat (limited to 'src/os/unix/rfork_thread.S')
-rw-r--r-- | src/os/unix/rfork_thread.S | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/os/unix/rfork_thread.S b/src/os/unix/rfork_thread.S new file mode 100644 index 000000000..5abb9f831 --- /dev/null +++ b/src/os/unix/rfork_thread.S @@ -0,0 +1,69 @@ + +#include <sys/syscall.h> +#include <machine/asm.h> + +/* + * rfork_thread(3) - rfork_thread(flags, stack, func, arg); + */ + +#define KERNCALL int $0x80 + +ENTRY(rfork_thread) + push %ebp + mov %esp, %ebp + push %esi + + mov 12(%ebp), %esi # the stack address + + sub $4, %esi + mov 20(%ebp), %eax # the thread argument + mov %eax, (%esi) + + sub $4, %esi + mov 16(%ebp), %eax # the start thread address + mov %eax, (%esi) + + push 8(%ebp) # rfork(2) flags + push $0 + mov $SYS_rfork, %eax + KERNCALL + jc error + + cmp $0, %edx + jne child + +parent: + add $8, %esp + pop %esi + mov %ebp, %esp + pop %ebp + ret + +child: + mov %esi, %esp + pop %eax + call *%eax # call a thread start address ... + add $4, %esp + + push %eax + push $0 + mov $SYS_exit, %eax # ... and exit(2) after a thread would return + KERNCALL + +error: + add $8, %esp + pop %esi + mov %ebp, %esp + pop %ebp + PIC_PROLOGUE + + /* libc's cerror: jmp PIC_PLT(HIDENAME(cerror)) */ + + push %eax + call PIC_PLT(CNAME(__error)) + pop %ecx + PIC_EPILOGUE + mov %ecx, (%eax) + mov $-1, %eax + mov $-1, %edx + ret |