1
0
mirror of https://github.com/golang/go synced 2024-09-30 14:28:33 -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"
"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
}