From cf73357e37b08fe80600470bb7618e1ea951b42e Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Wed, 28 Oct 2015 14:41:58 -0400 Subject: [PATCH] cmd/link: concurrent obj copy for external linking Change-Id: I630ae29ecb39252642883398cc51d49133c6f3d7 Reviewed-on: https://go-review.googlesource.com/16451 Reviewed-by: Ian Lance Taylor Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot --- src/cmd/link/internal/ld/lib.go | 52 +++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index c0dc9c7c0d..f3ca4b8f27 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -46,6 +46,7 @@ import ( "path/filepath" "runtime" "strings" + "sync" ) // Data layout and relocation. @@ -916,28 +917,41 @@ func hostlinksetup() { // hostobjCopy creates a copy of the object files in hostobj in a // temporary directory. func hostobjCopy() (paths []string) { + var wg sync.WaitGroup + sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors for i, h := range hostobj { - f, err := os.Open(h.file) - if err != nil { - Exitf("cannot reopen %s: %v", h.pn, err) - } - if _, err := f.Seek(h.off, 0); err != nil { - Exitf("cannot seek %s: %v", h.pn, err) - } + h := h + dst := fmt.Sprintf("%s/%06d.o", tmpdir, i) + paths = append(paths, dst) - p := fmt.Sprintf("%s/%06d.o", tmpdir, i) - paths = append(paths, p) - w, err := os.Create(p) - if err != nil { - Exitf("cannot create %s: %v", p, err) - } - if _, err := io.CopyN(w, f, h.length); err != nil { - Exitf("cannot write %s: %v", p, err) - } - if err := w.Close(); err != nil { - Exitf("cannot close %s: %v", p, err) - } + wg.Add(1) + go func() { + sema <- struct{}{} + defer func() { + <-sema + wg.Done() + }() + f, err := os.Open(h.file) + if err != nil { + Exitf("cannot reopen %s: %v", h.pn, err) + } + if _, err := f.Seek(h.off, 0); err != nil { + Exitf("cannot seek %s: %v", h.pn, err) + } + + w, err := os.Create(dst) + if err != nil { + Exitf("cannot create %s: %v", dst, err) + } + if _, err := io.CopyN(w, f, h.length); err != nil { + Exitf("cannot write %s: %v", dst, err) + } + if err := w.Close(); err != nil { + Exitf("cannot close %s: %v", dst, err) + } + }() } + wg.Wait() return paths }