Skip to content

Commit 14a3adb

Browse files
committed
Parallelize library discovery phase in compile
1 parent 142c297 commit 14a3adb

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

internal/arduino/builder/internal/detector/cache.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"encoding/json"
2020
"fmt"
2121

22+
"github.com/arduino/arduino-cli/internal/arduino/builder/internal/runner"
2223
"github.com/arduino/go-paths-helper"
2324
)
2425

@@ -28,17 +29,18 @@ type detectorCache struct {
2829
}
2930

3031
type detectorCacheEntry struct {
31-
AddedIncludePath *paths.Path `json:"added_include_path,omitempty"`
32-
Compile *sourceFile `json:"compile,omitempty"`
33-
MissingIncludeH *string `json:"missing_include_h,omitempty"`
32+
AddedIncludePath *paths.Path `json:"added_include_path,omitempty"`
33+
Compile *sourceFile `json:"compile,omitempty"`
34+
CompileTask *runner.Task `json:"compile_task,omitempty"`
35+
MissingIncludeH *string `json:"missing_include_h,omitempty"`
3436
}
3537

3638
func (e *detectorCacheEntry) String() string {
3739
if e.AddedIncludePath != nil {
3840
return "Added include path: " + e.AddedIncludePath.String()
3941
}
40-
if e.Compile != nil {
41-
return "Compiling: " + e.Compile.String()
42+
if e.Compile != nil && e.CompileTask != nil {
43+
return "Compiling: " + e.Compile.String() + " / " + e.CompileTask.String()
4244
}
4345
if e.MissingIncludeH != nil {
4446
if *e.MissingIncludeH == "" {
@@ -109,6 +111,14 @@ func (c *detectorCache) Peek() *detectorCacheEntry {
109111
return nil
110112
}
111113

114+
// EntriesAhead returns the entries that are ahead of the current cache position.
115+
func (c *detectorCache) EntriesAhead() []*detectorCacheEntry {
116+
if c.curr < len(c.entries) {
117+
return c.entries[c.curr:]
118+
}
119+
return nil
120+
}
121+
112122
// Save writes the current cache to the given file.
113123
func (c *detectorCache) Save(cacheFile *paths.Path) error {
114124
// Cut off the cache if it is not fully consumed

internal/arduino/builder/internal/detector/detector.go

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type SketchLibrariesDetector struct {
5959
includeFolders paths.PathList
6060
logger *logger.BuilderLogger
6161
diagnosticStore *diagnostics.Store
62+
preRunner *runner.Runner
6263
}
6364

6465
// NewSketchLibrariesDetector todo
@@ -254,6 +255,18 @@ func (l *SketchLibrariesDetector) findIncludes(
254255
l.logger.Warn(i18n.Tr("Failed to load library discovery cache: %[1]s", err))
255256
}
256257

258+
// Pre-run cache entries
259+
l.preRunner = runner.New(ctx)
260+
for _, entry := range l.cache.EntriesAhead() {
261+
if entry.Compile != nil && entry.CompileTask != nil {
262+
upToDate, _ := entry.Compile.ObjFileIsUpToDate()
263+
if !upToDate {
264+
l.preRunner.Enqueue(entry.CompileTask)
265+
}
266+
}
267+
}
268+
defer l.preRunner.Cancel()
269+
257270
l.addIncludeFolder(buildCorePath)
258271
if buildVariantPath != nil {
259272
l.addIncludeFolder(buildVariantPath)
@@ -291,6 +304,15 @@ func (l *SketchLibrariesDetector) findIncludes(
291304
cachePath.Remove()
292305
return err
293306
}
307+
308+
// Create a new pre-runner if the previous one was cancelled
309+
if l.preRunner == nil {
310+
l.preRunner = runner.New(ctx)
311+
// Push in the remainder of the queue
312+
for _, sourceFile := range *sourceFileQueue {
313+
l.preRunner.Enqueue(l.gccPreprocessTask(sourceFile, buildProperties))
314+
}
315+
}
294316
}
295317

296318
// Finalize the cache
@@ -354,9 +376,9 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
354376

355377
first := true
356378
for {
357-
l.cache.Expect(&detectorCacheEntry{Compile: sourceFile})
358-
359379
preprocTask := l.gccPreprocessTask(sourceFile, buildProperties)
380+
l.cache.Expect(&detectorCacheEntry{Compile: sourceFile, CompileTask: preprocTask})
381+
360382
var preprocErr error
361383
var preprocResult *runner.Result
362384

@@ -368,8 +390,27 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
368390
}
369391
first = false
370392
} else {
371-
preprocResult = preprocTask.Run(ctx)
372-
preprocErr = preprocResult.Error
393+
if l.preRunner != nil {
394+
if r := l.preRunner.Results(preprocTask); r != nil {
395+
preprocResult = r
396+
preprocErr = preprocResult.Error
397+
}
398+
}
399+
if preprocResult == nil {
400+
// The pre-runner missed this task, maybe the cache is outdated
401+
// or maybe the source code changed.
402+
403+
// Stop the pre-runner
404+
if l.preRunner != nil {
405+
preRunner := l.preRunner
406+
l.preRunner = nil
407+
go preRunner.Cancel()
408+
}
409+
410+
// Run the actual preprocessor
411+
preprocResult = preprocTask.Run(ctx)
412+
preprocErr = preprocResult.Error
413+
}
373414
if l.logger.VerbosityLevel() == logger.VerbosityVerbose {
374415
l.logger.WriteStdout(preprocResult.Stdout)
375416
}

0 commit comments

Comments
 (0)