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:
parent
d2fa937a21
commit
cf73357e37
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user