mirror of
https://github.com/reactos/reactos.git
synced 2024-10-23 14:36:11 +00:00
* Delete the virtual mapping first before the the mapped range
is freed in MmFreeNonPagedPoolRegion. * Adujust AllocMapHint only if the reserved block starts at AllocMapHint. * Changed the bit allocation functions to RtlXxxBitMapYyy. svn path=/trunk/; revision=3701
This commit is contained in:
parent
3d3d96c5d6
commit
4fcb4176f8
|
@ -1,4 +1,4 @@
|
|||
/* $Id: kmap.c,v 1.21 2002/10/01 19:27:22 chorns Exp $
|
||||
/* $Id: kmap.c,v 1.22 2002/11/05 20:41:17 hbirr Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -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<ALLOC_MAP_SIZE;i++)
|
||||
{
|
||||
if (!(AllocMap[i/32] & (1 << (i % 32))))
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
start=i;
|
||||
length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
length++;
|
||||
}
|
||||
if (length==nr_pages)
|
||||
{
|
||||
AllocMapHint = start + length;
|
||||
for (j=start;j<(start+length);j++)
|
||||
{
|
||||
AllocMap[j / 32] |= (1 << (j % 32));
|
||||
}
|
||||
DPRINT("returning %x\n",((start*PAGE_SIZE)+NonPagedPoolBase));
|
||||
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
||||
return(((start*PAGE_SIZE)+NonPagedPoolBase));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start=0;
|
||||
length=0;
|
||||
}
|
||||
}
|
||||
DbgPrint("CRITICAL: Out of non-paged pool space\n");
|
||||
KeBugCheck(0);
|
||||
return(0);
|
||||
Base = RtlFindClearBitsAndSet(&AllocMap, nr_pages, AllocMapHint);
|
||||
if (Base == 0xFFFFFFFF)
|
||||
{
|
||||
DbgPrint("CRITICAL: Out of non-paged pool space\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
if (AllocMapHint == Base)
|
||||
{
|
||||
AllocMapHint += nr_pages;
|
||||
}
|
||||
KeReleaseSpinLock(&AllocMapLock, oldlvl);
|
||||
DPRINT("returning %x\n",NonPagedPoolBase + Base * PAGE_SIZE);
|
||||
return NonPagedPoolBase + Base * PAGE_SIZE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue