| 1 | import os |
| 2 | |
| 3 | const thread_bool_wait_codegen_vexe = @VEXE |
| 4 | |
| 5 | fn test_thread_bool_waiter_is_declared_before_array_waiter_uses_it_on_windows() { |
| 6 | tmp_dir := os.join_path(os.vtmp_dir(), 'thread_bool_wait_windows_test_${os.getpid()}') |
| 7 | os.mkdir_all(tmp_dir)! |
| 8 | defer { |
| 9 | os.rmdir_all(tmp_dir) or {} |
| 10 | } |
| 11 | source_path := os.join_path(os.real_path(tmp_dir), 'thread_bool_wait_windows.vv') |
| 12 | os.write_file(source_path, |
| 13 | "fn ping(url string) bool {\n\treturn url.len > 0\n}\n\nfn main() {\n\turls := ['a', 'b']\n\tmut threads := []thread bool{}\n\tfor url in urls {\n\t\tthreads << go ping(url)\n\t}\n\tresults := threads.wait()\n\tprintln(results)\n}\n")! |
| 14 | cmd := '${os.quoted_path(thread_bool_wait_codegen_vexe)} -o - -os windows ${os.quoted_path(source_path)}' |
| 15 | res := os.execute(cmd) |
| 16 | assert res.exit_code == 0, '${cmd}\n${res.output}' |
| 17 | lines := res.output.replace('\r\n', '\n').split_into_lines() |
| 18 | thread_wait_decl := 'bool __v_thread_bool_wait(__v_thread_bool thread);' |
| 19 | array_wait_def := 'Array_bool Array___v_thread_bool_wait(Array___v_thread_bool a) {' |
| 20 | wait_call := '((bool*)res.data)[i] = __v_thread_bool_wait(t);' |
| 21 | thread_wait_decl_idx := find_generated_c_line(lines, thread_wait_decl, 0) |
| 22 | assert thread_wait_decl_idx >= 0, res.output |
| 23 | array_wait_def_idx := find_generated_c_line(lines, array_wait_def, thread_wait_decl_idx + 1) |
| 24 | assert array_wait_def_idx > thread_wait_decl_idx, res.output |
| 25 | wait_call_idx := find_generated_c_line_containing(lines, wait_call, array_wait_def_idx + 1) |
| 26 | assert wait_call_idx > array_wait_def_idx, res.output |
| 27 | } |
| 28 | |
| 29 | fn test_prealloc_spawn_args_use_c_malloc() { |
| 30 | tmp_dir := os.join_path(os.vtmp_dir(), 'prealloc_spawn_arg_codegen_test_${os.getpid()}') |
| 31 | os.mkdir_all(tmp_dir)! |
| 32 | defer { |
| 33 | os.rmdir_all(tmp_dir) or {} |
| 34 | } |
| 35 | source_path := os.join_path(os.real_path(tmp_dir), 'prealloc_spawn_arg.vv') |
| 36 | os.write_file(source_path, |
| 37 | "fn worker(s string) {\n\tprintln(s)\n}\n\nfn answer() int {\n\treturn 42\n}\n\nfn main() {\n\tt := spawn worker('ok')\n\tt.wait()\n\tt2 := spawn answer()\n\tprintln(t2.wait())\n}\n")! |
| 38 | cmd := '${os.quoted_path(thread_bool_wait_codegen_vexe)} -prealloc -o - ${os.quoted_path(source_path)}' |
| 39 | res := os.execute(cmd) |
| 40 | assert res.exit_code == 0, '${cmd}\n${res.output}' |
| 41 | assert res.output.contains('(thread_arg_main__worker *) malloc(sizeof(thread_arg_main__worker))'), res.output |
| 42 | assert res.output.contains('prealloc_scope = builtin__prealloc_scope_retain_current();'), res.output |
| 43 | assert res.output.contains('void* thread_prealloc_scope = builtin__prealloc_scope_begin();'), res.output |
| 44 | assert res.output.contains('builtin__prealloc_scope_end(thread_prealloc_scope);'), res.output |
| 45 | assert res.output.contains('builtin__prealloc_scope_release(arg->prealloc_scope);'), res.output |
| 46 | assert res.output.contains('free(arg);'), res.output |
| 47 | assert !res.output.contains('builtin___v_malloc(sizeof(thread_arg_main__worker))'), res.output |
| 48 | assert res.output.contains('malloc(sizeof(int))'), res.output |
| 49 | assert res.output.contains('free(ret_ptr);'), res.output |
| 50 | } |
| 51 | |
| 52 | fn find_generated_c_line(lines []string, needle string, start int) int { |
| 53 | for idx := start; idx < lines.len; idx++ { |
| 54 | if lines[idx] == needle { |
| 55 | return idx |
| 56 | } |
| 57 | } |
| 58 | return -1 |
| 59 | } |
| 60 | |
| 61 | fn find_generated_c_line_containing(lines []string, needle string, start int) int { |
| 62 | for idx := start; idx < lines.len; idx++ { |
| 63 | if lines[idx].contains(needle) { |
| 64 | return idx |
| 65 | } |
| 66 | } |
| 67 | return -1 |
| 68 | } |
| 69 | |