diff options
Diffstat (limited to 'storage/mroonga/vendor/groonga/vendor/nginx-1.7.4/src/os/unix/rfork_thread.S')
-rw-r--r-- | storage/mroonga/vendor/groonga/vendor/nginx-1.7.4/src/os/unix/rfork_thread.S | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/vendor/nginx-1.7.4/src/os/unix/rfork_thread.S b/storage/mroonga/vendor/groonga/vendor/nginx-1.7.4/src/os/unix/rfork_thread.S new file mode 100644 index 00000000000..e570349f93b --- /dev/null +++ b/storage/mroonga/vendor/groonga/vendor/nginx-1.7.4/src/os/unix/rfork_thread.S @@ -0,0 +1,73 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#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 thread stack address + + sub $4, %esi + mov 20(%ebp), %eax # the thread argument + mov %eax, (%esi) + + sub $4, %esi + mov 16(%ebp), %eax # the thread start 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 + leave + 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 + leave + 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 |