24
24
#include <support.h>
25
25
#include "lib.h"
26
26
27
- #define SIZE 4096L
27
+ #define THREAD_STACKSIZE 4096L
28
28
29
29
30
30
/* this is used by wait() and wait3() to retrieve the child's exit code */
@@ -33,52 +33,66 @@ long __waitval = -ENOENT;
33
33
/* and this is used to retrieve the child's time */
34
34
long __waittime = 0 ;
35
35
36
- static void __CDECL
37
- startup (register BASEPAGE * b )
36
+ /*
37
+ * This function must not be compiled without optimization,
38
+ * because we change the stack, and the BASEPAGE parameter
39
+ * is not accessible afterwards.
40
+ */
41
+ #pragma GCC optimize "-Os"
42
+ #pragma GCC optimize "-fomit-frame-pointer"
43
+
44
+ static void __CDECL startup (BASEPAGE * b )
38
45
{
39
- register int (* func )(long );
40
- register long arg ;
41
- _setstack (((char * )b ) + SIZE );
46
+ int (* func )(long );
47
+ long arg ;
48
+ BASEPAGE * parent ;
49
+
50
+ parent = b -> p_parent ;
51
+ _setstack (b -> p_hitpa );
42
52
func = (int (* )(long ))b -> p_dbase ;
43
53
arg = b -> p_dlen ;
44
54
45
55
/* If this is a thread, it doesn't need
46
56
* own copy of the environment, right?
47
57
*/
48
58
Mfree (b -> p_env );
49
- b -> p_env = _base -> p_env ;
59
+ b -> p_env = parent -> p_env ;
50
60
51
61
/* copy from parents basepage for debuggers... */
52
- b -> p_tbase = _base -> p_tbase ;
53
- b -> p_tlen = _base -> p_tlen ;
54
- b -> p_dbase = _base -> p_dbase ;
55
- b -> p_dlen = _base -> p_dlen ;
56
- b -> p_bbase = _base -> p_bbase ;
57
- b -> p_blen = _base -> p_blen ;
62
+ b -> p_tbase = parent -> p_tbase ;
63
+ b -> p_tlen = parent -> p_tlen ;
64
+ b -> p_dbase = parent -> p_dbase ;
65
+ b -> p_dlen = parent -> p_dlen ;
66
+ b -> p_bbase = parent -> p_bbase ;
67
+ b -> p_blen = parent -> p_blen ;
58
68
59
69
Pterm ((* func )(arg ));
70
+ __builtin_unreachable ();
60
71
}
61
72
62
73
/* use long instead of int so vfork works OK with -mshort */
63
74
long
64
75
tfork (int (* func )(long ), long arg )
65
76
{
66
- register BASEPAGE * b ;
67
- register long pid ;
68
- register long savpending , savmask ;
69
- register BASEPAGE * savbase ;
77
+ BASEPAGE * b ;
78
+ long pid ;
79
+ long savpending , savmask ;
70
80
sighandler_t savhandler [NSIG ];
71
81
long now ;
72
82
int i ;
83
+ long stacksize = THREAD_STACKSIZE ;
73
84
74
85
b = (BASEPAGE * )Pexec (PE_CBASEPAGE , 0L , "" , 0L );
75
- (void )Mshrink (b , SIZE + 256 );
86
+ if ((long )b <= 0 )
87
+ return (long )b ;
88
+ (void )Mshrink (b , stacksize + sizeof (* b ));
76
89
b -> p_tbase = (char * )startup ;
77
90
b -> p_dbase = (char * )func ;
78
91
b -> p_dlen = arg ;
79
- b -> p_hitpa = ((char * )b ) + SIZE + 256 ;
80
-
81
- pid = Pexec (104 , 0L , b , 0L );
92
+ b -> p_blen = stacksize ;
93
+ b -> p_hitpa = ((char * )b ) + stacksize + sizeof (* b );
94
+
95
+ pid = Pexec (PE_ASYNC_GO , 0L , b , 0L );
82
96
if (pid == - ENOSYS )
83
97
{
84
98
/* save the signal masks and signal handlers,
@@ -90,30 +104,35 @@ tfork(int (*func)(long), long arg)
90
104
_sigmask = 0 ;
91
105
for (i = 0 ; i < NSIG ; i ++ )
92
106
savhandler [i ] = _sig_handler [i ];
93
- savbase = _base ;
94
- _base = b ;
95
107
96
108
now = _clock ();
97
- pid = Pexec (4 , 0L , b , 0L );
109
+ pid = Pexec (PE_GO , 0L , b , 0L );
98
110
99
- _base = savbase ;
100
111
/* restore signal stuff */
101
112
for (i = 0 ; i < NSIG ; i ++ )
102
113
_sig_handler [i ] = savhandler [i ];
103
114
_sigmask = savmask ;
104
115
_sigpending = savpending ;
105
- if (pid >= 0 ) {
116
+ if (pid >= 0 )
117
+ {
106
118
long retval = pid ;
107
119
108
- /* see the TOS algorithm for getpid() */
120
+ /* see the TOS algorithm for getpid() */
109
121
pid = ((long )b ) >> 8 ;
110
122
__waitval = (pid << 16 ) | retval ;
111
123
raise (SIGCHLD );
112
124
__waittime = _clock () - now ;
113
125
_childtime += __waittime ;
126
+ /* child already terminated, but memory of basepage & env is still owned by us */
127
+ (void )Mfree (b -> p_env ); /* free the memory */
128
+ (void )Mfree (b );
114
129
}
115
130
}
116
- (void )Mfree (b -> p_env ); /* free the memory */
117
- (void )Mfree (b );
131
+ if (pid < 0 )
132
+ {
133
+ (void )Mfree (b -> p_env ); /* free the memory */
134
+ (void )Mfree (b );
135
+ }
136
+ /* memory of basepage & env is now owned by child */
118
137
return pid ;
119
138
}
0 commit comments