diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 0307f7c2d39..f8a17b03843 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -23,6 +23,7 @@ import ( "fmt" "io" "path/filepath" + "runtime" "sort" "strings" @@ -115,6 +116,12 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W builderCtx.CoreBuildCachePath = paths.TempDir().Join("arduino-core-cache") + jobs := runtime.NumCPU() + if req.GetJobs() > 0 { + jobs = int(req.GetJobs()) + } + builderCtx.Jobs = jobs + builderCtx.USBVidPid = req.GetVidPid() builderCtx.WarningsLevel = req.GetWarnings() diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 07b021ee8bf..72c109da793 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -175,20 +175,30 @@ func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources ctx.Progress.Steps = ctx.Progress.Steps / float64(len(sources)) var wg sync.WaitGroup - wg.Add(len(sources)) - for _, source := range sources { - go func(source *paths.Path) { - defer wg.Done() - PrintProgressIfProgressEnabledAndMachineLogger(ctx) - objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe) - if err != nil { - errorsChan <- err - } else { - objectFilesChan <- objectFile + // Split jobs into batches of N jobs each; wait for the completion of a batch to start the next + par := ctx.Jobs + + go func() { + for total := 0; total < len(sources); total += par { + for i := total; i < total+par && i < len(sources); i++ { + wg.Add(1) + go func(source *paths.Path) { + defer wg.Done() + PrintProgressIfProgressEnabledAndMachineLogger(ctx) + objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe) + if err != nil { + errorsChan <- err + } else { + objectFilesChan <- objectFile + } + }(sources[i]) } - }(source) - } + wg.Wait() + } + + doneChan <- struct{}{} + }() go func() { wg.Wait() diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index e2ed7ff8706..1a8a6b5c788 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -111,6 +111,9 @@ type Context struct { // Experimental: use arduino-preprocessor to create prototypes UseArduinoPreprocessor bool + // Parallel processes + Jobs int + // Out and Err stream to redirect all Exec commands ExecStdout io.Writer ExecStderr io.Writer