From: Bryan C. Mills Date: Mon, 20 Apr 2020 15:32:05 +0000 (-0400) Subject: cmd/api: limit concurrent 'go list' calls to GOMAXPROCS X-Git-Tag: go1.15beta1~485 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=75e79adaf94a3f883bd2d88467ee7c72ea18c0a3;p=gostls13.git 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 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go index 9874b29292..01b17b8839 100644 --- a/src/cmd/api/goapi.go +++ b/src/cmd/api/goapi.go @@ -444,6 +444,11 @@ type listImports struct { var listCache sync.Map // map[string]listImports, keyed by contextName +// listSem is a semaphore restricting concurrent invocations of 'go list'. +var listSem = make(chan semToken, runtime.GOMAXPROCS(0)) + +type semToken struct{} + // loadImports populates w with information about the packages in the standard // library and the packages they themselves import in w's build context. // @@ -468,6 +473,9 @@ func (w *Walker) loadImports() { imports, ok := listCache.Load(name) if !ok { + listSem <- semToken{} + defer func() { <-listSem }() + cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std") cmd.Env = listEnv(w.context) out, err := cmd.CombinedOutput()