mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
d4b7f5b494
commit
44f1e36c29
|
@ -489,10 +489,6 @@ begin
|
|||
newtd:=thread_alloc(0);
|
||||
if (newtd=nil) then Exit(ENOMEM);
|
||||
|
||||
writeln('create_thread[',name,']'#13#10,
|
||||
' newtd:0x',HexStr(newtd)
|
||||
);
|
||||
|
||||
thread0_param(newtd);
|
||||
|
||||
//user stack
|
||||
|
@ -518,6 +514,11 @@ begin
|
|||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
writeln('create_thread[',name,']'#13#10,
|
||||
' newtd:0x',HexStr(newtd),#13#10,
|
||||
' tid:',newtd^.td_tid
|
||||
);
|
||||
|
||||
if (child_tid<>nil) then
|
||||
begin
|
||||
n:=suword32(child_tid^,newtd^.td_tid);
|
||||
|
|
|
@ -35,17 +35,19 @@ end;
|
|||
|
||||
function TGameProcessPipe.exit_code:DWORD;
|
||||
var
|
||||
info:PROCESS_BASIC_INFORMATION;
|
||||
data:array[0..SizeOf(PROCESS_BASIC_INFORMATION)-1+7] of Byte;
|
||||
p_info:PPROCESS_BASIC_INFORMATION;
|
||||
begin
|
||||
info:=Default(PROCESS_BASIC_INFORMATION);
|
||||
p_info:=Align(@data,8);
|
||||
p_info^:=Default(PROCESS_BASIC_INFORMATION);
|
||||
|
||||
NtQueryInformationProcess(g_proc,
|
||||
ProcessBasicInformation,
|
||||
@info,
|
||||
SizeOf(info),
|
||||
p_info,
|
||||
SizeOf(PROCESS_BASIC_INFORMATION),
|
||||
nil);
|
||||
|
||||
Result:=info.ExitStatus;
|
||||
Result:=p_info^.ExitStatus;
|
||||
end;
|
||||
|
||||
procedure TGameProcessPipe.suspend;
|
||||
|
|
|
@ -26,6 +26,8 @@ function cpuset_setproc(new:Ptruint):Integer;
|
|||
var
|
||||
info:SYSTEM_INFO;
|
||||
i,m,t,n:Integer;
|
||||
data:array[0..SizeOf(Ptruint)-1+7] of Byte;
|
||||
p_mask:PPtruint;
|
||||
begin
|
||||
new:=new and $FF;
|
||||
|
||||
|
@ -45,41 +47,50 @@ begin
|
|||
new:=m;
|
||||
end;
|
||||
|
||||
p_mask:=Align(@data,8);
|
||||
p_mask^:=new;
|
||||
|
||||
Result:=NtSetInformationProcess(NtCurrentProcess,
|
||||
ProcessAffinityMask,
|
||||
@new,
|
||||
p_mask,
|
||||
SizeOf(QWORD));
|
||||
end;
|
||||
|
||||
function cpuset_getproc(var old:Ptruint):Integer;
|
||||
var
|
||||
info:PROCESS_BASIC_INFORMATION;
|
||||
data:array[0..SizeOf(PROCESS_BASIC_INFORMATION)-1+7] of Byte;
|
||||
p_info:PPROCESS_BASIC_INFORMATION;
|
||||
begin
|
||||
p_info:=Align(@data,8);
|
||||
|
||||
Result:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessBasicInformation,
|
||||
@info,
|
||||
SizeOf(info),
|
||||
p_info,
|
||||
SizeOf(PROCESS_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (Result=0) then
|
||||
begin
|
||||
old:=info.AffinityMask;
|
||||
old:=p_info^.AffinityMask;
|
||||
end;
|
||||
end;
|
||||
|
||||
function get_proc_prio():Integer;
|
||||
var
|
||||
info:PROCESS_PRIORITY_CLASS;
|
||||
data:array[0..SizeOf(PROCESS_PRIORITY_CLASS)-1+7] of Byte;
|
||||
p_info:PPROCESS_PRIORITY_CLASS;
|
||||
begin
|
||||
p_info:=Align(@data,8);
|
||||
|
||||
Result:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessPriorityClass,
|
||||
@info,
|
||||
SizeOf(info),
|
||||
p_info,
|
||||
SizeOf(PROCESS_PRIORITY_CLASS),
|
||||
nil);
|
||||
if (Result=0) then
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
case info.PriorityClass of
|
||||
case p_info^.PriorityClass of
|
||||
PROCESS_PRIORITY_CLASS_IDLE :Result:=-20;
|
||||
PROCESS_PRIORITY_CLASS_BELOW_NORMAL:Result:=-10;
|
||||
PROCESS_PRIORITY_CLASS_NORMAL :Result:=0;
|
||||
|
@ -96,24 +107,27 @@ end;
|
|||
|
||||
function set_proc_prio(n:Integer):Integer;
|
||||
var
|
||||
info:PROCESS_PRIORITY_CLASS;
|
||||
data:array[0..SizeOf(PROCESS_PRIORITY_CLASS)-1+7] of Byte;
|
||||
p_info:PPROCESS_PRIORITY_CLASS;
|
||||
begin
|
||||
info.Foreground :=False;
|
||||
info.PriorityClass:=PROCESS_PRIORITY_CLASS_NORMAL;
|
||||
p_info:=Align(@data,8);
|
||||
|
||||
p_info^.Foreground :=False;
|
||||
p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_NORMAL;
|
||||
|
||||
case n of
|
||||
-20..-14:info.PriorityClass:=PROCESS_PRIORITY_CLASS_IDLE;
|
||||
-13.. -7:info.PriorityClass:=PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
|
||||
-6.. 6:info.PriorityClass:=PROCESS_PRIORITY_CLASS_NORMAL;
|
||||
7.. 13:info.PriorityClass:=PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
|
||||
14.. 20:info.PriorityClass:=PROCESS_PRIORITY_CLASS_HIGH;
|
||||
-20..-14:p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_IDLE;
|
||||
-13.. -7:p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
|
||||
-6.. 6:p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_NORMAL;
|
||||
7.. 13:p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
|
||||
14.. 20:p_info^.PriorityClass:=PROCESS_PRIORITY_CLASS_HIGH;
|
||||
else;
|
||||
end;
|
||||
|
||||
Result:=NtSetInformationProcess(NtCurrentProcess,
|
||||
ProcessPriorityClass,
|
||||
@info,
|
||||
SizeOf(info));
|
||||
p_info,
|
||||
SizeOf(PROCESS_PRIORITY_CLASS));
|
||||
end;
|
||||
|
||||
Procedure md_halt(errnum:DWORD); noreturn;
|
||||
|
|
|
@ -16,7 +16,6 @@ uses
|
|||
ntapi,
|
||||
errno,
|
||||
time,
|
||||
md_proc,
|
||||
md_time,
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
|
@ -34,8 +33,11 @@ var
|
|||
|
||||
user,syst:Int64;
|
||||
|
||||
IO:IO_COUNTERS;
|
||||
VM:VM_COUNTERS;
|
||||
data:array[0..SizeOf(VM_COUNTERS)-1+7] of Byte;
|
||||
|
||||
P_IO:PIO_COUNTERS;
|
||||
P_VM:PVM_COUNTERS;
|
||||
|
||||
R:DWORD;
|
||||
|
||||
vms:p_vmspace;
|
||||
|
@ -60,22 +62,24 @@ begin
|
|||
rup^.ru_idrss :=pgtok(vms^.vm_dsize);
|
||||
rup^.ru_isrss :=pgtok(vms^.vm_ssize);
|
||||
|
||||
IO:=Default(IO_COUNTERS);
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,ProcessIoCounters,@IO,SizeOf(IO),nil);
|
||||
P_IO:=Align(@data,8);
|
||||
P_IO^:=Default(IO_COUNTERS);
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,ProcessIoCounters,P_IO,SizeOf(IO_COUNTERS),nil);
|
||||
|
||||
if (R=0) then
|
||||
begin
|
||||
rup^.ru_inblock:=IO.ReadOperationCount;
|
||||
rup^.ru_oublock:=IO.WriteOperationCount;
|
||||
rup^.ru_inblock:=P_IO^.ReadOperationCount;
|
||||
rup^.ru_oublock:=P_IO^.WriteOperationCount;
|
||||
end;
|
||||
|
||||
VM:=Default(VM_COUNTERS);
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,ProcessVmCounters,@VM,SizeOf(VM),nil);
|
||||
P_VM:=Align(@data,8);
|
||||
P_VM^:=Default(VM_COUNTERS);
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,ProcessVmCounters,P_VM,SizeOf(VM_COUNTERS),nil);
|
||||
|
||||
if (R=0) then
|
||||
begin
|
||||
rup^.ru_maxrss:=VM.PeakWorkingSetSize div 1024;
|
||||
rup^.ru_majflt:=VM.PageFaultCount;
|
||||
rup^.ru_maxrss:=P_VM^.PeakWorkingSetSize div 1024;
|
||||
rup^.ru_majflt:=P_VM^.PageFaultCount;
|
||||
end;
|
||||
|
||||
calcru_proc(@user,@syst);
|
||||
|
|
|
@ -188,21 +188,23 @@ function AssignProcessToJobObject(hJob,hProcess:THandle):BOOL; stdcall; external
|
|||
|
||||
function NtQueryTeb(td_handle:THandle;var teb:p_teb):Integer;
|
||||
var
|
||||
TBI:THREAD_BASIC_INFORMATION;
|
||||
data:array[0..SizeOf(THREAD_BASIC_INFORMATION)-1+7] of Byte;
|
||||
P_TBI:PTHREAD_BASIC_INFORMATION;
|
||||
begin
|
||||
Result:=0;
|
||||
teb:=nil;
|
||||
TBI:=Default(THREAD_BASIC_INFORMATION);
|
||||
P_TBI:=Align(@data,8);
|
||||
P_TBI^:=Default(THREAD_BASIC_INFORMATION);
|
||||
|
||||
Result:=NtQueryInformationThread(
|
||||
td_handle,
|
||||
ThreadBasicInformation,
|
||||
@TBI,
|
||||
P_TBI,
|
||||
SizeOf(THREAD_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
teb:=TBI.TebBaseAddress;
|
||||
teb:=P_TBI^.TebBaseAddress;
|
||||
end;
|
||||
|
||||
procedure NtGetVirtualInfo(hProcess:THandle;var base:Pointer;var size:QWORD);
|
||||
|
@ -367,7 +369,12 @@ begin
|
|||
size:=guest_pmap_mem[i].__end-guest_pmap_mem[i].start;
|
||||
|
||||
r:=nt_reserve_ex(hProcess,base,size);
|
||||
if (r<>0) then Exit(r);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln(stderr,'nt_reserve_ex(0x',HexStr(base),',0x',HexStr(size,16),'):0x',HexStr(r,8));
|
||||
Exit(r);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -376,7 +383,11 @@ begin
|
|||
size:=VM_MAX_GPU_ADDRESS-VM_MIN_GPU_ADDRESS;
|
||||
|
||||
r:=nt_reserve_ex(hProcess,base,size);
|
||||
if (r<>0) then Exit(r);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln(stderr,'nt_reserve_ex(0x',HexStr(base),',0x',HexStr(size,16),'):0x',HexStr(r,8));
|
||||
Exit(r);
|
||||
end;
|
||||
|
||||
//fill corners
|
||||
|
||||
|
@ -522,6 +533,7 @@ end;
|
|||
|
||||
function md_fork_process(var info:t_fork_proc):Integer;
|
||||
type
|
||||
PBUF_PROC_INFO=^TBUF_PROC_INFO;
|
||||
TBUF_PROC_INFO=packed record
|
||||
UNAME:UNICODE_STRING;
|
||||
DATA :array[0..MAX_PATH*2] of WideChar;
|
||||
|
@ -529,18 +541,21 @@ type
|
|||
var
|
||||
si:TSTARTUPINFO;
|
||||
pi:PROCESS_INFORMATION;
|
||||
BUF:TBUF_PROC_INFO;
|
||||
data:array[0..SizeOf(TBUF_PROC_INFO)-1+7] of Byte;
|
||||
P_BUF:PBUF_PROC_INFO;
|
||||
LEN:ULONG;
|
||||
b:BOOL;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
BUF:=Default(TBUF_PROC_INFO);
|
||||
LEN:=SizeOf(BUF);
|
||||
P_BUF:=Align(@data,8);
|
||||
|
||||
P_BUF^:=Default(TBUF_PROC_INFO);
|
||||
LEN:=SizeOf(TBUF_PROC_INFO);
|
||||
|
||||
Result:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessImageFileNameWin32,
|
||||
@BUF,
|
||||
P_BUF,
|
||||
LEN,
|
||||
@LEN);
|
||||
if (Result<>0) then Exit;
|
||||
|
@ -550,23 +565,39 @@ begin
|
|||
|
||||
si.cb:=SizeOf(si);
|
||||
|
||||
b:=CreateProcessW(PWideChar(@BUF.DATA),nil,nil,nil,False,CREATE_SUSPENDED,nil,nil,@si,@pi);
|
||||
b:=CreateProcessW(PWideChar(@P_BUF^.DATA),nil,nil,nil,False,CREATE_SUSPENDED,nil,nil,@si,@pi);
|
||||
if not b then Exit(-1);
|
||||
|
||||
b:=AssignProcessToJobObject(NtFetchJob, pi.hProcess);
|
||||
if not b then Exit(-1);
|
||||
|
||||
Result:=NtMoveStack(pi.hProcess,pi.hThread);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(stderr,'NtMoveStack:0x',HexStr(Result,8));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=NtReserve(pi.hProcess);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(stderr,'NtReserve:0x',HexStr(Result,8));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=NtCreateShared(pi.hProcess,info);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(stderr,'NtCreateShared:0x',HexStr(Result,8));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=NtResumeProcess(pi.hProcess);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(stderr,'NtResumeProcess:0x',HexStr(Result,8));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
NtClose(pi.hThread);
|
||||
|
||||
|
|
|
@ -145,20 +145,22 @@ end;
|
|||
|
||||
function BaseQueryInfo(td:p_kthread):Integer;
|
||||
var
|
||||
TBI:THREAD_BASIC_INFORMATION;
|
||||
data:array[0..SizeOf(THREAD_BASIC_INFORMATION)-1+7] of Byte;
|
||||
P_TBI:PTHREAD_BASIC_INFORMATION;
|
||||
begin
|
||||
TBI:=Default(THREAD_BASIC_INFORMATION);
|
||||
P_TBI:=Align(@data,8);
|
||||
P_TBI^:=Default(THREAD_BASIC_INFORMATION);
|
||||
|
||||
Result:=NtQueryInformationThread(
|
||||
td^.td_handle,
|
||||
ThreadBasicInformation,
|
||||
@TBI,
|
||||
P_TBI,
|
||||
SizeOf(THREAD_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
td^.td_teb :=TBI.TebBaseAddress;
|
||||
td^.td_cpuset:=TBI.AffinityMask;
|
||||
td^.td_teb :=P_TBI^.TebBaseAddress;
|
||||
td^.td_cpuset:=P_TBI^.AffinityMask;
|
||||
|
||||
td^.td_teb^.thread:=td; //self
|
||||
end;
|
||||
|
@ -319,6 +321,8 @@ function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer;
|
|||
var
|
||||
info:SYSTEM_INFO;
|
||||
i,m,t,n:Integer;
|
||||
data:array[0..SizeOf(Ptruint)-1+7] of Byte;
|
||||
p_mask:PPtruint;
|
||||
begin
|
||||
if (td=nil) then Exit;
|
||||
if (td^.td_handle=0) or (td^.td_handle=THandle(-1)) then Exit(-1);
|
||||
|
@ -342,10 +346,17 @@ begin
|
|||
end;
|
||||
|
||||
td^.td_cpuset:=new;
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadAffinityMask,@new,SizeOf(Ptruint));
|
||||
|
||||
p_mask:=Align(@data,8);
|
||||
p_mask^:=new;
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadAffinityMask,p_mask,SizeOf(Ptruint));
|
||||
end;
|
||||
|
||||
function cpu_set_priority(td:p_kthread;prio:Integer):Integer;
|
||||
var
|
||||
data:array[0..SizeOf(Integer)-1+7] of Byte;
|
||||
p_prio:PInteger;
|
||||
begin
|
||||
if (td=nil) then Exit;
|
||||
if (td^.td_handle=0) or (td^.td_handle=THandle(-1)) then Exit(-1);
|
||||
|
@ -363,28 +374,39 @@ begin
|
|||
prio:=-16;
|
||||
end;
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadBasePriority,@prio,SizeOf(Integer));
|
||||
p_prio:=Align(@data,8);
|
||||
p_prio^:=prio;
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadBasePriority,p_prio,SizeOf(Integer));
|
||||
end;
|
||||
|
||||
function cpu_thread_set_name(td:p_kthread;const name:shortstring):Integer;
|
||||
Const
|
||||
MAX_LEN=256;
|
||||
var
|
||||
W:array[0..255] of WideChar;
|
||||
UNAME:UNICODE_STRING;
|
||||
W:array[0..MAX_LEN-1+7] of WideChar;
|
||||
P_W:PWideChar;
|
||||
data:array[0..SizeOf(UNICODE_STRING)-1+7] of Byte;
|
||||
P_UNAME:PUNICODE_STRING;
|
||||
L:DWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
if (td=nil) then Exit;
|
||||
if (td^.td_handle=0) or (td^.td_handle=THandle(-1)) then Exit;
|
||||
|
||||
L:=Utf8ToUnicode(@W,length(W),@name[1],length(name));
|
||||
P_W:=Align(@W,8);
|
||||
|
||||
W:=UTF8Decode(name);
|
||||
FillWord(P_W^,MAX_LEN,0);
|
||||
L:=Utf8ToUnicode(P_W,MAX_LEN,@name[1],length(name));
|
||||
|
||||
UNAME.Length :=L*SizeOf(WideChar);
|
||||
UNAME.MaximumLength:=UNAME.Length;
|
||||
UNAME.Buffer :=PWideChar(W);
|
||||
P_UNAME:=Align(@data,8);
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadNameInformation,@UNAME,SizeOf(UNAME));
|
||||
P_UNAME^.Length :=L*SizeOf(WideChar);
|
||||
P_UNAME^.MaximumLength:=P_UNAME^.Length;
|
||||
P_UNAME^._Align :=0;
|
||||
P_UNAME^.Buffer :=P_W;
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadNameInformation,P_UNAME,SizeOf(UNICODE_STRING));
|
||||
end;
|
||||
|
||||
function md_suspend(td:p_kthread):Integer;
|
||||
|
|
|
@ -227,13 +227,15 @@ end;
|
|||
procedure calcru_proc(user,syst:PInt64);
|
||||
var
|
||||
k:KERNEL_USER_TIMES;
|
||||
R:DWORD;
|
||||
begin
|
||||
k:=Default(KERNEL_USER_TIMES);
|
||||
NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
Assert(R=0,'calcru_proc');
|
||||
user^:=k.UserTime.QuadPart;
|
||||
syst^:=k.KernelTime.QuadPart;
|
||||
end;
|
||||
|
@ -241,14 +243,15 @@ end;
|
|||
procedure get_process_cputime(time:PInt64);
|
||||
var
|
||||
k:KERNEL_USER_TIMES;
|
||||
R:DWORD;
|
||||
begin
|
||||
k:=Default(KERNEL_USER_TIMES);
|
||||
NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
Assert(R=0,'get_process_cputime');
|
||||
unittime(@k.ExitTime.QuadPart);
|
||||
time^:=k.ExitTime.QuadPart-k.CreateTime.QuadPart;
|
||||
end;
|
||||
|
@ -256,13 +259,15 @@ end;
|
|||
procedure calcru_thread(user,syst:PInt64);
|
||||
var
|
||||
k:KERNEL_USER_TIMES;
|
||||
R:DWORD;
|
||||
begin
|
||||
k:=Default(KERNEL_USER_TIMES);
|
||||
NtQueryInformationThread(NtCurrentThread,
|
||||
ThreadTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
R:=NtQueryInformationThread(NtCurrentThread,
|
||||
ThreadTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
Assert(R=0,'calcru_thread');
|
||||
unittime(@k.ExitTime.QuadPart);
|
||||
user^:=k.ExitTime.QuadPart-k.UserTime.QuadPart;
|
||||
syst^:=k.ExitTime.QuadPart-k.KernelTime.QuadPart;
|
||||
|
@ -271,13 +276,15 @@ end;
|
|||
procedure get_thread_cputime(time:PInt64);
|
||||
var
|
||||
k:KERNEL_USER_TIMES;
|
||||
R:DWORD;
|
||||
begin
|
||||
k:=Default(KERNEL_USER_TIMES);
|
||||
NtQueryInformationThread(NtCurrentThread,
|
||||
ThreadTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
R:=NtQueryInformationThread(NtCurrentThread,
|
||||
ThreadTimes,
|
||||
@k,
|
||||
SizeOf(KERNEL_USER_TIMES),
|
||||
nil);
|
||||
Assert(R=0,'get_thread_cputime');
|
||||
unittime(@k.ExitTime.QuadPart);
|
||||
time^:=k.ExitTime.QuadPart-k.CreateTime.QuadPart;
|
||||
end;
|
||||
|
|
Loading…
Reference in New Issue