diff options
author | Alex Brainman <alex.brainman@gmail.com> | 2012-03-02 14:47:40 +1100 |
---|---|---|
committer | Alex Brainman <alex.brainman@gmail.com> | 2012-03-02 14:47:40 +1100 |
commit | 99ef13563d81fc91504dbb538b02538ded46963a (patch) | |
tree | 7e79df85a6ec3615b5eef14b5560072e20ac887c | |
parent | 2dcfd6fa4642949594e2f56ccadc25ed8273f54c (diff) | |
download | go-99ef13563d81fc91504dbb538b02538ded46963a.tar.gz |
os: implement UserTime/SystemTime on windows
Fixes issue 3145.
R=golang-dev, rsc
CC=golang-dev
http://codereview.appspot.com/5721044
-rw-r--r-- | src/pkg/os/exec_windows.go | 16 | ||||
-rw-r--r-- | src/pkg/syscall/syscall_windows.go | 9 | ||||
-rw-r--r-- | src/pkg/syscall/zsyscall_windows_386.go | 13 | ||||
-rw-r--r-- | src/pkg/syscall/zsyscall_windows_amd64.go | 13 | ||||
-rw-r--r-- | src/pkg/syscall/ztypes_windows.go | 2 |
5 files changed, 47 insertions, 6 deletions
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go index 93360b15f..fa58020c0 100644 --- a/src/pkg/os/exec_windows.go +++ b/src/pkg/os/exec_windows.go @@ -27,9 +27,14 @@ func (p *Process) wait() (ps *ProcessState, err error) { if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } + var u syscall.Rusage + e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) + if e != nil { + return nil, NewSyscallError("GetProcessTimes", e) + } p.done = true defer p.Release() - return &ProcessState{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil + return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil } func (p *Process) signal(sig Signal) error { @@ -82,12 +87,15 @@ func init() { } } -// BUG(rsc): On Windows, ProcessState's UserTime and SystemTime methods always return 0. +func ftToDuration(ft *syscall.Filetime) time.Duration { + n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals + return time.Duration(n*100) * time.Nanosecond +} func (p *ProcessState) userTime() time.Duration { - return 0 + return ftToDuration(&p.rusage.UserTime) } func (p *ProcessState) systemTime() time.Duration { - return 0 + return ftToDuration(&p.rusage.KernelTime) } diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go index fde3bef50..7c82932d0 100644 --- a/src/pkg/syscall/syscall_windows.go +++ b/src/pkg/syscall/syscall_windows.go @@ -151,6 +151,7 @@ func NewCallback(fn interface{}) uintptr //sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) //sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW //sys GetCurrentProcess() (pseudoHandle Handle, err error) +//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) //sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) //sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] //sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW @@ -601,10 +602,14 @@ func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32 } // Invented structures to support what package os expects. -type Rusage struct{} +type Rusage struct { + CreationTime Filetime + ExitTime Filetime + KernelTime Filetime + UserTime Filetime +} type WaitStatus struct { - Status uint32 ExitCode uint32 } diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go index 0209463e5..8b1a6db90 100644 --- a/src/pkg/syscall/zsyscall_windows_386.go +++ b/src/pkg/syscall/zsyscall_windows_386.go @@ -55,6 +55,7 @@ var ( procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procGetTempPathW = modkernel32.NewProc("GetTempPathW") @@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) { return } +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + if int(r1) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = EINVAL + } + } + return +} + func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { var _p0 uint32 if bInheritHandle { diff --git a/src/pkg/syscall/zsyscall_windows_amd64.go b/src/pkg/syscall/zsyscall_windows_amd64.go index 95b8b36be..9d9990d10 100644 --- a/src/pkg/syscall/zsyscall_windows_amd64.go +++ b/src/pkg/syscall/zsyscall_windows_amd64.go @@ -55,6 +55,7 @@ var ( procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procGetTempPathW = modkernel32.NewProc("GetTempPathW") @@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) { return } +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + if int(r1) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = EINVAL + } + } + return +} + func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { var _p0 uint32 if bInheritHandle { diff --git a/src/pkg/syscall/ztypes_windows.go b/src/pkg/syscall/ztypes_windows.go index 5a7a50c08..e4881e561 100644 --- a/src/pkg/syscall/ztypes_windows.go +++ b/src/pkg/syscall/ztypes_windows.go @@ -252,6 +252,8 @@ type Filetime struct { HighDateTime uint32 } +// Nanoseconds returns Filetime ft in nanoseconds +// since Epoch (00:00:00 UTC, January 1, 1970). func (ft *Filetime) Nanoseconds() int64 { // 100-nanosecond intervals since January 1, 1601 nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) |