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) { ...@@ -27,9 +27,14 @@ func (p *Process) wait() (ps *ProcessState, err error) {
if e != nil { if e != nil {
return nil, NewSyscallError("GetExitCodeProcess", e) 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 p.done = true
defer p.Release() 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 { func (p *Process) signal(sig Signal) error {
...@@ -82,12 +87,15 @@ func init() { ...@@ -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 { func (p *ProcessState) userTime() time.Duration {
return 0 return ftToDuration(&p.rusage.UserTime)
} }
func (p *ProcessState) systemTime() time.Duration { func (p *ProcessState) systemTime() time.Duration {
return 0 return ftToDuration(&p.rusage.KernelTime)
} }
...@@ -151,6 +151,7 @@ func NewCallback(fn interface{}) uintptr ...@@ -151,6 +151,7 @@ func NewCallback(fn interface{}) uintptr
//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) //sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW //sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
//sys GetCurrentProcess() (pseudoHandle Handle, err error) //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 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 WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW //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 ...@@ -601,10 +602,14 @@ func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32
} }
// Invented structures to support what package os expects. // 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 { type WaitStatus struct {
Status uint32
ExitCode uint32 ExitCode uint32
} }
......
...@@ -55,6 +55,7 @@ var ( ...@@ -55,6 +55,7 @@ var (
procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess")
procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW")
procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess")
procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
procGetTempPathW = modkernel32.NewProc("GetTempPathW") procGetTempPathW = modkernel32.NewProc("GetTempPathW")
...@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) { ...@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) {
return 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) { func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
var _p0 uint32 var _p0 uint32
if bInheritHandle { if bInheritHandle {
......
...@@ -55,6 +55,7 @@ var ( ...@@ -55,6 +55,7 @@ var (
procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess")
procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW")
procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess")
procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
procGetTempPathW = modkernel32.NewProc("GetTempPathW") procGetTempPathW = modkernel32.NewProc("GetTempPathW")
...@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) { ...@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) {
return 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) { func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
var _p0 uint32 var _p0 uint32
if bInheritHandle { if bInheritHandle {
......
...@@ -252,6 +252,8 @@ type Filetime struct { ...@@ -252,6 +252,8 @@ type Filetime struct {
HighDateTime uint32 HighDateTime uint32
} }
// Nanoseconds returns Filetime ft in nanoseconds
// since Epoch (00:00:00 UTC, January 1, 1970).
func (ft *Filetime) Nanoseconds() int64 { func (ft *Filetime) Nanoseconds() int64 {
// 100-nanosecond intervals since January 1, 1601 // 100-nanosecond intervals since January 1, 1601
nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) 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