mirror of https://github.com/golang/go.git
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>
This commit is contained in:
parent
c2cdfbd1a7
commit
a379b7d9ac
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue