]> Cypherpunks repositories - gostls13.git/commitdiff
os: implement UserTime/SystemTime on windows
authorAlex Brainman <alex.brainman@gmail.com>
Fri, 2 Mar 2012 03:47:40 +0000 (14:47 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Fri, 2 Mar 2012 03:47:40 +0000 (14:47 +1100)
Fixes #3145.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5721044

src/pkg/os/exec_windows.go
src/pkg/syscall/syscall_windows.go
src/pkg/syscall/zsyscall_windows_386.go
src/pkg/syscall/zsyscall_windows_amd64.go
src/pkg/syscall/ztypes_windows.go

index 93360b15f13618c3f6980fd4225b781823274cea..fa58020c03120be245d999b72dda9a5e7fc455ba 100644 (file)
@@ -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)
 }
index fde3bef50e04f0e62c5c35e249fca3a998c1944f..7c82932d0b3fd0fc54f025c46ba33f75ea0b206e 100644 (file)
@@ -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
 }
 
index 0209463e51d0c0479eb84510e1c4f2ab5a024eea..8b1a6db90af6dddf3076dd43c8a5cf56ac83b34c 100644 (file)
@@ -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 {
index 95b8b36be2fd8e63b7750df5e93f7456b107dee3..9d9990d101e93c9385c56b78367c2b2191f37af6 100644 (file)
@@ -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 {
index 5a7a50c08dbc7ea1ea97d3c5427632571661df94..e4881e561ff81741ebebd69573759486861c1f60 100644 (file)
@@ -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)