mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: support [spawn_stack: 131072]
fn attribute, for controlling the max size of the stack, of the spawned threads (#17222)
This commit is contained in:
parent
19ba7c5ceb
commit
dcb9c3beb3
19
examples/control_thread_stack_size.v
Normal file
19
examples/control_thread_stack_size.v
Normal file
@ -0,0 +1,19 @@
|
||||
module main
|
||||
|
||||
fn main() {
|
||||
th := spawn my_print1()
|
||||
th.wait()
|
||||
th2 := spawn my_print2()
|
||||
th2.wait()
|
||||
}
|
||||
|
||||
// default stack size
|
||||
fn my_print1() {
|
||||
println('hello word')
|
||||
}
|
||||
|
||||
// 2MB stack size
|
||||
[spawn_stack: 2097152]
|
||||
fn my_print2() {
|
||||
println('ahoj svet')
|
||||
}
|
@ -14,6 +14,8 @@ const diff_cmd = diff.find_working_diff_command() or { '' }
|
||||
|
||||
const show_compilation_output = os.getenv('VTEST_SHOW_COMPILATION_OUTPUT').int() == 1
|
||||
|
||||
const user_os = os.user_os()
|
||||
|
||||
fn mm(s string) string {
|
||||
return term.colorize(term.magenta, s)
|
||||
}
|
||||
@ -36,6 +38,9 @@ fn test_out_files() {
|
||||
mut total_errors := 0
|
||||
for out_path in paths {
|
||||
basename, path, relpath, out_relpath := target2paths(out_path, '.out')
|
||||
if should_skip(relpath) {
|
||||
continue
|
||||
}
|
||||
pexe := os.join_path(output_path, '${basename}.exe')
|
||||
//
|
||||
file_options := get_file_options(path)
|
||||
@ -108,6 +113,9 @@ fn test_c_must_have_files() {
|
||||
mut failed_descriptions := []string{cap: paths.len}
|
||||
for must_have_path in paths {
|
||||
basename, path, relpath, must_have_relpath := target2paths(must_have_path, '.c.must_have')
|
||||
if should_skip(relpath) {
|
||||
continue
|
||||
}
|
||||
file_options := get_file_options(path)
|
||||
alloptions := '-o - ${file_options.vflags}'
|
||||
description := mm('v ${alloptions} ${relpath}') +
|
||||
@ -221,3 +229,18 @@ pub fn get_file_options(file string) FileOptions {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fn should_skip(relpath string) bool {
|
||||
if user_os == 'windows' {
|
||||
if relpath.contains('_nix.vv') {
|
||||
eprintln('> skipping ${relpath} on windows')
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if relpath.contains('_windows.vv') {
|
||||
eprintln('> skipping ${relpath} on !windows')
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -1972,7 +1972,8 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
|
||||
} else {
|
||||
'thread_${tmp}'
|
||||
}
|
||||
g.writeln('HANDLE ${simple_handle} = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)${wrapper_fn_name}, ${arg_tmp_var}, 0, 0);')
|
||||
stack_size := g.get_cur_thread_stack_size(expr.name)
|
||||
g.writeln('HANDLE ${simple_handle} = CreateThread(0, ${stack_size}, (LPTHREAD_START_ROUTINE)${wrapper_fn_name}, ${arg_tmp_var}, 0, 0); // fn: ${expr.name}')
|
||||
g.writeln('if (!${simple_handle}) panic_lasterr(tos3("`go ${name}()`: "));')
|
||||
if node.is_expr && node.call_expr.return_type != ast.void_type {
|
||||
g.writeln('${gohandle_name} thread_${tmp} = {')
|
||||
@ -1989,7 +1990,8 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
|
||||
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});')
|
||||
size := g.get_cur_thread_stack_size(expr.name)
|
||||
g.writeln('pthread_attr_setstacksize(&thread_${tmp}_attributes, ${size}); // fn: ${expr.name}')
|
||||
sthread_attributes = '&thread_${tmp}_attributes'
|
||||
}
|
||||
g.writeln('int ${tmp}_thr_res = pthread_create(&thread_${tmp}, ${sthread_attributes}, (void*)${wrapper_fn_name}, ${arg_tmp_var});')
|
||||
@ -2210,6 +2212,22 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
|
||||
}
|
||||
}
|
||||
|
||||
// get current thread size, if fn hasn't defined return default
|
||||
[inline]
|
||||
fn (mut g Gen) get_cur_thread_stack_size(name string) string {
|
||||
ast_fn := g.table.fns[name] or { return '${g.pref.thread_stack_size}' }
|
||||
attrs := ast_fn.attrs
|
||||
if isnil(attrs) {
|
||||
return '${g.pref.thread_stack_size}'
|
||||
}
|
||||
for attr in attrs {
|
||||
if attr.name == 'spawn_stack' {
|
||||
return attr.arg
|
||||
}
|
||||
}
|
||||
return '${g.pref.thread_stack_size}'
|
||||
}
|
||||
|
||||
// similar to `autofree_call_pregen()` but only to to handle [keep_args_alive] for C functions
|
||||
fn (mut g Gen) keep_alive_call_pregen(node ast.CallExpr) int {
|
||||
g.empty_line = true
|
||||
|
2
vlib/v/gen/c/testdata/spawn_stack_nix.c.must_have
vendored
Normal file
2
vlib/v/gen/c/testdata/spawn_stack_nix.c.must_have
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
pthread_attr_setstacksize(&thread__t3_attributes, 65536); // fn: main.my_print2
|
||||
pthread_attr_setstacksize(&thread__t5_attributes, 131072); // fn: main.my_print3
|
3
vlib/v/gen/c/testdata/spawn_stack_nix.out
vendored
Normal file
3
vlib/v/gen/c/testdata/spawn_stack_nix.out
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
hello word
|
||||
ahoj svet
|
||||
здравей свят
|
27
vlib/v/gen/c/testdata/spawn_stack_nix.vv
vendored
Normal file
27
vlib/v/gen/c/testdata/spawn_stack_nix.vv
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
module main
|
||||
|
||||
fn main() {
|
||||
th := spawn my_print1()
|
||||
th.wait()
|
||||
th2 := spawn my_print2()
|
||||
th2.wait()
|
||||
th3 := spawn my_print3()
|
||||
th3.wait()
|
||||
}
|
||||
|
||||
// default stack size
|
||||
fn my_print1() {
|
||||
println('hello word')
|
||||
}
|
||||
|
||||
// 64KB stack size
|
||||
[spawn_stack: 65536]
|
||||
fn my_print2() {
|
||||
println('ahoj svet')
|
||||
}
|
||||
|
||||
// 64KB stack size
|
||||
[spawn_stack: 131072]
|
||||
fn my_print3() {
|
||||
println('здравей свят')
|
||||
}
|
2
vlib/v/gen/c/testdata/spawn_stack_windows.c.must_have
vendored
Normal file
2
vlib/v/gen/c/testdata/spawn_stack_windows.c.must_have
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
CreateThread(0, 65536, (LPTHREAD_START_ROUTINE)main__my_print2_thread_wrapper
|
||||
CreateThread(0, 131072, (LPTHREAD_START_ROUTINE)main__my_print3_thread_wrapper
|
3
vlib/v/gen/c/testdata/spawn_stack_windows.out
vendored
Normal file
3
vlib/v/gen/c/testdata/spawn_stack_windows.out
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
hello word
|
||||
ahoj svet
|
||||
здравей свят
|
27
vlib/v/gen/c/testdata/spawn_stack_windows.vv
vendored
Normal file
27
vlib/v/gen/c/testdata/spawn_stack_windows.vv
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
module main
|
||||
|
||||
fn main() {
|
||||
th := spawn my_print1()
|
||||
th.wait()
|
||||
th2 := spawn my_print2()
|
||||
th2.wait()
|
||||
th3 := spawn my_print3()
|
||||
th3.wait()
|
||||
}
|
||||
|
||||
// default stack size
|
||||
fn my_print1() {
|
||||
println('hello word')
|
||||
}
|
||||
|
||||
// 64KB stack size
|
||||
[spawn_stack: 65536]
|
||||
fn my_print2() {
|
||||
println('ahoj svet')
|
||||
}
|
||||
|
||||
// 64KB stack size
|
||||
[spawn_stack: 131072]
|
||||
fn my_print3() {
|
||||
println('здравей свят')
|
||||
}
|
Loading…
Reference in New Issue
Block a user