pref: add support for `-thread-stack-size 4194304` (default set to 8MB) (#14168)

Delyan Angelov 2022-04-28 08:46:33 +03:00 committed by Jef Roosens
parent 47c18c4570
commit 444d8c7a81
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 51 additions and 2 deletions

View File

@ -257,7 +257,7 @@ see also `v help build`.
Passing -no-std will remove that flag, and you can then use -cflags ''
to pass the other options for your specific C compiler.
-assert aborts
-assert aborts
Call abort() after an assertion failure. Debuggers usually
install signal handlers for SIGABRT, so your program will stop and you
will get a backtrace. If you are running your program outside of a
@ -267,3 +267,14 @@ see also `v help build`.
Call print_backtrace() after an assertion failure. Note that
backtraces are not implemented yet on all combinations of
platform/compiler.
-thread-stack-size 4194304
Set the thread stack size to 4MB. Use multiples of 4096.
The default is 8MB, which is enough for compiling V programs, with deeply
nested expressions (~40 levels).
It may need to be increased, if you are getting stack overflow errors for
deeply recursive programs like some of the stages of the V compiler itself,
that use relatively few threads.
It may be decreased, to reduce the memory footprint of programs that launch
hundreds/thousands of threads, but where each of the threads does not need
a big stack.

View File

@ -1777,7 +1777,14 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
}
} else {
g.writeln('pthread_t thread_$tmp;')
g.writeln('int ${tmp}_thr_res = pthread_create(&thread_$tmp, NULL, (void*)$wrapper_fn_name, $arg_tmp_var);')
mut sthread_attributes := 'NULL'
if g.pref.os != .vinix {
g.writeln('pthread_attr_t thread_${tmp}_attributes;')
g.writeln('pthread_attr_init(&thread_${tmp}_attributes);')
g.writeln('pthread_attr_setstacksize(&thread_${tmp}_attributes, $g.pref.thread_stack_size);')
sthread_attributes = '&thread_${tmp}_attributes'
}
g.writeln('int ${tmp}_thr_res = pthread_create(&thread_$tmp, $sthread_attributes, (void*)$wrapper_fn_name, $arg_tmp_var);')
g.writeln('if (${tmp}_thr_res) panic_error_number(tos3("`go ${name}()`: "), ${tmp}_thr_res);')
if !node.is_expr {
g.writeln('pthread_detach(thread_$tmp);')

View File

@ -199,6 +199,7 @@ pub mut:
nofloat bool // for low level code, like kernels: replaces f32 with u32 and f64 with u64
// checker settings:
checker_match_exhaustive_cutoff_limit int = 12
thread_stack_size int = 8388608 // Change with `-thread-stack-size 4194304`. Note: on macos it was 524288, which is too small for more complex programs with many nested callexprs.
}
pub fn parse_args(known_external_commands []string, args []string) (&Preferences, string) {
@ -571,6 +572,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
res.message_limit = cmdline.option(current_args, arg, '5').int()
i++
}
'-thread-stack-size' {
res.thread_stack_size = cmdline.option(current_args, arg, res.thread_stack_size.str()).int()
i++
}
'-cc' {
res.ccompiler = cmdline.option(current_args, '-cc', 'cc')
res.build_options << '$arg "$res.ccompiler"'

View File

@ -0,0 +1,26 @@
fn f(x u8) u8 {
eprintln('> f: $x')
if x == 0 {
return 0
}
mut local := [131072]u8{}
local[local.len - 1] = x + f(x - 1)
return local[0] + local[local.len - 1]
}
fn abc(depth u8) u8 {
return f(depth)
}
fn test_default_stack_depth() {
$if tinyc && windows {
exit(0) // skip for now testing on windows-tcc
}
// Note: 10 levels of recursing f, requires a little over 1.4MB,
// and would have failed on macos, where the default thread size
// is just 512KB, if V was not changed to have a default for
// `-thread-stack-size` of 8MB.
t := go abc(10)
res := t.wait()
assert res == 55
}