Skip to content

feat: run link and archive in parallel via argv spawn#1300

Open
krystophny wants to merge 3 commits into
fortran-lang:mainfrom
krystophny:feat/parallel-link-argv
Open

feat: run link and archive in parallel via argv spawn#1300
krystophny wants to merge 3 commits into
fortran-lang:mainfrom
krystophny:feat/parallel-link-argv

Conversation

@krystophny

Copy link
Copy Markdown
Contributor

Summary

  • Make link_executable, link_shared, and make_archive exec through run_argv
    instead of shelling out, so the critical(run_command) serialization is
    dropped and link/archive run concurrently under OpenMP
  • Rare shell fallbacks (tokenization failure) stay wrapped in
    critical(run_command) since those still fork
  • split_append / clean_shlex_token promoted to module scope so link and
    archive reuse the compile path's OS-native tokenization

Context

Commit bb891e3f wrapped link/archive in critical(run_command) because their
run() shells out and concurrent fork from OpenMP threads is not safe. This
serializes all linking and archiving. After the argv Fortran compile migration
(#1299), this change extends the safe spawn path to link and archive.

Merge order

This is PR 2 of 3 in the argv spawn chain. Merge in order:

  1. Fortran compiles via argv (feat: exec Fortran compiles via argv (posix_spawn/CreateProcess) #1299)
  2. This PR — parallel link/archive via argv
  3. C/C++ compiles via argv (feat: exec C/C++ compiles via argv, close the shell-fork gap #1301)

Note: Until #1299 merges, the diff for this PR includes its commits.
After merge, rebase will show only this PR's own commit.

Refs: #962

Verification

$ fpm build --flag -fopenmp
[100%] Project compiled successfully.

$ fpm test --flag -fopenmp
TALLY;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
PASSED: all 35 tests passed

A fresh sample project compiles, archives (libargvtest2.a), links, and runs
through the new argv archive+link path.

Extend the argv-based Fortran compile spawn to Windows so it no longer
falls back to the shell there. Tokenize with the OS-native lexer
(ms_split on Windows, sh_split on Unix) so backslash paths and quoting
survive, route run_argv through c_run_argv on both platforms, and add a
CreateProcessA path with per-process stdout/stderr redirect. The shell
run remains as a fallback when the spawn returns a negative status.

Windows std handles are only overridden when redirecting, to avoid
stripping the child console; out-of-range child exit codes are clamped
positive so they are not mistaken for the spawn-failure sentinel.
Replace the shell run() in link_executable/link_shared/make_archive
with an argv spawn through run_argv (posix_spawn on Unix, CreateProcess
on Windows), which is fork-safe under OpenMP, and drop the
critical(run_command) that previously serialized them. Link and archive
steps now run in parallel; the rare shell fallback (tokenization
failure) and run_argv's own shell fallback stay serialized under
critical(run_command).

make_archive reproduces 'self%ar // output' exactly: the archive name
glues onto the last flag token for MSVC 'lib /OUT:' and is a separate
token for GNU 'ar -rs '. Promote split_append/clean_shlex_token to
module scope so link/archive reuse the compile path tokenization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant