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,7 +917,20 @@ func hostlinksetup() { ...@@ -916,7 +917,20 @@ 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 {
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) f, err := os.Open(h.file)
if err != nil { if err != nil {
Exitf("cannot reopen %s: %v", h.pn, err) Exitf("cannot reopen %s: %v", h.pn, err)
...@@ -925,19 +939,19 @@ func hostobjCopy() (paths []string) { ...@@ -925,19 +939,19 @@ func hostobjCopy() (paths []string) {
Exitf("cannot seek %s: %v", h.pn, err) 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)
w, err := os.Create(p)
if err != nil { if err != nil {
Exitf("cannot create %s: %v", p, err) Exitf("cannot create %s: %v", dst, err)
} }
if _, err := io.CopyN(w, f, h.length); err != nil { if _, err := io.CopyN(w, f, h.length); err != nil {
Exitf("cannot write %s: %v", p, err) Exitf("cannot write %s: %v", dst, err)
} }
if err := w.Close(); err != nil { if err := w.Close(); err != nil {
Exitf("cannot close %s: %v", p, err) Exitf("cannot close %s: %v", dst, 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