The "Include CPU (and other) usage of children in collapsed processes" option now aggregates memory and I/O statistics; Change size formatting so that formatted values between 1000 and 1024 are disallowed; Fix bug in PhInitializeTreeNewColumnMenuEx regarding the "Reset Sort" menu item

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@6320 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2016-01-28 07:20:43 +00:00
parent 98c4d84748
commit 1997bac42b
5 changed files with 139 additions and 47 deletions
+1
View File
@@ -3,6 +3,7 @@ Process Hacker
2.37
* HIGHLIGHTS:
* Updated for Windows 10
* The "Include CPU (and other) usage of children in collapsed processes" option now aggregates memory and I/O statistics
* Added regex search to "Find Handles or DLLs"
* Added process exit codes to log
* Fixed crash that occurred under some conditions when processes terminated
+7 -2
View File
@@ -1321,8 +1321,8 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,43,167,10
CONTROL "Resolve addresses for network connections",IDC_ENABLENETWORKRESOLVE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,55,155,10
CONTROL "Include CPU usage of children in collapsed processes",IDC_PROPAGATECPUUSAGE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,184,10
CONTROL "Include CPU (and other) usage of children in collapsed processes",IDC_PROPAGATECPUUSAGE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,223,10
CONTROL "Show tooltips instantly",IDC_ENABLEINSTANTTOOLTIPS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,79,88,10
CONTROL "Enable cycle-based CPU usage",IDC_ENABLECYCLECPUUSAGE,
@@ -2484,6 +2484,11 @@ BEGIN
0
END
IDD_OPTADVANCED AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -1578,7 +1578,7 @@ VOID PhInitializeTreeNewColumnMenuEx(
TreeNew_GetSort(Data->TreeNewHandle, &sortColumn, &sortOrder);
if (sortColumn != Data->DefaultSortColumn || sortOrder != Data->DefaultSortOrder)
if (sortOrder != Data->DefaultSortOrder || (Data->DefaultSortOrder != NoSortOrder && sortColumn != Data->DefaultSortColumn))
resetSortMenuItem = PhCreateEMenuItem(0, PH_TN_COLUMN_MENU_RESET_SORT_ID, L"Reset Sort", NULL, NULL);
}
+129 -43
View File
@@ -36,6 +36,20 @@
#include <emenu.h>
#include <verify.h>
typedef enum _PHP_AGGREGATE_TYPE
{
AggregateTypeFloat,
AggregateTypeInt32,
AggregateTypeInt64,
AggregateTypeIntPtr
} PHP_AGGREGATE_TYPE;
typedef enum _PHP_AGGREGATE_LOCATION
{
AggregateLocationProcessNode,
AggregateLocationProcessItem
} PHP_AGGREGATE_LOCATION;
VOID PhpRemoveProcessNode(
_In_ PPH_PROCESS_NODE ProcessNode
);
@@ -692,21 +706,86 @@ static BOOLEAN PhpFormatInt32GroupDigits(
}
}
static FLOAT PhpCalculateInclusiveCpuUsage(
_In_ PPH_PROCESS_NODE ProcessNode
FORCEINLINE PVOID PhpFieldForAggregate(
_In_ PPH_PROCESS_NODE ProcessNode,
_In_ PHP_AGGREGATE_LOCATION Location,
_In_ SIZE_T FieldOffset
)
{
PVOID object;
switch (Location)
{
case AggregateLocationProcessNode:
object = ProcessNode;
break;
case AggregateLocationProcessItem:
object = ProcessNode->ProcessItem;
break;
default:
PhRaiseStatus(STATUS_INVALID_PARAMETER);
}
return PTR_ADD_OFFSET(object, FieldOffset);
}
FORCEINLINE VOID PhpAccumulateField(
_Inout_ PVOID Accumulator,
_In_ PVOID Value,
_In_ PHP_AGGREGATE_TYPE Type
)
{
switch (Type)
{
case AggregateTypeFloat:
*(PFLOAT)Accumulator += *(PFLOAT)Value;
break;
case AggregateTypeInt32:
*(PULONG)Accumulator += *(PULONG)Value;
break;
case AggregateTypeInt64:
*(PULONG64)Accumulator += *(PULONG64)Value;
break;
case AggregateTypeIntPtr:
*(PULONG_PTR)Accumulator += *(PULONG_PTR)Value;
break;
}
}
static VOID PhpAggregateField(
_In_ PPH_PROCESS_NODE ProcessNode,
_In_ PHP_AGGREGATE_TYPE Type,
_In_ PHP_AGGREGATE_LOCATION Location,
_In_ SIZE_T FieldOffset,
_Inout_ PVOID AggregatedValue
)
{
FLOAT cpuUsage;
ULONG i;
cpuUsage = ProcessNode->ProcessItem->CpuUsage;
PhpAccumulateField(AggregatedValue, PhpFieldForAggregate(ProcessNode, Location, FieldOffset), Type);
for (i = 0; i < ProcessNode->Children->Count; i++)
{
cpuUsage += PhpCalculateInclusiveCpuUsage(ProcessNode->Children->Items[i]);
PhpAggregateField(ProcessNode->Children->Items[i], Type, Location, FieldOffset, AggregatedValue);
}
}
return cpuUsage;
static VOID PhpAggregateFieldIfNeeded(
_In_ PPH_PROCESS_NODE ProcessNode,
_In_ PHP_AGGREGATE_TYPE Type,
_In_ PHP_AGGREGATE_LOCATION Location,
_In_ SIZE_T FieldOffset,
_Inout_ PVOID AggregatedValue
)
{
if (!PhCsPropagateCpuUsage || ProcessNode->Node.Expanded || ProcessTreeListSortOrder != NoSortOrder)
{
PhpAccumulateField(AggregatedValue, PhpFieldForAggregate(ProcessNode, Location, FieldOffset), Type);
}
else
{
PhpAggregateField(ProcessNode, Type, Location, FieldOffset, AggregatedValue);
}
}
static VOID PhpUpdateProcessNodeWsCounters(
@@ -1943,16 +2022,10 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
break;
case PHPRTLC_CPU:
{
FLOAT cpuUsage;
FLOAT cpuUsage = 0;
if (!PhCsPropagateCpuUsage || node->Node.Expanded || ProcessTreeListSortOrder != NoSortOrder)
{
cpuUsage = processItem->CpuUsage * 100;
}
else
{
cpuUsage = PhpCalculateInclusiveCpuUsage(node) * 100;
}
PhpAggregateFieldIfNeeded(node, AggregateTypeFloat, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CpuUsage), &cpuUsage);
cpuUsage *= 100;
if (cpuUsage >= 0.01)
{
@@ -1985,18 +2058,16 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
break;
case PHPRTLC_IOTOTALRATE:
{
ULONG64 number;
ULONG64 number = 0;
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value) // delta is wrong on first run of process provider
{
number = processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoReadDelta.Delta), &number);
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoWriteDelta.Delta), &number);
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoOtherDelta.Delta), &number);
number *= 1000;
number /= PhCsUpdateInterval;
}
else
{
number = 0;
}
if (number != 0)
{
@@ -2010,8 +2081,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
}
break;
case PHPRTLC_PRIVATEBYTES:
PhMoveReference(&node->PrivateBytesText, PhFormatSize(processItem->VmCounters.PagefileUsage, -1));
getCellText->Text = node->PrivateBytesText->sr;
{
SIZE_T value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeIntPtr, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, VmCounters.PagefileUsage), &value);
PhMoveReference(&node->PrivateBytesText, PhFormatSize(value, -1));
getCellText->Text = node->PrivateBytesText->sr;
}
break;
case PHPRTLC_USERNAME:
getCellText->Text = PhGetStringRef(processItem->UserName);
@@ -2039,8 +2114,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
getCellText->Text = node->PeakPrivateBytesText->sr;
break;
case PHPRTLC_WORKINGSET:
PhMoveReference(&node->WorkingSetText, PhFormatSize(processItem->VmCounters.WorkingSetSize, -1));
getCellText->Text = node->WorkingSetText->sr;
{
SIZE_T value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeIntPtr, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, VmCounters.WorkingSetSize), &value);
PhMoveReference(&node->WorkingSetText, PhFormatSize(value, -1));
getCellText->Text = node->WorkingSetText->sr;
}
break;
case PHPRTLC_PEAKWORKINGSET:
PhMoveReference(&node->PeakWorkingSetText, PhFormatSize(processItem->VmCounters.PeakWorkingSetSize, -1));
@@ -2091,10 +2170,18 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
PhInitializeStringRefLongHint(&getCellText->Text, node->BasePriorityText);
break;
case PHPRTLC_THREADS:
PhpFormatInt32GroupDigits(processItem->NumberOfThreads, node->ThreadsText, sizeof(node->ThreadsText), &getCellText->Text);
{
ULONG value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt32, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, NumberOfThreads), &value);
PhpFormatInt32GroupDigits(value, node->ThreadsText, sizeof(node->ThreadsText), &getCellText->Text);
}
break;
case PHPRTLC_HANDLES:
PhpFormatInt32GroupDigits(processItem->NumberOfHandles, node->HandlesText, sizeof(node->HandlesText), &getCellText->Text);
{
ULONG value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt32, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, NumberOfHandles), &value);
PhpFormatInt32GroupDigits(value, node->HandlesText, sizeof(node->HandlesText), &getCellText->Text);
}
break;
case PHPRTLC_GDIHANDLES:
PhpUpdateProcessNodeGdiUserHandles(node);
@@ -2106,18 +2193,15 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
break;
case PHPRTLC_IORORATE:
{
ULONG64 number;
ULONG64 number = 0;
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value)
{
number = processItem->IoReadDelta.Delta + processItem->IoOtherDelta.Delta;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoReadDelta.Delta), &number);
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoOtherDelta.Delta), &number);
number *= 1000;
number /= PhCsUpdateInterval;
}
else
{
number = 0;
}
if (number != 0)
{
@@ -2132,18 +2216,14 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
break;
case PHPRTLC_IOWRATE:
{
ULONG64 number;
ULONG64 number = 0;
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value)
{
number = processItem->IoWriteDelta.Delta;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoWriteDelta.Delta), &number);
number *= 1000;
number /= PhCsUpdateInterval;
}
else
{
number = 0;
}
if (number != 0)
{
@@ -2294,9 +2374,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
case PHPRTLC_CYCLES:
if (WindowsVersion >= WINDOWS_7)
{
if (processItem->CycleTimeDelta.Value != 0)
ULONG64 value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CycleTimeDelta.Value), &value);
if (value != 0)
{
PhMoveReference(&node->CyclesText, PhFormatUInt64(processItem->CycleTimeDelta.Value, TRUE));
PhMoveReference(&node->CyclesText, PhFormatUInt64(value, TRUE));
getCellText->Text = node->CyclesText->sr;
}
}
@@ -2308,9 +2391,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
case PHPRTLC_CYCLESDELTA:
if (WindowsVersion >= WINDOWS_7)
{
if (processItem->CycleTimeDelta.Delta != 0)
ULONG64 value = 0;
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CycleTimeDelta.Delta), &value);
if (value != 0)
{
PhMoveReference(&node->CyclesDeltaText, PhFormatUInt64(processItem->CycleTimeDelta.Delta, TRUE));
PhMoveReference(&node->CyclesDeltaText, PhFormatUInt64(value, TRUE));
getCellText->Text = node->CyclesDeltaText->sr;
}
}
+1 -1
View File
@@ -494,7 +494,7 @@ CommonInt64Format:
maxSizeUnit = PhMaxSizeUnit;
while (
s >= 1024 &&
s >= 1000 &&
i < sizeof(PhpSizeUnitNamesCounted) / sizeof(PH_STRINGREF) &&
i < maxSizeUnit
)