Commit cf73357e authored by David Crawshaw's avatar David Crawshaw

cmd/link: concurrent obj copy for external linking

Change-Id: I630ae29ecb39252642883398cc51d49133c6f3d7
Reviewed-on: https://go-review.googlesource.com/16451Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent d2fa937a
...@@ -46,6 +46,7 @@ import ( ...@@ -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() { ...@@ -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 { wg.Add(1)
Exitf("cannot seek %s: %v", h.pn, err) 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) w, err := os.Create(dst)
paths = append(paths, p) if err != nil {
w, err := os.Create(p) Exitf("cannot create %s: %v", dst, err)
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", dst, 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", dst, err)
if err := w.Close(); err != nil { }
Exitf("cannot close %s: %v", p, err) }()
}
} }
wg.Wait()
return paths return paths
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment