0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
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
|
|
22 mov 12(%ebp), %esi # the stack address
|
|
23
|
|
24 sub $4, %esi
|
|
25 mov 20(%ebp), %eax # the thread argument
|
|
26 mov %eax, (%esi)
|
|
27
|
|
28 sub $4, %esi
|
|
29 mov 16(%ebp), %eax # the start thread address
|
|
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
|
|
44 mov %ebp, %esp
|
|
45 pop %ebp
|
|
46 ret
|
|
47
|
|
48 child:
|
|
49 mov %esi, %esp
|
|
50 pop %eax
|
|
51 call *%eax # call a thread start address ...
|
|
52 add $4, %esp
|
|
53
|
|
54 push %eax
|
|
55 push $0
|
|
56 mov $SYS_exit, %eax # ... and exit(2) after a thread would return
|
|
57 KERNCALL
|
|
58
|
|
59 error:
|
|
60 add $8, %esp
|
|
61 pop %esi
|
|
62 mov %ebp, %esp
|
|
63 pop %ebp
|
|
64 PIC_PROLOGUE
|
|
65
|
|
66 /* libc's cerror: jmp PIC_PLT(HIDENAME(cerror)) */
|
|
67
|
|
68 push %eax
|
|
69 call PIC_PLT(CNAME(__error))
|
|
70 pop %ecx
|
|
71 PIC_EPILOGUE
|
|
72 mov %ecx, (%eax)
|
|
73 mov $-1, %eax
|
|
74 mov $-1, %edx
|
|
75 ret
|