aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2012-03-02 14:47:40 +1100
committerAlex Brainman <alex.brainman@gmail.com>2012-03-02 14:47:40 +1100
commitc3fbc9a5e817d037f04abba4ec6d8a453afb344a (patch)
tree8060143471cfc7bc75609c38391f19c70b56dd0e
parent36d9ee4aec46a08e859ce30715c5034ada90645f (diff)
downloadgo-c3fbc9a5e817d037f04abba4ec6d8a453afb344a.tar.gz
go-c3fbc9a5e817d037f04abba4ec6d8a453afb344a.zip
os: implement UserTime/SystemTime on windows
Fixes #3145. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5721044
-rw-r--r--src/pkg/os/exec_windows.go16
-rw-r--r--src/pkg/syscall/syscall_windows.go9
-rw-r--r--src/pkg/syscall/zsyscall_windows_386.go13
-rw-r--r--src/pkg/syscall/zsyscall_windows_amd64.go13
-rw-r--r--src/pkg/syscall/ztypes_windows.go2
5 files changed, 47 insertions, 6 deletions
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
index 93360b15f1..fa58020c03 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 fde3bef50e..7c82932d0b 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 0209463e51..8b1a6db90a 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 95b8b36be2..9d9990d101 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 5a7a50c08d..e4881e561f 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)