UINT64 D3DKMTGetMemoryUsage() { ULONG i; D3DKMT_QUERYSTATISTICS queryStatistics; UINT64 dedicatedUsage; dedicatedUsage = 0; for (i = 0; i < D3dkmt_GpuAdapter->SegmentCount; i++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT; queryStatistics.AdapterLuid = D3dkmt_GpuAdapter->AdapterLuid; queryStatistics.QuerySegment.SegmentId = i; if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics))) { UINT64 bytesCommitted; bytesCommitted = queryStatistics.QueryResult.SegmentInformationV1.BytesCommitted; if (!RtlCheckBit(&D3dkmt_GpuAdapter->ApertureBitMap, i)) dedicatedUsage += bytesCommitted; } } return dedicatedUsage; }
VOID test_bitmap() { Pool pool; ULONG Bitmap_Size, Index; PULONG Bitmap_Buffer; // Initialize Bitmap_Size = 13; // Number of bits Bitmap_Buffer = ExAllocatePoolWithTag ( NonPagedPool, (ULONG)(((Bitmap_Size/8+1)/sizeof(ULONG) + 1)* sizeof(ULONG)), BITMAP_TAG ); RtlInitializeBitMap( &pool.Bitmap, (PULONG)(Bitmap_Buffer), (ULONG)(Bitmap_Size) ); RtlClearAllBits(&pool.Bitmap); for (Index = 0; Index < 10; Index++) RtlSetBit(&pool.Bitmap, Index); if (RtlAreBitsSet(&pool.Bitmap, 0, 10) == TRUE) DbgPrint("bitmap: bit[0..9] is set\r\n"); if (RtlCheckBit(&pool.Bitmap, 10)) DbgPrint("bitmap: bit[10] is set\r\n"); if (RtlCheckBit(&pool.Bitmap, 1024)) //Warning! Return 1 here DbgPrint("bitmap: bit[1024] is set\r\n"); Index = 0; do { Index = RtlFindClearBitsAndSet ( &pool.Bitmap, 1, //NumberToFind Index //HintIndex ); DbgPrint("%d\n", Index); }while (Index != -1); // Free ExFreePoolWithTag(pool.Bitmap.Buffer, BITMAP_TAG); }
VOID EtpLoadNodeBitMap( VOID ) { ULONG i; for (i = 0; i < EtGpuTotalNodeCount; i++) { Button_SetCheck( CheckBoxHandle[i], RtlCheckBit(&EtGpuNodeBitMap, i) ? BST_CHECKED : BST_UNCHECKED ); } }
NTSTATUS FilterBox::MatchEvent ( __in EventData *Event, __in PRTL_BITMAP Affecting ) { /// \todo добавить параметр - какие уже элементы проверялись и с каким результатом \ // для оптимизации при продолжении сканирования по списку параметров if ( IsListEmpty( &m_Items ) ) { return STATUS_SUCCESS; } NTSTATUS status = STATUS_SUCCESS; PBoxFilterItem pEntry = NULL; PLIST_ENTRY Flink = m_Items.Flink; while ( Flink != &m_Items ) { pEntry = CONTAINING_RECORD( Flink, BoxFilterItem, m_List ); Flink = Flink->Flink; if ( pEntry->m_Position > Affecting->SizeOfBitMap ) { __debugbreak(); //nct continue; } if ( !RtlCheckBit( Affecting, pEntry->m_Position ) ) { continue; } status = CheckEntry( pEntry->m_Param, Event ); if ( NT_SUCCESS( status ) ) { break; } } return status; }
static void test_RtlCheckBit(void) { BOOLEAN bRet; memset(buff, 0 , sizeof(buff)); pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); pRtlSetBits(&bm, 0, 1); pRtlSetBits(&bm, 7, 2); pRtlSetBits(&bm, sizeof(buff)*8-1, 1); bRet = RtlCheckBit(&bm, 0); ok (bRet, "didn't find set bit\n"); bRet = RtlCheckBit(&bm, 7); ok (bRet, "didn't find set bit\n"); bRet = RtlCheckBit(&bm, 8); ok (bRet, "didn't find set bit\n"); bRet = RtlCheckBit(&bm, sizeof(buff)*8-1); ok (bRet, "didn't find set bit\n"); bRet = RtlCheckBit(&bm, 1); ok (!bRet, "found non set bit\n"); bRet = RtlCheckBit(&bm, sizeof(buff)*8-2); ok (!bRet, "found non set bit\n"); }
BOOLEAN FFSCheckSetBlock( PFFS_IRP_CONTEXT IrpContext, PFFS_VCB Vcb, ULONG Block) { #if 0 ULONG Group, dwBlk, Length; RTL_BITMAP BlockBitmap; PVOID BitmapCache; PBCB BitmapBcb; LARGE_INTEGER Offset; BOOLEAN bModified = FALSE; //Group = (Block - FFS_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP; dwBlk = (Block - FFS_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP; Offset.QuadPart = (LONGLONG) Vcb->BlockSize; Offset.QuadPart = Offset.QuadPart * Vcb->ffs_group_desc[Group].bg_block_bitmap; if (Group == Vcb->ffs_groups - 1) { Length = TOTAL_BLOCKS % BLOCKS_PER_GROUP; /* s_blocks_count is integer multiple of s_blocks_per_group */ if (Length == 0) Length = BLOCKS_PER_GROUP; } else { Length = BLOCKS_PER_GROUP; } if (dwBlk >= Length) return FALSE; if (!CcPinRead(Vcb->StreamObj, &Offset, Vcb->BlockSize, PIN_WAIT, &BitmapBcb, &BitmapCache)) { FFSPrint((DBG_ERROR, "FFSDeleteBlock: PinReading error ...\n")); return FALSE; } RtlInitializeBitMap(&BlockBitmap, BitmapCache, Length); if (RtlCheckBit(&BlockBitmap, dwBlk) == 0) { FFSBreakPoint(); RtlSetBits(&BlockBitmap, dwBlk, 1); bModified = TRUE; } if (bModified) { CcSetDirtyPinnedData(BitmapBcb, NULL); FFSRepinBcb(IrpContext, BitmapBcb); FFSAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize); } { CcUnpinData(BitmapBcb); BitmapBcb = NULL; BitmapCache = NULL; RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP)); } return (!bModified); #endif return FALSE; }
ULONG FASTCALL MiReleasePageFileSpace ( IN MMPTE PteContents ) /*++ Routine Description: This routine frees the paging file allocated to the specified PTE and adjusts the necessary quotas. Arguments: PteContents - Supplies the PTE which is in page file format. Return Value: Returns TRUE if any paging file space was deallocated. Environment: Kernel mode, APCs disabled, PFN lock held. --*/ { ULONG FreeBit; ULONG PageFileNumber; MM_PFN_LOCK_ASSERT(); if (PteContents.u.Soft.Prototype == 1) { // // Not in page file format. // return FALSE; } FreeBit = GET_PAGING_FILE_OFFSET (PteContents); if ((FreeBit == 0) || (FreeBit == 0xFFFFF)) { // // Page is not in a paging file, just return. // return FALSE; } PageFileNumber = GET_PAGING_FILE_NUMBER (PteContents); ASSERT (RtlCheckBit( MmPagingFile[PageFileNumber]->Bitmap, FreeBit) == 1); #if DBG if ((FreeBit < 8192) && (PageFileNumber == 0)) { ASSERT ((MmPagingFileDebug[FreeBit] & 1) != 0); MmPagingFileDebug[FreeBit] &= 0xfffffffe; } #endif //DBG RtlClearBits ( MmPagingFile[PageFileNumber]->Bitmap, FreeBit, 1); MmPagingFile[PageFileNumber]->FreeSpace += 1; MmPagingFile[PageFileNumber]->CurrentUsage -= 1; // // Check to see if we should move some MDL entries for the // modified page writer now that more free space is available. // if ((MmNumberOfActiveMdlEntries == 0) || (MmPagingFile[PageFileNumber]->FreeSpace == MM_USABLE_PAGES_FREE)) { MiUpdateModifiedWriterMdls (PageFileNumber); } return TRUE; }
VOID EtQueryProcessGpuStatistics( _In_ HANDLE ProcessHandle, _Out_ PET_PROCESS_GPU_STATISTICS Statistics ) { NTSTATUS status; ULONG i; ULONG j; PETP_GPU_ADAPTER gpuAdapter; D3DKMT_QUERYSTATISTICS queryStatistics; memset(Statistics, 0, sizeof(ET_PROCESS_GPU_STATISTICS)); for (i = 0; i < EtpGpuAdapterList->Count; i++) { gpuAdapter = EtpGpuAdapterList->Items[i]; Statistics->SegmentCount += gpuAdapter->SegmentCount; Statistics->NodeCount += gpuAdapter->NodeCount; for (j = 0; j < gpuAdapter->SegmentCount; j++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS_SEGMENT; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; queryStatistics.hProcess = ProcessHandle; queryStatistics.QueryProcessSegment.SegmentId = j; if (NT_SUCCESS(status = D3DKMTQueryStatistics_I(&queryStatistics))) { ULONG64 bytesCommitted; bytesCommitted = queryStatistics.QueryResult.ProcessSegmentInformation.BytesCommitted; if (RtlCheckBit(&gpuAdapter->ApertureBitMap, j)) Statistics->SharedCommitted += bytesCommitted; else Statistics->DedicatedCommitted += bytesCommitted; } } for (j = 0; j < gpuAdapter->NodeCount; j++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS_NODE; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; queryStatistics.hProcess = ProcessHandle; queryStatistics.QueryProcessNode.NodeId = j; if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics))) { Statistics->RunningTime += queryStatistics.QueryResult.ProcessNodeInformation.RunningTime.QuadPart; Statistics->ContextSwitches += queryStatistics.QueryResult.ProcessNodeInformation.ContextSwitch; } } memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; queryStatistics.hProcess = ProcessHandle; if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics))) { Statistics->BytesAllocated += queryStatistics.QueryResult.ProcessInformation.SystemMemory.BytesAllocated; Statistics->BytesReserved += queryStatistics.QueryResult.ProcessInformation.SystemMemory.BytesReserved; Statistics->WriteCombinedBytesAllocated += queryStatistics.QueryResult.ProcessInformation.SystemMemory.WriteCombinedBytesAllocated; Statistics->WriteCombinedBytesReserved += queryStatistics.QueryResult.ProcessInformation.SystemMemory.WriteCombinedBytesReserved; Statistics->CachedBytesAllocated += queryStatistics.QueryResult.ProcessInformation.SystemMemory.CachedBytesAllocated; Statistics->CachedBytesReserved += queryStatistics.QueryResult.ProcessInformation.SystemMemory.CachedBytesReserved; Statistics->SectionBytesAllocated += queryStatistics.QueryResult.ProcessInformation.SystemMemory.SectionBytesAllocated; Statistics->SectionBytesReserved += queryStatistics.QueryResult.ProcessInformation.SystemMemory.SectionBytesReserved; } } }
static VOID EtpUpdateNodeInformation( _In_opt_ PET_PROCESS_BLOCK Block ) { ULONG i; ULONG j; PETP_GPU_ADAPTER gpuAdapter; D3DKMT_QUERYSTATISTICS queryStatistics; ULONG64 totalRunningTime; ULONG64 systemRunningTime; if (Block && !Block->ProcessItem->QueryHandle) return; totalRunningTime = 0; systemRunningTime = 0; for (i = 0; i < EtpGpuAdapterList->Count; i++) { gpuAdapter = EtpGpuAdapterList->Items[i]; for (j = 0; j < gpuAdapter->NodeCount; j++) { if (Block && !RtlCheckBit(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j)) continue; memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); if (Block) queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS_NODE; else queryStatistics.Type = D3DKMT_QUERYSTATISTICS_NODE; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; if (Block) { queryStatistics.hProcess = Block->ProcessItem->QueryHandle; queryStatistics.QueryProcessNode.NodeId = j; } else { queryStatistics.QueryNode.NodeId = j; } if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics))) { if (Block) { totalRunningTime += queryStatistics.QueryResult.ProcessNodeInformation.RunningTime.QuadPart; } else { ULONG nodeIndex; nodeIndex = gpuAdapter->FirstNodeIndex + j; PhUpdateDelta(&EtGpuNodesTotalRunningTimeDelta[nodeIndex], queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart); if (RtlCheckBit(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j)) { totalRunningTime += queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart; systemRunningTime += queryStatistics.QueryResult.NodeInformation.SystemInformation.RunningTime.QuadPart; } } } } } if (Block) { PhUpdateDelta(&Block->GpuRunningTimeDelta, totalRunningTime); } else { LARGE_INTEGER performanceCounter; NtQueryPerformanceCounter(&performanceCounter, &EtClockTotalRunningTimeFrequency); PhUpdateDelta(&EtClockTotalRunningTimeDelta, performanceCounter.QuadPart); PhUpdateDelta(&EtGpuTotalRunningTimeDelta, totalRunningTime); PhUpdateDelta(&EtGpuSystemRunningTimeDelta, systemRunningTime); } }
static VOID EtpUpdateSegmentInformation( _In_opt_ PET_PROCESS_BLOCK Block ) { ULONG i; ULONG j; PETP_GPU_ADAPTER gpuAdapter; D3DKMT_QUERYSTATISTICS queryStatistics; ULONG64 dedicatedUsage; ULONG64 sharedUsage; if (Block && !Block->ProcessItem->QueryHandle) return; dedicatedUsage = 0; sharedUsage = 0; for (i = 0; i < EtpGpuAdapterList->Count; i++) { gpuAdapter = EtpGpuAdapterList->Items[i]; for (j = 0; j < gpuAdapter->SegmentCount; j++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); if (Block) queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS_SEGMENT; else queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; if (Block) { queryStatistics.hProcess = Block->ProcessItem->QueryHandle; queryStatistics.QueryProcessSegment.SegmentId = j; } else { queryStatistics.QuerySegment.SegmentId = j; } if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics))) { if (Block) { ULONG64 bytesCommitted; bytesCommitted = queryStatistics.QueryResult.ProcessSegmentInformation.BytesCommitted; if (RtlCheckBit(&gpuAdapter->ApertureBitMap, j)) sharedUsage += bytesCommitted; else dedicatedUsage += bytesCommitted; } else { ULONG64 bytesCommitted; bytesCommitted = queryStatistics.QueryResult.SegmentInformation.BytesCommitted; if (RtlCheckBit(&gpuAdapter->ApertureBitMap, j)) sharedUsage += bytesCommitted; else dedicatedUsage += bytesCommitted; } } } } if (Block) { Block->GpuDedicatedUsage = dedicatedUsage; Block->GpuSharedUsage = sharedUsage; } else { EtGpuDedicatedUsage = dedicatedUsage; EtGpuSharedUsage = sharedUsage; } }
VOID MiZeroPageFile ( IN PVOID Context ) /*++ Routine Description: This routine zeroes all inactive pagefile blocks in the specified paging file. Arguments: Context - Supplies the information on which pagefile to zero and a zeroed page to use for the I/O. Return Value: Returns TRUE on success, FALSE on failure. Environment: Kernel mode, the caller must lock down PAGELK. --*/ { PFN_NUMBER MaxPagesToWrite; PMMPFN Pfn1; PPFN_NUMBER Page; PFN_NUMBER MdlHack[(sizeof(MDL)/sizeof(PFN_NUMBER)) + MM_MAXIMUM_WRITE_CLUSTER]; PMDL Mdl; NTSTATUS Status; KEVENT IoEvent; IO_STATUS_BLOCK IoStatus; KIRQL OldIrql; LARGE_INTEGER StartingOffset; ULONG count; ULONG i; PFN_NUMBER first; ULONG write; PKEVENT AllDone; SIZE_T NumberOfBytes; PMMPAGING_FILE PagingFile; PFN_NUMBER ZeroedPageFrame; PMM_ZERO_PAGEFILE_CONTEXT ZeroContext; ZeroContext = (PMM_ZERO_PAGEFILE_CONTEXT) Context; PagingFile = ZeroContext->PagingFile; ZeroedPageFrame = ZeroContext->ZeroedPageFrame; AllDone = ZeroContext->AllDone; ExFreePool (Context); NumberOfBytes = MmModifiedWriteClusterSize << PAGE_SHIFT; MaxPagesToWrite = NumberOfBytes >> PAGE_SHIFT; Mdl = (PMDL) MdlHack; Page = (PPFN_NUMBER)(Mdl + 1); KeInitializeEvent (&IoEvent, NotificationEvent, FALSE); MmInitializeMdl (Mdl, NULL, PAGE_SIZE); Mdl->MdlFlags |= MDL_PAGES_LOCKED; Mdl->StartVa = NULL; i = 0; Page = (PPFN_NUMBER)(Mdl + 1); for (i = 0; i < MaxPagesToWrite; i += 1) { *Page = ZeroedPageFrame; Page += 1; } count = 0; write = FALSE; SATISFY_OVERZEALOUS_COMPILER (first = 0); LOCK_PFN (OldIrql); for (i = 1; i < PagingFile->Size; i += 1) { if (RtlCheckBit (PagingFile->Bitmap, (ULONG) i) == 0) { // // Claim the pagefile location as the modified writer // may already be scanning. // RtlSetBit (PagingFile->Bitmap, (ULONG) i); if (count == 0) { first = i; } count += 1; if ((count == MaxPagesToWrite) || (i == PagingFile->Size - 1)) { write = TRUE; } } else { if (count != 0) { // // Issue a write. // write = TRUE; } } if (write) { UNLOCK_PFN (OldIrql); StartingOffset.QuadPart = (LONGLONG)first << PAGE_SHIFT; Mdl->ByteCount = count << PAGE_SHIFT; KeClearEvent (&IoEvent); Status = IoSynchronousPageWrite (PagingFile->File, Mdl, &StartingOffset, &IoEvent, &IoStatus); // // Ignore all I/O failures - there is nothing that can // be done at this point. // if (!NT_SUCCESS (Status)) { KeSetEvent (&IoEvent, 0, FALSE); } Status = KeWaitForSingleObject (&IoEvent, WrPageOut, KernelMode, FALSE, (PLARGE_INTEGER)&MmTwentySeconds); if (Status == STATUS_TIMEOUT) { // // The write did not complete in 20 seconds, assume // that the file systems are hung and return an error. // // Note the zero page (and any MDL system virtual address a // driver may have created) is leaked because we don't know // what the filesystem or storage stack might (still) be // doing to them. // Pfn1 = MI_PFN_ELEMENT (ZeroedPageFrame); LOCK_PFN (OldIrql); // // Increment the reference count on the zeroed page to ensure // it is never freed. // InterlockedIncrementPfn ((PSHORT)&Pfn1->u3.e2.ReferenceCount); RtlClearBits (PagingFile->Bitmap, (ULONG) first, count); break; } if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) { MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); } write = FALSE; LOCK_PFN (OldIrql); RtlClearBits (PagingFile->Bitmap, (ULONG) first, count); count = 0; } } UNLOCK_PFN (OldIrql); KeSetEvent (AllDone, 0, FALSE); return; }