upstream nginx-0.7.34
[nginx.git] / nginx / src / os / unix / rfork_thread.S
1
2 /*
3  * Copyright (C) Igor Sysoev
4  */
5
6
7 #include <sys/syscall.h>
8 #include <machine/asm.h>
9
10 /*
11  * rfork_thread(3) - rfork_thread(flags, stack, func, arg);
12  */
13
14 #define KERNCALL        int $0x80
15
16 ENTRY(rfork_thread)
17         push    %ebp
18         mov     %esp, %ebp
19         push    %esi
20
21         mov     12(%ebp), %esi  # the thread stack address
22
23         sub     $4, %esi
24         mov     20(%ebp), %eax  # the thread argument
25         mov     %eax, (%esi)
26
27         sub     $4, %esi
28         mov     16(%ebp), %eax  # the thread start address
29         mov     %eax, (%esi)
30
31         push    8(%ebp)         # rfork(2) flags
32         push    $0
33         mov     $SYS_rfork, %eax
34         KERNCALL
35         jc      error
36
37         cmp     $0, %edx
38         jne     child
39
40 parent:
41         add     $8, %esp
42         pop     %esi
43         leave
44         ret
45
46 child:
47         mov     %esi, %esp
48         pop     %eax
49         call    *%eax           # call a thread start address ...
50         add     $4, %esp
51
52         push    %eax
53         push    $0
54         mov     $SYS_exit, %eax # ... and exit(2) after a thread would return
55         KERNCALL
56
57 error:
58         add     $8, %esp
59         pop     %esi
60         leave
61         PIC_PROLOGUE
62
63         /* libc's cerror: jmp  PIC_PLT(HIDENAME(cerror)) */
64
65         push    %eax
66         call    PIC_PLT(CNAME(__error))
67         pop     %ecx
68         PIC_EPILOGUE
69         mov     %ecx, (%eax)
70         mov     $-1, %eax
71         mov     $-1, %edx
72         ret