]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: concurrent obj copy for external linking
authorDavid Crawshaw <crawshaw@golang.org>
Wed, 28 Oct 2015 18:41:58 +0000 (14:41 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Mon, 2 Nov 2015 17:52:55 +0000 (17:52 +0000)
Change-Id: I630ae29ecb39252642883398cc51d49133c6f3d7
Reviewed-on: https://go-review.googlesource.com/16451
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/lib.go

index c0dc9c7c0d8c6734bf63b2dcd99f9429ee54767e..f3ca4b8f27231aa1414b52a7140e561e3b6f2781 100644 (file)
@@ -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)
+
+               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)
+                       }
 
-               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)
-               }
+                       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
 }