Commit a379b7d9 authored by Richard Miller's avatar Richard Miller Committed by Brad Fitzpatrick

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/97675Reviewed-by: 's avatarDavid du Colombier <0intro@gmail.com>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: David du Colombier <0intro@gmail.com>
parent c2cdfbd1
......@@ -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()
......
......@@ -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)
}
......
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