Commit c3fbc9a5 authored by Alex Brainman's avatar Alex Brainman

os: implement UserTime/SystemTime on windows

Fixes #3145.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5721044
parent 36d9ee4a
......@@ -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)
}
......@@ -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
}
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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)
......
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