1
0
mirror of https://github.com/golang/go synced 2024-09-30 16:18:35 -06:00

cmd/link: concurrent obj copy for external linking

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>
This commit is contained in:
David Crawshaw 2015-10-28 14:41:58 -04:00
parent d2fa937a21
commit cf73357e37

View File

@ -46,6 +46,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"sync"
) )
// Data layout and relocation. // Data layout and relocation.
@ -916,28 +917,41 @@ func hostlinksetup() {
// hostobjCopy creates a copy of the object files in hostobj in a // hostobjCopy creates a copy of the object files in hostobj in a
// temporary directory. // temporary directory.
func hostobjCopy() (paths []string) { func hostobjCopy() (paths []string) {
var wg sync.WaitGroup
sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
for i, h := range hostobj { for i, h := range hostobj {
f, err := os.Open(h.file) h := h
if err != nil { dst := fmt.Sprintf("%s/%06d.o", tmpdir, i)
Exitf("cannot reopen %s: %v", h.pn, err) paths = append(paths, dst)
}
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) wg.Add(1)
paths = append(paths, p) go func() {
w, err := os.Create(p) sema <- struct{}{}
if err != nil { defer func() {
Exitf("cannot create %s: %v", p, err) <-sema
} wg.Done()
if _, err := io.CopyN(w, f, h.length); err != nil { }()
Exitf("cannot write %s: %v", p, err) f, err := os.Open(h.file)
} if err != nil {
if err := w.Close(); err != nil { Exitf("cannot reopen %s: %v", h.pn, err)
Exitf("cannot close %s: %v", p, 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 return paths
} }