Skip to content

Commit 75e79ad

Browse files
author
Bryan C. Mills
committed
cmd/api: limit concurrent 'go list' calls to GOMAXPROCS
Each invocation of 'go list' may consume a significant quantity of system resources, including buffers for reading files and RAM for the runtime's memory footprint. Very small builders may even hit swap as a result of that load, further exacerbating resource contention. To avoid overloading small builders, restrict 'go list' calls to runtime.GOMAXPROCS as it is set at the first call to loadImports. This also somewhat improves running time even on larger machines: on my workstation, this change reduces the wall time for 'go test cmd/api' by around 100ms. Updates #38537 Change-Id: I968e0f961a8f1d84c27e1ab8b621b9670dcfd448 Reviewed-on: https://go-review.googlesource.com/c/go/+/228998 Run-TryBot: Bryan C. Mills <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 40a144b commit 75e79ad

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

src/cmd/api/goapi.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ type listImports struct {
444444

445445
var listCache sync.Map // map[string]listImports, keyed by contextName
446446

447+
// listSem is a semaphore restricting concurrent invocations of 'go list'.
448+
var listSem = make(chan semToken, runtime.GOMAXPROCS(0))
449+
450+
type semToken struct{}
451+
447452
// loadImports populates w with information about the packages in the standard
448453
// library and the packages they themselves import in w's build context.
449454
//
@@ -468,6 +473,9 @@ func (w *Walker) loadImports() {
468473

469474
imports, ok := listCache.Load(name)
470475
if !ok {
476+
listSem <- semToken{}
477+
defer func() { <-listSem }()
478+
471479
cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std")
472480
cmd.Env = listEnv(w.context)
473481
out, err := cmd.CombinedOutput()

0 commit comments

Comments
 (0)