… | |
… | |
6 | |
6 | |
7 | $|=1; |
7 | $|=1; |
8 | |
8 | |
9 | $DEFINE = ""; |
9 | $DEFINE = ""; |
10 | |
10 | |
|
|
11 | print <<EOF; |
|
|
12 | |
|
|
13 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
14 | |
|
|
15 | Coro has a number of configuration options. Due to its maturity, the |
|
|
16 | defaults that Coro chooses are usually fine, so you can decide to skip |
|
|
17 | these questions. Only if something went wrong you should select 'n' |
|
|
18 | here and manually configure Coro, and, of course, report this to the |
|
|
19 | maintainer :) |
|
|
20 | |
|
|
21 | EOF |
|
|
22 | |
|
|
23 | if (prompt ("Skip further questions and use defaults (y/n)?", "y") =~ /[yY]/) { |
|
|
24 | $ENV{PERL_MM_USE_DEFAULT} = 1; |
|
|
25 | } |
|
|
26 | |
|
|
27 | |
11 | $DEFINE .= " -DHAVE_MMAP" if $Config{d_mmap} eq "define" && $Config{d_munmap} eq "define"; |
28 | $DEFINE .= " -DHAVE_MMAP" if $Config{d_mmap} eq "define" && $Config{d_munmap} eq "define"; |
12 | |
29 | |
13 | if ($^O =~ /win32/i or $^O =~ /cygwin/) { |
30 | if ($^O =~ /win32/i or $^O =~ /cygwin/ or $^O =~ /mswin/) { |
14 | $DEFINE = " -DCORO_LOOSE"; |
31 | $iface = 'w'; |
15 | } elsif ($^O =~ /irix/) { |
32 | } elsif ($^O =~ /irix/) { |
16 | $iface = "i"; |
33 | $iface = "i"; |
17 | } elsif ($^O =~ /linux/) { |
34 | } elsif ($^O =~ /linux/) { |
18 | # default to setjmp/longjmp on non-x86... |
35 | # default to setjmp/longjmp on non-x86... |
19 | $iface = $Config{archname} =~ /^i[3456]86-/ ? "l" : "s"; |
36 | $iface = $Config{archname} =~ /^(i[3456]86|amd64|x86_64)-/ ? "l" : "s"; |
20 | } elsif ($^O =~ /(free|net|open)bsd/) { |
37 | } elsif ($^O =~ /(free|net|open)bsd/) { |
21 | # FreeBSD 4.x has ucontext.h but no makecontext et al (see BUGS section of |
38 | # FreeBSD 4.x has ucontext.h but no makecontext et al. (see BUGS section of |
22 | # man context). Assume the same problem for all other BSDs. |
39 | # man context). Assume the same problem for all other BSDs. |
23 | $iface = "s"; |
40 | $iface = "s"; |
24 | } elsif ($^O =~ /solaris/) { |
41 | } elsif ($^O =~ /solaris/) { |
25 | $iface = "s"; |
42 | $iface = "s"; |
26 | } elsif ($^O =~ /darwin/) { |
43 | } elsif ($^O =~ /darwin/) { |
27 | $iface = "s"; |
44 | $iface = "s"; |
28 | } elsif (-e "/usr/include/ucontext.h") { |
45 | } elsif (-e "/usr/include/ucontext.h") { # shame on this heuristic |
29 | $iface = "u"; |
46 | $iface = "u"; |
30 | } else { |
47 | } else { |
31 | $iface = "s"; |
48 | $iface = "s"; |
32 | } |
49 | } |
33 | |
50 | |
34 | print <<EOF; |
51 | print <<EOF; |
35 | |
52 | |
36 | Version 0.12 introduced C context sharing. This makes it possible to share |
53 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
37 | the C stack and context between many coroutines, resulting in memory |
|
|
38 | savings and slight speed gains, at the cost of potential (but mostly |
|
|
39 | theoretical) segfaults. On my Linux/x86 machine this decreased the size |
|
|
40 | of a new coroutine from 9k to 5k, but the savings are much more apparent |
|
|
41 | on machines without mmap or good memory management. This algorithm relies |
|
|
42 | on the non-fact that the same machine stack pointer indicates the same |
|
|
43 | function call nesting level, which usually works good enough but might |
|
|
44 | fail... |
|
|
45 | |
54 | |
46 | The default (enabled) has been in-use on productions servers for some time |
|
|
47 | now, without any problem reports so far. |
|
|
48 | |
|
|
49 | EOF |
|
|
50 | |
|
|
51 | if (prompt ("Do you want to enable C context sharing (y/n)", "y") !~ /^\s*n/i) { |
|
|
52 | print "\nExperimental context sharing enabled.\n\n"; |
|
|
53 | $DEFINE .= " -DCORO_LAZY_STACK"; |
|
|
54 | } |
|
|
55 | |
|
|
56 | if ($iface) { |
|
|
57 | print <<EOF; |
|
|
58 | |
|
|
59 | Coro can use various ways to implement coroutines at the C level: |
55 | Coro can use a number of methods to implement coroutines at the C |
|
|
56 | level. The default chosen is based on your current confguration and is |
|
|
57 | correct in most cases, but you still can chose between these alternatives: |
60 | |
58 | |
61 | u The unix ucontext functions are newer and not implemented in older |
59 | u The unix 'ucontext.h' functions are relatively new and not implemented |
62 | unices (or broken libc's like glibc-2.2.2 and below). They allow very |
60 | or well-tested in older unices. They allow very fast coroutine creation |
63 | fast coroutine creation and fast switching, and, most importantly, are |
61 | and reasonably fast switching, and, most importantly, are very stable. |
64 | very stable. |
|
|
65 | |
62 | |
66 | s If the ucontext functions are not working or you don't want |
63 | s If the ucontext functions are not working or you don't want |
67 | to use them for other reasons you can try a workaround using |
64 | to use them for other reasons you can try a workaround using |
68 | setjmp/longjmp/sigaltstack (also standard unix functions). Coroutine |
65 | setjmp/longjmp/sigaltstack (also standard unix functions). Coroutine |
69 | creation is rather slow, but switching is very fast as well (often much |
66 | creation is rather slow, but switching is very fast as well (often much |
70 | faster than with the ucontext functions). Unfortunately, glibc-2.1 and |
67 | faster than with the ucontext functions). Unfortunately, glibc-2.1 and |
71 | below don't even feature a working sigaltstack. |
68 | below don't even feature a working sigaltstack. |
72 | |
69 | |
73 | l Older GNU/Linux systems (glibc-2.1 and below) need this hack. Since it is |
70 | l GNU/Linux. Very old GNU/Linux systems (glibc-2.1 and below) need |
74 | very linux-specific it is also quite fast for newer versions; when it |
71 | this hack. Since it is very linux-specific it is also quite fast and |
75 | works, that is (currently x86 only)... |
72 | recommended even for newer versions; when it works, that is (currently |
|
|
73 | x86 and a few others only. If it compiles, it's usually ok). |
76 | |
74 | |
77 | i IRIX. For some reason, SGI really does not like to follow the unix |
75 | i IRIX. For some reason, SGI really does not like to follow the single |
78 | standard (does that surprise you?), so this workaround might be needed |
76 | unix specification (does that surprise you?), so this workaround might |
79 | (it's fast), although s and u should also work now. |
77 | be needed (it's fast), although [s] and [u] should also work now. |
|
|
78 | |
|
|
79 | w Microsoft Windows. Try this on Microsoft Windows, although, as there is |
|
|
80 | no standard on how to do this under windows, this might work only on |
|
|
81 | cygwin or specific versions of msvc. Your problem. |
|
|
82 | |
|
|
83 | For most systems, the default chosen should be OK. If you experience |
|
|
84 | problems then you should experiment with this setting and/or turn off |
|
|
85 | optimizations (make OPTIMIZE=-O0). |
80 | |
86 | |
81 | EOF |
87 | EOF |
82 | |
88 | |
83 | retry: |
89 | retry: |
84 | |
90 | |
85 | my $r = prompt "Use which implementation,\n" . |
91 | my $r = prompt "Use which implementation,\n" . |
86 | "<s>etjmp/longjump, <u>context, <i>rix or <l>inux?", |
92 | "<s>etjmp/longjump, <u>context, <i>rix, <l>inux or <w>indows?", |
87 | $iface; |
93 | $iface; |
88 | $iface = lc $1 if $r =~ /(\S)/; |
94 | $iface = lc $1 if $r =~ /(\S)/; |
89 | |
95 | |
90 | if ($iface eq "u") { |
96 | if ($iface eq "u") { |
91 | $DEFINE .= " -DCORO_UCONTEXT"; |
97 | $DEFINE .= " -DCORO_UCONTEXT"; |
92 | print "\nUsing ucontext implementation\n\n"; |
98 | print "\nUsing ucontext implementation\n\n"; |
93 | conftest("TEST_makecontext"); |
99 | conftest("TEST_makecontext"); |
94 | } elsif ($iface eq "s") { |
100 | } elsif ($iface eq "s") { |
95 | $DEFINE .= " -DCORO_SJLJ"; |
101 | $DEFINE .= " -DCORO_SJLJ"; |
96 | print "\nUsing setjmp/longjmp/sigaltstack implementation\n\n"; |
102 | print "\nUsing setjmp/longjmp/sigaltstack implementation\n\n"; |
97 | conftest("TEST_sigaltstack"); |
103 | conftest("TEST_sigaltstack"); |
98 | } elsif ($iface eq "l") { |
104 | } elsif ($iface eq "l") { |
99 | $DEFINE .= " -DCORO_LINUX"; |
105 | $DEFINE .= " -DCORO_LINUX"; |
100 | print "\nUsing linux-specific implementation\n\n"; |
106 | print "\nUsing linux-specific implementation\n\n"; |
101 | } elsif ($iface eq "i") { |
107 | } elsif ($iface eq "i") { |
102 | $DEFINE .= " -DCORO_IRIX"; |
108 | $DEFINE .= " -DCORO_IRIX"; |
103 | print "\nUsing irix-specific implementation\n\n"; |
109 | print "\nUsing irix-specific implementation\n\n"; |
104 | } else { |
110 | } elsif ($iface eq "w") { |
105 | print "\nUnknown implementation \"$iface\"\n"; |
111 | $DEFINE .= " -DCORO_LOSER"; |
106 | goto retry; |
112 | print "\nUsing windows-specific implementation\n\n"; |
107 | } |
|
|
108 | } else { |
113 | } else { |
109 | print "\nUsing microsoft compatible coroutines\n\n"; |
114 | print "\nUnknown implementation \"$iface\"\n"; |
|
|
115 | goto retry; |
110 | } |
116 | } |
|
|
117 | |
|
|
118 | print <<EOF; |
|
|
119 | |
|
|
120 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
121 | |
|
|
122 | Per-context stack size factor: Depending on your settings, Coro tries to |
|
|
123 | share the C stack as much as possible, but sometimes it needs to allocate |
|
|
124 | a new one. This setting controls the maximum size that gets allocated, |
|
|
125 | and should not be set too high, as memory and address space still is |
|
|
126 | wasted even if it's not fully used. The value entered will be multiplied |
|
|
127 | by sizeof(long), which is usually 4 on 32-bit systems, and 8 on 64-bit |
|
|
128 | systems. |
|
|
129 | |
|
|
130 | A setting of 16384 (the default) therefore corresponds to a 64k..128k |
|
|
131 | stack, which usually is ample space (you might even want to try 8192 or |
|
|
132 | lower if your program creates many coroutines). |
|
|
133 | |
|
|
134 | On systems supporting mmap and dynamic memory management, the actual |
|
|
135 | memory usually gets allocated on demand, but with many large stacks you |
|
|
136 | can still run out of address space on your typical 32 bit platform. |
|
|
137 | |
|
|
138 | Some perls (mostly threaded ones and perl compiled under linux 2.6) and |
|
|
139 | some programs (inefficient regexes can use a lot of stack space) may |
|
|
140 | need much, much more: If Coro segfaults with weird backtraces (e.g. in a |
|
|
141 | function prologue) or in t/10_bugs.t, you might want to increase this to |
|
|
142 | 65536 or more. |
|
|
143 | |
|
|
144 | The default should be fine, and can be changed at runtime with |
|
|
145 | Coro::State::cctx_stacksize. |
|
|
146 | |
|
|
147 | EOF |
|
|
148 | |
|
|
149 | my $stacksize = prompt ("C stack size factor?", "16384"); |
|
|
150 | $DEFINE .= " -DCORO_STACKSIZE=$stacksize"; |
|
|
151 | |
|
|
152 | print "using a stacksize of $stacksize * sizeof(long)\n"; |
|
|
153 | |
|
|
154 | print <<EOF; |
|
|
155 | |
|
|
156 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
157 | |
|
|
158 | Coro can optionally put a guard area before each stack segment. When the |
|
|
159 | stack is too small and the access is not too far outside the stack (i.e. |
|
|
160 | within the guard area), then the program will safely segfault instead of |
|
|
161 | running into other data. The cost is some additional overhead with is |
|
|
162 | usually negligible, and extra use of address space. |
|
|
163 | |
|
|
164 | The guard area size currently needs to be specified in pages (typical |
|
|
165 | pagesizes are 4k and 8k). The guard area is only enabled on a few |
|
|
166 | hardcoded architectures and is ignored on others. The actual preprocessor |
|
|
167 | expression disables this feature if: |
|
|
168 | |
|
|
169 | !__i386 && !__x86_64 && !__powerpc && !__m68k \ |
|
|
170 | && !__alpha && !__mips && !__sparc64 |
|
|
171 | |
|
|
172 | The default, as usual, should be just fine. |
|
|
173 | |
|
|
174 | EOF |
|
|
175 | |
|
|
176 | my $stackguard = prompt ("Number of guard pages (0 disables)?", "4"); |
|
|
177 | $DEFINE .= " -DCORO_STACKGUARD=$stackguard"; |
|
|
178 | |
|
|
179 | print <<EOF; |
|
|
180 | |
|
|
181 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
182 | |
|
|
183 | Coro can tell valgrind about its stacks and so reduce spurious warnings |
|
|
184 | where valgrind would otherwise complain about possible stack switches. |
|
|
185 | |
|
|
186 | Enabling this does not incur visible runtime or memory overhead, but it |
|
|
187 | requires that you have the <valgrind/valgrind.h> header file available. |
|
|
188 | |
|
|
189 | Valgrind support is completely optional, so the default of disabling it is |
|
|
190 | the safe choice. |
|
|
191 | |
|
|
192 | EOF |
|
|
193 | |
|
|
194 | my $valgrind = prompt ("Enable valgrind support (y/n)?", |
|
|
195 | -r "/usr/include/valgrind/valgrind.h" ? "y" : "n"); |
|
|
196 | $DEFINE .= " -DCORO_USE_VALGRIND=1" if $valgrind =~ /[yY]/; |
|
|
197 | |
|
|
198 | |
|
|
199 | print <<EOF; |
|
|
200 | |
|
|
201 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
202 | |
|
|
203 | Coro can use (or even trick) some perl functions into doing what it needs |
|
|
204 | instead of relying on (some) of its own functions. This might increase |
|
|
205 | chances that it compiles and works, but it could just as well result in |
|
|
206 | memory leaks, crashes or silent data corruption. It certainly does result |
|
|
207 | in slightly slower speed and higher memory consumption, though, so you |
|
|
208 | should enable it only as a last resort. |
|
|
209 | |
|
|
210 | EOF |
|
|
211 | |
|
|
212 | my $use_internals = prompt ("Prefer perl functions over coro functions (y/n)?", "n"); |
|
|
213 | $DEFINE .= " -DCORO_PREFER_PERL_FUNCTIONS=1" if $use_internals =~ /[yY]/; |
|
|
214 | |
|
|
215 | print <<EOF; |
|
|
216 | |
|
|
217 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
|
|
218 | |
|
|
219 | EOF |
111 | |
220 | |
112 | WriteMakefile( |
221 | WriteMakefile( |
113 | NAME => "Coro::State", |
222 | NAME => "Coro::State", |
114 | VERSION_FROM => "State.pm", |
223 | VERSION_FROM => "State.pm", |
115 | DEFINE => $DEFINE, |
224 | DEFINE => $DEFINE, |
… | |
… | |
127 | $res =~ s/\s+$//; |
236 | $res =~ s/\s+$//; |
128 | my ($sp, $ss) = split /,/, $res; |
237 | my ($sp, $ss) = split /,/, $res; |
129 | |
238 | |
130 | print "\n\n*****************************************************************************\n"; |
239 | print "\n\n*****************************************************************************\n"; |
131 | print "If the testsuite fails PLEASE provide the following information\n"; |
240 | print "If the testsuite fails PLEASE provide the following information\n"; |
132 | print "to Marc Lehmann <pcg\@goof.com>: operating system name, version,\n"; |
241 | print "to Marc Lehmann <schmorp\@schmorp.de>: operating system name, version,\n"; |
133 | print "architecture name and this string '$sp|$ss'. Thanks a lot!\n";#d# |
242 | print "architecture name and this string '$sp|$ss'. Thanks a lot!\n";#d# |
134 | print "*****************************************************************************\n\n"; |
243 | print "*****************************************************************************\n\n"; |
135 | |
244 | |
136 | unlink "a.out"; |
245 | unlink "a.out"; |
137 | unlink "conftestval"; |
246 | unlink "conftestval"; |