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