diff options
| author | Richard Miller <miller.research@gmail.com> | 2018-02-28 14:29:27 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2018-02-28 16:26:49 +0000 |
| commit | a379b7d9acd69cd4a23eec7d7409084e15f8ace0 (patch) | |
| tree | a151d6bf033d9fdb3845b2370ef1e0f09fb79bfb /src/syscall | |
| parent | c2cdfbd1a75b74bf7b960f6904fcfaaad9edb708 (diff) | |
| download | go-a379b7d9acd69cd4a23eec7d7409084e15f8ace0.tar.xz | |
syscall: reduce redundant getwd tracking in Plan 9
In Plan 9, each M is implemented as a separate OS process with
its own working directory. To keep the wd consistent across
goroutines (or rescheduling of the same goroutine), CL 6350
introduced a Fixwd procedure which checks using getwd and calls
chdir if necessary before any syscall operating on a pathname.
This wd checking will not be necessary if the pathname is absolute
(starts with '/' or '#'). Getwd is a fairly expensive operation
in Plan 9 (implemented by opening "." and calling Fd2path on the
file descriptor). Eliminating the redundant getwd calls can
significantly reduce overhead for common operations like
"dist test --list" which perform many syscalls on absolute pathnames.
Updates #9428.
Change-Id: I13fd9380779de27b0ac2f2b488229778d6839255
Reviewed-on: https://go-review.googlesource.com/97675
Reviewed-by: David du Colombier <0intro@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: David du Colombier <0intro@gmail.com>
Diffstat (limited to 'src/syscall')
| -rw-r--r-- | src/syscall/pwd_plan9.go | 10 | ||||
| -rw-r--r-- | src/syscall/syscall_plan9.go | 16 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/syscall/pwd_plan9.go b/src/syscall/pwd_plan9.go index 12486135f0..1deeaa9061 100644 --- a/src/syscall/pwd_plan9.go +++ b/src/syscall/pwd_plan9.go @@ -39,6 +39,15 @@ func fixwdLocked() { } } +func fixwd(paths ...string) { + for _, path := range paths { + if path != "" && path[0] != '/' && path[0] != '#' { + Fixwd() + return + } + } +} + // goroutine-specific getwd func getwd() (wd string, err error) { fd, err := open(".", O_RDONLY) @@ -66,6 +75,7 @@ func Getwd() (wd string, err error) { } func Chdir(path string) error { + fixwd(path) wdmu.Lock() defer wdmu.Unlock() diff --git a/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go index 7595126faa..48513c73c9 100644 --- a/src/syscall/syscall_plan9.go +++ b/src/syscall/syscall_plan9.go @@ -244,7 +244,7 @@ func Await(w *Waitmsg) (err error) { } func Unmount(name, old string) (err error) { - Fixwd() + fixwd(name, old) oldp, err := BytePtrFromString(old) if err != nil { return err @@ -326,43 +326,43 @@ func Getgroups() (gids []int, err error) { //sys open(path string, mode int) (fd int, err error) func Open(path string, mode int) (fd int, err error) { - Fixwd() + fixwd(path) return open(path, mode) } //sys create(path string, mode int, perm uint32) (fd int, err error) func Create(path string, mode int, perm uint32) (fd int, err error) { - Fixwd() + fixwd(path) return create(path, mode, perm) } //sys remove(path string) (err error) func Remove(path string) error { - Fixwd() + fixwd(path) return remove(path) } //sys stat(path string, edir []byte) (n int, err error) func Stat(path string, edir []byte) (n int, err error) { - Fixwd() + fixwd(path) return stat(path, edir) } //sys bind(name string, old string, flag int) (err error) func Bind(name string, old string, flag int) (err error) { - Fixwd() + fixwd(name, old) return bind(name, old, flag) } //sys mount(fd int, afd int, old string, flag int, aname string) (err error) func Mount(fd int, afd int, old string, flag int, aname string) (err error) { - Fixwd() + fixwd(old) return mount(fd, afd, old, flag, aname) } //sys wstat(path string, edir []byte) (err error) func Wstat(path string, edir []byte) (err error) { - Fixwd() + fixwd(path) return wstat(path, edir) } |
