ULONG PerfUnregisterCallback( IN PERF_CONSUMER_CALLBACK Callback ) { PBSP_CALLBACK CallbackObject; PLIST_ENTRY ListEntry; ListEntry = PerfCallbackListHead.Flink; while (ListEntry != &PerfCallbackListHead) { CallbackObject = CONTAINING_RECORD(ListEntry, BSP_CALLBACK, ListEntry); if (CallbackObject->Callback == (PVOID)Callback) { RemoveEntryList(&CallbackObject->ListEntry); BspFree(CallbackObject); break; } ListEntry = ListEntry->Flink; } return ERROR_SUCCESS; }
BOOLEAN RspRemoveCallback( IN RSP_DECODE_CALLBACK Callback ) { PLIST_ENTRY Entry; PBSP_CALLBACK Object; ASSERT(Callback != NULL); if (Callback == NULL) { return FALSE; } Entry = RspCallbackList.Flink; while (Entry != &RspCallbackList) { Object = CONTAINING_RECORD(Entry, BSP_CALLBACK, Entry); if (Object->Callback == (PVOID)Callback) { RemoveEntryList(&Object->Entry); BspFree(Object); return TRUE; } Entry = Entry->Flink; } return FALSE; }
ULONG PerfDeleteTask( IN ULONG ProcessId ) { PPERF_INFORMATION Information; Information = PerfLookupTask(ProcessId); if (Information != NULL) { RemoveEntryList(&Information->ListEntry); BspFree(Information); PerfNumberOfTasks -= 1; } return ERROR_SUCCESS; }
VOID PerfDeleteAll( VOID ) { PLIST_ENTRY ListEntry; PPERF_INFORMATION Information; while (IsListEmpty(&PerfListHead) != TRUE) { ListEntry = RemoveHeadList(&PerfListHead); Information = CONTAINING_RECORD(ListEntry, PERF_INFORMATION, ListEntry); BspFree(Information); } PerfNumberOfTasks = 0; PerfFirstRun = TRUE; }
VOID PerfCleanUp( IN PDIALOG_OBJECT Object ) { PPERF_TASK_CONTEXT TaskContext; PPERF_DIALOG_CONTEXT ObjectContext; PLIST_ENTRY ListEntry; // // N.B. Perfmon callback must be unregistered before any // clean up work // PerfUnregisterCallback(PerfGraphConsumerCallback); ObjectContext = (PPERF_DIALOG_CONTEXT)Object->Context; while (IsListEmpty(&ObjectContext->TaskContextList) != TRUE) { ListEntry = RemoveHeadList(&ObjectContext->TaskContextList); TaskContext = CONTAINING_RECORD(ListEntry, PERF_TASK_CONTEXT, ListEntry); BspFree(TaskContext); } }
VOID PerfRemoveTerminatedTasks( IN HWND hWnd ) { HWND hWndList; PPERF_TASK_CONTEXT Task; int Count; int i; BOOLEAN Changed = FALSE; PPERF_DIALOG_CONTEXT Context; PDIALOG_OBJECT Object; Object = (PDIALOG_OBJECT)SdkGetObject(hWnd); Context = SdkGetContext(Object, PERF_DIALOG_CONTEXT); hWndList = GetDlgItem(hWnd, IDC_LIST_PERF_PROCESS); Count = ListView_GetItemCount(hWndList); for(i = Count - 1; i != -1; i--) { ListViewGetParam(hWndList, i, (LPARAM *)&Task); if (Task && Task->Information.Terminated) { ListView_DeleteItem(hWndList, i); RemoveEntryList(&Task->ListEntry); BspFree(Task); Changed = TRUE; } } // // N.B. If there's no any removed task, we don't switch // selected item. // if (ListView_GetItemCount(hWndList) != 0 && Changed) { ListViewSelectSingle(hWndList, 0); } }
BOOLEAN ArgumentOnOk( IN HWND hWnd ) { HWND hWndCtrl; BTR_CALLTYPE CallType; BTR_RETURN_TYPE ReturnType; BTR_ARGUMENT Argument; PDIALOG_OBJECT Object; PDIALOG_RESULT Result; PPSP_PROBE Probe; LONG Current; LONG Count, i; BOOLEAN Changed; WCHAR Buffer[64]; PPSP_ARGUMENT Cache; Object = (PDIALOG_OBJECT)SdkGetObject(hWnd); Result = (PDIALOG_RESULT)Object->Context; Probe = (PPSP_PROBE)Result->Context; hWndCtrl = GetDlgItem(hWnd, IDC_COMBO_CONVENTION); CallType = (BTR_ARGUMENT)SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0); hWndCtrl = GetDlgItem(hWnd, IDC_COMBO_RETURN); ReturnType = (BTR_ARGUMENT)SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0); hWndCtrl = GetDlgItem(GetParent(hWnd), IDC_LIST_MANUAL); Current = ListViewGetFirstSelected(hWndCtrl); ListView_SetItemText(hWndCtrl, Current, 2, L"Y"); Changed = FALSE; Cache = (PPSP_ARGUMENT)BspMalloc(sizeof(PSP_ARGUMENT)); if (Probe->Current == ProbeCreating) { Probe->CallType = CallType; Probe->ReturnType = ReturnType; } else { Cache->CallType = CallType; if (Probe->CallType != CallType) { Changed = TRUE; } Cache->ReturnType = ReturnType; if (Probe->ReturnType != ReturnType) { Changed = TRUE; } } hWndCtrl = GetDlgItem(hWnd, IDC_LIST_ARGUMENT); Count = ListView_GetItemCount(hWndCtrl); if (Probe->Current != ProbeCreating) { Cache->ArgumentCount = Count; if (Count != Probe->ArgumentCount) { Changed = TRUE; } } else { Probe->ArgumentCount = Count; } if (Probe->Current == ProbeCreating) { for(i = 0; i < Count; i++) { ListViewGetParam(hWndCtrl, i, (LPARAM *)&Argument); ListView_GetItemText(hWndCtrl, i, 1, Buffer, 30); Probe->Parameters[i] = (BTR_ARGUMENT)Argument; StringCchCopy(&Probe->ParameterName[i][0], MAX_ARGUMENT_NAME_LENGTH, Buffer); } } else { for(i = 0; i < Count; i++) { ListViewGetParam(hWndCtrl, i, (LPARAM *)&Argument); ListView_GetItemText(hWndCtrl, i, 1, Buffer, 30); Cache->Arguments[i] = (BTR_ARGUMENT)Argument; if (Probe->Parameters[i] != (BTR_ARGUMENT)Argument) { Changed = TRUE; } // // N.B. Event it has only naming change, we still consider it's a different probe object, // because we need decode record with new argument names. // StringCchCopy(&Cache->Names[i][0], MAX_ARGUMENT_NAME_LENGTH, Buffer); if (wcscmp(&Cache->Names[i][0], &Probe->ParameterName[i][0]) != 0) { Changed = TRUE; } } } if (Probe->Current != ProbeCreating && Changed) { Probe->Current = ProbeEditing; Probe->Cache = Cache; } else { BspFree(Cache); } Result->Context = Probe; Result->Status = IDOK; ArgumentFreeResources(hWnd); EndDialog(hWnd, IDOK); return TRUE; }
ULONG PerfUpdateInformation( VOID ) { ULONG i; ULONG64 TotalTime; PLIST_ENTRY ListEntry; LIST_ENTRY ListHead; PBSP_PROCESS Process; PPERF_INFORMATION Information; NTSTATUS Status; LIST_ENTRY FreeListHead; RtlZeroMemory(&PerfCpuTotal, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)); Status = (*NtQuerySystemInformation)(SystemProcessorPerformanceInformation, PerfCpuInformation, PerfCpuInformationLength, NULL); ASSERT(Status == STATUS_SUCCESS); for (i = 0; i < BspProcessorNumber; i++) { PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Cpu = &PerfCpuInformation[i]; Cpu->KernelTime.QuadPart -= Cpu->IdleTime.QuadPart + Cpu->DpcTime.QuadPart + Cpu->InterruptTime.QuadPart; PerfCpuTotal.DpcTime.QuadPart += Cpu->DpcTime.QuadPart; PerfCpuTotal.IdleTime.QuadPart += Cpu->IdleTime.QuadPart; PerfCpuTotal.InterruptCount += Cpu->InterruptCount; PerfCpuTotal.InterruptTime.QuadPart += Cpu->InterruptTime.QuadPart; PerfCpuTotal.KernelTime.QuadPart += Cpu->KernelTime.QuadPart; PerfCpuTotal.UserTime.QuadPart += Cpu->UserTime.QuadPart; PerfUpdateDelta(&PerfCpusKernelDelta[i], Cpu->KernelTime.QuadPart); PerfUpdateDelta(&PerfCpusUserDelta[i], Cpu->UserTime.QuadPart); PerfUpdateDelta(&PerfCpusOtherDelta[i], Cpu->IdleTime.QuadPart + Cpu->DpcTime.QuadPart + Cpu->InterruptTime.QuadPart); TotalTime = PerfCpusKernelDelta[i].Delta + PerfCpusUserDelta[i].Delta + PerfCpusOtherDelta[i].Delta; if (TotalTime != 0) { PerfCpusKernelUsage[i] = (FLOAT)PerfCpusKernelDelta[i].Delta / TotalTime; PerfCpusUserUsage[i] = (FLOAT)PerfCpusUserDelta[i].Delta / TotalTime; } else { PerfCpusKernelUsage[i] = 0; PerfCpusUserUsage[i] = 0; } } PerfUpdateDelta(&PerfCpuKernelDelta, PerfCpuTotal.KernelTime.QuadPart); PerfUpdateDelta(&PerfCpuUserDelta, PerfCpuTotal.UserTime.QuadPart); PerfUpdateDelta(&PerfCpuOtherDelta, PerfCpuTotal.IdleTime.QuadPart + PerfCpuTotal.DpcTime.QuadPart + PerfCpuTotal.InterruptTime.QuadPart); TotalTime = PerfCpuKernelDelta.Delta + PerfCpuUserDelta.Delta + PerfCpuOtherDelta.Delta; if (TotalTime) { PerfCpuKernelUsage = (FLOAT)PerfCpuKernelDelta.Delta / TotalTime; PerfCpuUserUsage = (FLOAT)PerfCpuUserDelta.Delta / TotalTime; } else { PerfCpuKernelUsage = 0; PerfCpuUserUsage = 0; } PerfTotalTime = TotalTime; InitializeListHead(&ListHead); InitializeListHead(&FreeListHead); BspQueryProcessList(&ListHead); ListEntry = PerfListHead.Flink; while (ListEntry != &PerfListHead) { HANDLE ProcessHandle; PROCESS_MEMORY_COUNTERS_EX MemoryCounters; IO_COUNTERS IoCounters; Information = CONTAINING_RECORD(ListEntry, PERF_INFORMATION, ListEntry); Process = BspQueryProcessById(&ListHead, Information->ProcessId); if (!Process) { ASSERT(Information->ProcessId != 0); ListEntry = ListEntry->Flink; Information->Terminated = TRUE; RemoveEntryList(&Information->ListEntry); InsertTailList(&FreeListHead, &Information->ListEntry); if (!PerfFirstRun) { PerfPushUpdateToConsumers(Information); } continue; } PerfUpdateDelta(&Information->CpuKernelDelta, Process->KernelTime.QuadPart); PerfUpdateDelta(&Information->CpuUserDelta, Process->UserTime.QuadPart); if (PerfTotalTime != 0) { Information->CpuKernelUsage = (FLOAT)Information->CpuKernelDelta.Delta / PerfTotalTime; Information->CpuUserUsage = (FLOAT)Information->CpuUserDelta.Delta / PerfTotalTime; Information->CpuTotalUsage = (FLOAT)Information->CpuKernelUsage + Information->CpuUserUsage; } else { Information->CpuKernelUsage = 0; Information->CpuUserUsage = 0; Information->CpuTotalUsage = 0; } ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process->ProcessId); GetProcessMemoryInfo(ProcessHandle, (PPROCESS_MEMORY_COUNTERS)&MemoryCounters, sizeof(MemoryCounters)); GetProcessIoCounters(ProcessHandle, &IoCounters); PerfUpdateDelta(&Information->PrivateDelta, MemoryCounters.PrivateUsage); PerfUpdateDelta(&Information->WorkingSetDelta, MemoryCounters.WorkingSetSize); Information->WorkingSetPeak = MemoryCounters.PeakWorkingSetSize; PerfUpdateDelta(&Information->VirtualDelta, Process->VirtualBytes); PerfUpdateDelta(&Information->IoReadDelta, IoCounters.ReadTransferCount); PerfUpdateDelta(&Information->IoWriteDelta, IoCounters.WriteTransferCount); Information->KernelHandles = Process->KernelHandleCount; Information->UserHandles = GetGuiResources(ProcessHandle, GR_USEROBJECTS); Information->GdiHandles = GetGuiResources(ProcessHandle, GR_GDIOBJECTS); CloseHandle(ProcessHandle); if (Information->KernelHandlesPeak < Information->KernelHandles) { Information->KernelHandlesPeak = Information->KernelHandles; } if (Information->UserHandlesPeak < Information->UserHandles) { Information->UserHandlesPeak = Information->UserHandles; } if (Information->GdiHandlesPeak < Information->GdiHandles) { Information->GdiHandlesPeak = Information->GdiHandles; } // // Notify all performance data consumers via registered callback objects // if (!PerfFirstRun) { PerfPushUpdateToConsumers(Information); } ListEntry = ListEntry->Flink; } // // Deallocate died PERF_INFORMATION structures // while (IsListEmpty(&FreeListHead) != TRUE) { ListEntry = RemoveHeadList(&FreeListHead); Information = CONTAINING_RECORD(ListEntry, PERF_INFORMATION, ListEntry); BspFree(Information); } BspFreeProcessList(&ListHead); if (PerfFirstRun) { PerfFirstRun = FALSE; } return 0; }
void AppExit( void ) { BspFree(); }