X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fmm%2Fkmap.c;fp=ntoskrnl%2Fmm%2Fkmap.c;h=ab4879214a6bc336693d5dd05550c6285738e52f;hp=69809310b7db88f4861f3fc700c74746ed30a223;hb=d378c68f5a9bb25c9e671dacd482d2e25d211df3;hpb=83300d602d72c8c64d110c3086f98fd970d3ba07 diff --git a/ntoskrnl/mm/kmap.c b/ntoskrnl/mm/kmap.c index 6980931..ab48792 100644 --- a/ntoskrnl/mm/kmap.c +++ b/ntoskrnl/mm/kmap.c @@ -26,9 +26,10 @@ * One bit for each page in the kmalloc region * If set then the page is used by a kmalloc block */ -static ULONG AllocMap[ALLOC_MAP_SIZE/32]={0,}; +static UCHAR AllocMapBuffer[ROUND_UP(ALLOC_MAP_SIZE, 8) / 8]; +static RTL_BITMAP AllocMap; static KSPIN_LOCK AllocMapLock; -static ULONG AllocMapHint = 1; +static ULONG AllocMapHint = 0; static PVOID NonPagedPoolBase; @@ -38,15 +39,14 @@ VOID ExUnmapPage(PVOID Addr) { KIRQL oldIrql; - ULONG i = (Addr - NonPagedPoolBase) / PAGE_SIZE; + ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE; DPRINT("ExUnmapPage(Addr %x)\n",Addr); - DPRINT("i %x\n",i); MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL); KeAcquireSpinLock(&AllocMapLock, &oldIrql); - AllocMap[i / 32] &= (~(1 << (i % 32))); - AllocMapHint = min(AllocMapHint, i); + RtlClearBits(&AllocMap, Base, 1); + AllocMapHint = min(AllocMapHint, Base); KeReleaseSpinLock(&AllocMapLock, oldIrql); } @@ -99,35 +99,31 @@ PVOID ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage) { KIRQL oldlvl; - ULONG addr; - ULONG i; + PVOID Addr; + ULONG Base; NTSTATUS Status; KeAcquireSpinLock(&AllocMapLock, &oldlvl); - for (i = AllocMapHint; i < ALLOC_MAP_SIZE; i++) - { - if (!(AllocMap[i / 32] & (1 << (i % 32)))) - { - DPRINT("i %x\n",i); - AllocMap[i / 32] |= (1 << (i % 32)); - AllocMapHint = i + 1; - addr = (ULONG)(NonPagedPoolBase + (i*PAGE_SIZE)); - Status = MmCreateVirtualMapping(NULL, - (PVOID)addr, - PAGE_READWRITE | PAGE_SYSTEM, - PhysPage, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KeBugCheck(0); - } - KeReleaseSpinLock(&AllocMapLock, oldlvl); - return((PVOID)addr); - } - } + Base = RtlFindClearBitsAndSet(&AllocMap, 1, AllocMapHint); + if (Base != 0xFFFFFFFF) + { + AllocMapHint = Base + 1; + KeReleaseSpinLock(&AllocMapLock, oldlvl); + Addr = NonPagedPoolBase + Base * PAGE_SIZE; + Status = MmCreateVirtualMapping(NULL, + Addr, + PAGE_READWRITE | PAGE_SYSTEM, + PhysPage, + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KeBugCheck(0); + } + return Addr; + } KeReleaseSpinLock(&AllocMapLock, oldlvl); - return(NULL); + return NULL; } VOID @@ -135,6 +131,8 @@ MmInitKernelMap(PVOID BaseAddress) { NonPagedPoolBase = BaseAddress; KeInitializeSpinLock(&AllocMapLock); + RtlInitializeBitMap(&AllocMap, (PVOID)&AllocMapBuffer, ALLOC_MAP_SIZE); + RtlClearAllBits(&AllocMap); } VOID @@ -142,21 +140,19 @@ MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free) { ULONG i; ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE; - ULONG Offset; KIRQL oldlvl; - KeAcquireSpinLock(&AllocMapLock, &oldlvl); - AllocMapHint = min(AllocMapHint, Base); for (i = 0; i < Count; i++) - { - Offset = Base + i; - AllocMap[Offset / 32] &= (~(1 << (Offset % 32))); + { MmDeleteVirtualMapping(NULL, Addr + (i * PAGE_SIZE), Free, NULL, NULL); - } + } + KeAcquireSpinLock(&AllocMapLock, &oldlvl); + RtlClearBits(&AllocMap, Base, Count); + AllocMapHint = min(AllocMapHint, Base); KeReleaseSpinLock(&AllocMapLock, oldlvl); } @@ -166,44 +162,21 @@ MiAllocNonPagedPoolRegion(ULONG nr_pages) * FUNCTION: Allocates a region of pages within the nonpaged pool area */ { - unsigned int start = 0; - unsigned int length = 0; - unsigned int i,j; + ULONG Base; KIRQL oldlvl; KeAcquireSpinLock(&AllocMapLock, &oldlvl); - for (i=AllocMapHint; i