- /*
- * 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