From cc824ce464403601f1ecaadf6f518b52cb78bc79 Mon Sep 17 00:00:00 2001 From: David Welch Date: Thu, 20 Dec 2001 03:56:10 +0000 Subject: [PATCH] Fixed fast mutex implementation (they are NOT recursive) Implemented paged pool Removed duplicate dependency tool source file svn path=/trunk/; revision=2433 --- reactos/hal/halx86/fmutex.c | 25 +-- reactos/lib/kernel32/misc/console.c | 92 ++++---- reactos/ntoskrnl/depends.c | 55 ----- reactos/ntoskrnl/ex/fmutex.c | 29 ++- reactos/ntoskrnl/include/internal/mm.h | 2 + reactos/ntoskrnl/include/internal/ntoskrnl.h | 2 +- reactos/ntoskrnl/include/internal/pool.h | 10 + reactos/ntoskrnl/mm/freelist.c | 5 +- reactos/ntoskrnl/mm/mm.c | 26 ++- reactos/ntoskrnl/mm/mminit.c | 21 +- reactos/ntoskrnl/mm/npool.c | 4 +- reactos/ntoskrnl/mm/pool.c | 38 ++-- reactos/ntoskrnl/mm/ppool.c | 224 ++++++++++++++++++- reactos/subsys/win32k/ntuser/message.c | 16 +- 14 files changed, 370 insertions(+), 179 deletions(-) delete mode 100644 reactos/ntoskrnl/depends.c diff --git a/reactos/hal/halx86/fmutex.c b/reactos/hal/halx86/fmutex.c index c840382d30e..06a0454c051 100644 --- a/reactos/hal/halx86/fmutex.c +++ b/reactos/hal/halx86/fmutex.c @@ -1,4 +1,4 @@ -/* $Id: fmutex.c,v 1.1 2001/08/21 20:18:27 chorns Exp $ +/* $Id: fmutex.c,v 1.2 2001/12/20 03:56:08 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,32 +22,15 @@ VOID FASTCALL ExAcquireFastMutex (PFAST_MUTEX FastMutex) { KeEnterCriticalRegion(); - if (InterlockedDecrement(&(FastMutex->Count))==0) - { - return; - } - FastMutex->Contention++; - KeWaitForSingleObject(&(FastMutex->Event), - Executive, - KernelMode, - FALSE, - NULL); - FastMutex->Owner=KeGetCurrentThread(); + ExAcquireFastMutexUnsafe(FastMutex); } VOID FASTCALL ExReleaseFastMutex (PFAST_MUTEX FastMutex) { - assert(FastMutex->Owner == KeGetCurrentThread()); - FastMutex->Owner=NULL; - if (InterlockedIncrement(&(FastMutex->Count))<=0) - { - return; - } - KeSetEvent(&(FastMutex->Event),0,FALSE); - - KeLeaveCriticalRegion(); + ExReleaseFastMutexUnsafe(FastMutex); + KeLeaveCriticalRegion(); } diff --git a/reactos/lib/kernel32/misc/console.c b/reactos/lib/kernel32/misc/console.c index eee14aa0699..8fa9b328b32 100644 --- a/reactos/lib/kernel32/misc/console.c +++ b/reactos/lib/kernel32/misc/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.38 2001/12/02 23:34:40 dwelch Exp $ +/* $Id: console.c,v 1.39 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -1279,54 +1279,50 @@ ReadConsoleOutputAttribute( /*-------------------------------------------------------------- * WriteConsoleOutputCharacterA */ -WINBASEAPI -BOOL -WINAPI -WriteConsoleOutputCharacterA( - HANDLE hConsoleOutput, - LPCSTR lpCharacter, - DWORD nLength, - COORD dwWriteCoord, - LPDWORD lpNumberOfCharsWritten - ) +WINBASEAPI BOOL WINAPI +WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, + LPCSTR lpCharacter, + DWORD nLength, + COORD dwWriteCoord, + LPDWORD lpNumberOfCharsWritten) { - PCSRSS_API_REQUEST Request; - CSRSS_API_REPLY Reply; - NTSTATUS Status; - WORD Size; - - Request = RtlAllocateHeap(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR); - if( !Request ) - { - SetLastError( ERROR_OUTOFMEMORY ); - return FALSE; - } - Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR; - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord; - if( lpNumberOfCharsWritten ) - *lpNumberOfCharsWritten = nLength; - while( nLength ) - { - Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength; - Request->Data.WriteConsoleOutputCharRequest.Length = Size; - memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0], - lpCharacter, - Size ); - Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) ); - if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) - { - RtlFreeHeap( GetProcessHeap(), 0, Request ); - SetLastErrorByStatus ( Status ); - return FALSE; - } - nLength -= Size; - lpCharacter += Size; - Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord; - } - return TRUE; + PCSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + WORD Size; + + Request = RtlAllocateHeap(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR); + if( !Request ) + { + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR; + Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput; + Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord; + if( lpNumberOfCharsWritten ) + *lpNumberOfCharsWritten = nLength; + while( nLength ) + { + Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength; + Request->Data.WriteConsoleOutputCharRequest.Length = Size; + memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0], + lpCharacter, + Size ); + Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) ); + if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) + { + RtlFreeHeap( GetProcessHeap(), 0, Request ); + SetLastErrorByStatus ( Status ); + return FALSE; + } + nLength -= Size; + lpCharacter += Size; + Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord; + } + return TRUE; } diff --git a/reactos/ntoskrnl/depends.c b/reactos/ntoskrnl/depends.c deleted file mode 100644 index e15f4bf0fd3..00000000000 --- a/reactos/ntoskrnl/depends.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include - -int main(int argc, char* argv[]) -{ - char buf[512]; - char ch; - unsigned int i; - char* dot; - char* prefix; - FILE* out; - - if (argc != 3) - { - printf("Too few arguments\n"); - return(1); - } - - prefix = strdup(argv[1]); - - out = fopen(argv[2], "wb"); - if (out == NULL) - { - printf("Unable to open output file\n"); - return(1); - } - - i = 0; - while ((ch = fgetc(stdin)) != ':' && ch != EOF) - { - buf[i] = ch; - i++; - } - buf[i] = 0; - - if (i == 0) - { - return(0); - } - - dot = strrchr(buf, '.'); - if (dot != NULL) - { - *dot = 0; - } - fprintf(out, "%s/.%s.d %s/%s.o:", prefix, buf, prefix,buf); - - while ((ch = fgetc(stdin)) != EOF) - { - fputc(ch, out); - } - - return(0); -} diff --git a/reactos/ntoskrnl/ex/fmutex.c b/reactos/ntoskrnl/ex/fmutex.c index 68768746025..213b8e87a58 100644 --- a/reactos/ntoskrnl/ex/fmutex.c +++ b/reactos/ntoskrnl/ex/fmutex.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: fmutex.c,v 1.10 2001/06/20 12:57:32 ekohl Exp $ +/* $Id: fmutex.c,v 1.11 2001/12/20 03:56:09 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ex/fmutex.c @@ -39,29 +39,26 @@ VOID FASTCALL ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) { - if (InterlockedDecrement(&FastMutex->Count) == 0) + while (InterlockedExchange(&FastMutex->Count, 0) == 0) { - return; + FastMutex->Contention++; + KeWaitForSingleObject(&FastMutex->Event, + Executive, + KernelMode, + FALSE, + NULL); + FastMutex->Contention--; } - FastMutex->Contention++; - KeWaitForSingleObject(&FastMutex->Event, - Executive, - KernelMode, - FALSE, - NULL); FastMutex->Owner = KeGetCurrentThread(); } VOID FASTCALL ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex) { - assert(FastMutex->Owner == KeGetCurrentThread()); - if (InterlockedIncrement(&FastMutex->Count) <= 0) - { - return; - } - FastMutex->Owner = NULL; - KeSetEvent(&FastMutex->Event, 0, FALSE); + assert(FastMutex->Owner == KeGetCurrentThread()); + FastMutex->Owner = NULL; + InterlockedExchange(&FastMutex->Count, 1); + KeSetEvent(&FastMutex->Event, 0, FALSE); } /* EOF */ diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 6d2c6270ca6..8d2cc184794 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -26,6 +26,7 @@ typedef ULONG SWAPENTRY; #define MEMORY_AREA_SHARED_DATA (11) #define MEMORY_AREA_WORKING_SET (12) #define MEMORY_AREA_KERNEL_STACK (13) +#define MEMORY_AREA_PAGED_POOL (14) #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \ ((x) / (4*1024*1024)) @@ -470,5 +471,6 @@ NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address, ULONG flProtect, ULONG PhysicalAddress); +NTSTATUS MmCommitPagedPoolAddress(PVOID Address); #endif diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 6f65225d8fa..712de53d110 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -22,7 +22,7 @@ /* * Maximum size of the kmalloc area (this is totally arbitary) */ -#define NONPAGED_POOL_SIZE (400*1024*1024) +#define NONPAGED_POOL_SIZE (4*1024*1024) /* * Defines a descriptor as it appears in the processor tables diff --git a/reactos/ntoskrnl/include/internal/pool.h b/reactos/ntoskrnl/include/internal/pool.h index 000d93ea8ee..0248baf46a7 100644 --- a/reactos/ntoskrnl/include/internal/pool.h +++ b/reactos/ntoskrnl/include/internal/pool.h @@ -9,5 +9,15 @@ PVOID STDCALL ExAllocateNonPagedPoolWithTag (POOL_TYPE type, PVOID STDCALL ExAllocatePagedPoolWithTag (POOL_TYPE Type, ULONG size, ULONG Tag); +VOID STDCALL ExFreeNonPagedPool (PVOID block); + +VOID STDCALL +ExFreePagedPool(IN PVOID Block); +VOID MmInitializePagedPool(VOID); + +extern PVOID MmPagedPoolBase; +extern ULONG MmPagedPoolSize; + +#define MM_PAGED_POOL_SIZE (4*1024*1024) #endif /* __INTERNAL_POOL_H */ diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 42a6cb2d13c..c33950ff8bb 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -219,6 +219,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, { ULONG i; ULONG Reserved; + ULONG ReservedGap; NTSTATUS Status; DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, " @@ -237,12 +238,14 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, Reserved = PAGE_ROUND_UP((MemorySizeInPages * sizeof(PHYSICAL_PAGE))) / PAGESIZE; + ReservedGap = + PAGE_ROUND_UP((131072 * sizeof(PHYSICAL_PAGE))) / PAGESIZE; MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress; DPRINT("Reserved %d\n", Reserved); LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); - LastKernelAddress = ((ULONG)LastKernelAddress + (Reserved * PAGESIZE)); + LastKernelAddress = ((ULONG)LastKernelAddress + (ReservedGap * PAGESIZE)); LastPhysKernelAddress = (PVOID)PAGE_ROUND_UP(LastPhysKernelAddress); LastPhysKernelAddress = LastPhysKernelAddress + (Reserved * PAGESIZE); diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index b4658d6c1b7..9e208d833ed 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: mm.c,v 1.49 2001/12/06 00:54:54 dwelch Exp $ +/* $Id: mm.c,v 1.50 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -210,6 +210,10 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode, case MEMORY_AREA_SYSTEM: Status = STATUS_UNSUCCESSFUL; break; + + case MEMORY_AREA_PAGED_POOL: + Status = STATUS_SUCCESS; + break; case MEMORY_AREA_SECTION_VIEW_COMMIT: Status = MmAccessFaultSectionView(AddressSpace, @@ -238,6 +242,18 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode, return(Status); } +NTSTATUS MmCommitPagedPoolAddress(PVOID Address) +{ + NTSTATUS Status; + PVOID AllocatedPage = MmAllocPage(0); + Status = + MmCreateVirtualMapping(NULL, + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READONLY, + (ULONG)AllocatedPage); + return(Status); +} + NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, ULONG Address, BOOLEAN FromMdl) @@ -303,6 +319,12 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, switch (MemoryArea->Type) { + case MEMORY_AREA_PAGED_POOL: + { + Status = MmCommitPagedPoolAddress((PVOID)Address); + break; + } + case MEMORY_AREA_SYSTEM: Status = STATUS_UNSUCCESSFUL; break; @@ -323,7 +345,7 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, case MEMORY_AREA_SHARED_DATA: Status = - MmCreateVirtualMapping(PsGetCurrentProcess(), + MmCreateVirtualMapping(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address), PAGE_READONLY, (ULONG)MmSharedDataPagePhysicalAddress); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 51fa252847a..a71c1744aa9 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -1,4 +1,4 @@ -/* $Id: mminit.c,v 1.27 2001/12/06 00:54:54 dwelch Exp $ +/* $Id: mminit.c,v 1.28 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -19,6 +19,7 @@ #include #include #include +#include #define NDEBUG #include @@ -46,6 +47,7 @@ static MEMORY_AREA* kernel_data_desc = NULL; static MEMORY_AREA* kernel_param_desc = NULL; static MEMORY_AREA* kernel_pool_desc = NULL; static MEMORY_AREA* kernel_shared_data_desc = NULL; +static MEMORY_AREA* MiPagedPoolDescriptor = NULL; PVOID MmSharedDataPagePhysicalAddress = NULL; @@ -85,9 +87,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); MmInitMemoryAreas(); -// ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE); ExInitNonPagedPool(LastKernelAddress + PAGESIZE); - /* * Setup the system area descriptor list @@ -152,6 +152,21 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, &kernel_pool_desc, FALSE); + MmPagedPoolSize = MM_PAGED_POOL_SIZE; + BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE + NONPAGED_POOL_SIZE + + PAGESIZE); + MmPagedPoolBase = BaseAddress; + Length = MM_PAGED_POOL_SIZE; + MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_PAGED_POOL, + &BaseAddress, + Length, + 0, + &MiPagedPoolDescriptor, + FALSE); + MmInitializePagedPool(); + /* * Create the kernel mapping of the user/kernel shared memory. */ diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index d91d009a8be..a560f97b2b2 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -1,4 +1,4 @@ -/* $Id: npool.c,v 1.50 2001/12/06 00:54:54 dwelch Exp $ +/* $Id: npool.c,v 1.51 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -825,7 +825,7 @@ static void* take_block(BLOCK_HDR* current, unsigned int size, #endif /* not WHOLE_PAGE_ALLOCATIONS */ -VOID STDCALL ExFreePool (PVOID block) +VOID STDCALL ExFreeNonPagedPool (PVOID block) /* * FUNCTION: Releases previously allocated memory * ARGUMENTS: diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index 9a19f9b37a8..11f0b74a9e5 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -1,4 +1,4 @@ -/* $Id: pool.c,v 1.12 2001/03/07 08:57:09 dwelch Exp $ +/* $Id: pool.c,v 1.13 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -51,9 +51,7 @@ EiAllocatePool(POOL_TYPE PoolType, case PagedPool: case PagedPoolCacheAligned: - // Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); - Block = ExAllocateNonPagedPoolWithTag(PoolType, NumberOfBytes, - Tag, Caller); + Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); break; default: @@ -68,8 +66,7 @@ EiAllocatePool(POOL_TYPE PoolType, return(Block); } -PVOID -STDCALL +PVOID STDCALL ExAllocatePool (POOL_TYPE PoolType, ULONG NumberOfBytes) /* * FUNCTION: Allocates pool memory of a specified type and returns a pointer @@ -114,19 +111,10 @@ ExAllocatePoolWithTag (ULONG PoolType, ULONG NumberOfBytes, ULONG Tag) } -PVOID -STDCALL +PVOID STDCALL ExAllocatePoolWithQuota (POOL_TYPE PoolType, ULONG NumberOfBytes) { -#if 0 - PVOID Block; - Block = EiAllocatePool(PoolType, - NumberOfBytes, - TAG_NONE, - (PVOID)__builtin_return_address(0)); - return(Block); -#endif - UNIMPLEMENTED; + return(ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, TAG_NONE)); } @@ -146,5 +134,21 @@ ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, UNIMPLEMENTED; } +VOID STDCALL +ExFreePool(IN PVOID Block) +{ + if (Block >= MmPagedPoolBase && Block < (MmPagedPoolBase + MmPagedPoolSize)) + { + ExFreePagedPool(Block); + } + else + { + ExFreeNonPagedPool(Block); + } +} /* EOF */ + + + + diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index cb81cf8b2da..17f605597bc 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -1,4 +1,4 @@ -/* $Id: ppool.c,v 1.3 2001/03/06 14:41:18 dwelch Exp $ +/* $Id: ppool.c,v 1.4 2001/12/20 03:56:09 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,11 +13,43 @@ #include #include +#include #include +/* GLOBALS *******************************************************************/ + +typedef struct _MM_PPOOL_FREE_BLOCK_HEADER +{ + ULONG Size; + struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree; +} MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER; + +typedef struct _MM_PPOOL_USED_BLOCK_HEADER +{ + ULONG Size; +} MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER; + +PVOID MmPagedPoolBase; +ULONG MmPagedPoolSize; +static FAST_MUTEX MmPagedPoolLock; +static PMM_PPOOL_FREE_BLOCK_HEADER MmPagedPoolFirstFreeBlock; + /* FUNCTIONS *****************************************************************/ +VOID MmInitializePagedPool(VOID) +{ + MmPagedPoolFirstFreeBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)MmPagedPoolBase; + /* + * We are still at a high IRQL level at this point so explicitly commit + * the first page of the paged pool before writing the first block header. + */ + MmCommitPagedPoolAddress((PVOID)MmPagedPoolFirstFreeBlock); + MmPagedPoolFirstFreeBlock->Size = MmPagedPoolSize; + MmPagedPoolFirstFreeBlock->NextFree = NULL; + + ExInitializeFastMutex(&MmPagedPoolLock); +} /********************************************************************** * NAME INTERNAL @@ -34,9 +66,195 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag) { - UNIMPLEMENTED; /* FIXME: */ - return(NULL); + PMM_PPOOL_FREE_BLOCK_HEADER BestBlock; + PMM_PPOOL_FREE_BLOCK_HEADER CurrentBlock; + ULONG BlockSize; + PMM_PPOOL_USED_BLOCK_HEADER NewBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; + PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; + PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock; + PVOID BlockAddress; + + /* + * Don't bother allocating anything for a zero-byte block. + */ + if (NumberOfBytes == 0) + { + return(NULL); + } + + /* + * Calculate the total number of bytes we will need. + */ + BlockSize = NumberOfBytes + sizeof(MM_PPOOL_USED_BLOCK_HEADER); + + ExAcquireFastMutex(&MmPagedPoolLock); + + /* + * Find the best fitting block. + */ + PreviousBlock = NULL; + BestPreviousBlock = BestBlock = NULL; + CurrentBlock = MmPagedPoolFirstFreeBlock; + while (CurrentBlock != NULL) + { + if (CurrentBlock->Size >= BlockSize && + (BestBlock == NULL || + (BestBlock->Size - BlockSize) > (CurrentBlock->Size - BlockSize))) + { + BestPreviousBlock = PreviousBlock; + BestBlock = CurrentBlock; + } + + PreviousBlock = CurrentBlock; + CurrentBlock = CurrentBlock->NextFree; + } + + /* + * We didn't find anything suitable at all. + */ + if (BestBlock == NULL) + { + ExReleaseFastMutex(&MmPagedPoolLock); + return(NULL); + } + + /* + * Is there enough space to create a second block from the unused portion. + */ + if ((BestBlock->Size - BlockSize) > sizeof(PMM_PPOOL_USED_BLOCK_HEADER)) + { + ULONG NewSize = BestBlock->Size - BlockSize; + + /* + * Create the new free block. + */ + NextBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)((PVOID)BestBlock + BlockSize); + NextBlock->Size = NewSize; + NextBlock->NextFree = BestBlock->NextFree; + + /* + * Replace the old free block with it. + */ + if (BestPreviousBlock == NULL) + { + MmPagedPoolFirstFreeBlock = NextBlock; + } + else + { + BestPreviousBlock->NextFree = NextBlock; + } + + /* + * Create the new used block header. + */ + NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock; + NewBlock->Size = BlockSize; + } + else + { + ULONG NewSize = BestBlock->Size; + + /* + * Remove the selected block from the list of free blocks. + */ + if (BestPreviousBlock == NULL) + { + MmPagedPoolFirstFreeBlock = BestBlock->NextFree; + } + else + { + BestPreviousBlock->NextFree = BestBlock->NextFree; + } + + /* + * Set up the header of the new block + */ + NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock; + NewBlock->Size = NewSize; + } + + ExReleaseFastMutex(&MmPagedPoolLock); + + BlockAddress = (PVOID)NewBlock + sizeof(MM_PPOOL_USED_BLOCK_HEADER); + + memset(BlockAddress, 0, NumberOfBytes); + + return(BlockAddress); } +VOID STDCALL +ExFreePagedPool(IN PVOID Block) +{ + PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; + PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = + (PMM_PPOOL_USED_BLOCK_HEADER)(Block - sizeof(MM_PPOOL_USED_BLOCK_HEADER)); + ULONG UsedSize = UsedBlock->Size; + PMM_PPOOL_FREE_BLOCK_HEADER FreeBlock = + (PMM_PPOOL_FREE_BLOCK_HEADER)UsedBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextNextBlock; + + ExAcquireFastMutex(&MmPagedPoolLock); + + /* + * Begin setting up the new free block's header. + */ + FreeBlock->Size = UsedSize; + + /* + * Find the block immediate before and after it on the free list. + */ + PreviousBlock = NULL; + NextBlock = MmPagedPoolFirstFreeBlock; + while (NextBlock != NULL && NextBlock < FreeBlock) + { + PreviousBlock = NextBlock; + NextBlock = NextBlock->NextFree; + } + + /* + * Insert the freed block on the free list. + */ + if (PreviousBlock == NULL) + { + FreeBlock->NextFree = MmPagedPoolFirstFreeBlock; + MmPagedPoolFirstFreeBlock = FreeBlock; + } + else + { + PreviousBlock->NextFree = FreeBlock; + FreeBlock->NextFree = NextBlock; + } + + /* + * If the next block is immediately adjacent to the newly freed one then + * free them. + */ + if (NextBlock != NULL && + ((PVOID)FreeBlock + FreeBlock->Size) == (PVOID)NextBlock) + { + FreeBlock->Size = FreeBlock->Size + NextBlock->Size; + FreeBlock->NextFree = NextBlock->NextFree; + NextNextBlock = NextBlock->NextFree; + } + else + { + NextNextBlock = NextBlock; + } + + /* + * If the previous block is adjacent to the newly freed one then + * purge them. + */ + if (PreviousBlock != NULL && + ((PVOID)PreviousBlock + PreviousBlock->Size) == (PVOID)FreeBlock) + { + PreviousBlock->Size = PreviousBlock->Size + FreeBlock->Size; + PreviousBlock->NextFree = NextNextBlock; + } + + ExReleaseFastMutex(&MmPagedPoolLock); +} /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index fedb7d35087..a777c174af6 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.1 2001/06/12 17:50:29 chorns Exp $ +/* $Id: message.c,v 1.2 2001/12/20 03:56:10 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -43,16 +43,12 @@ NtUserDispatchMessage( return 0; } -BOOL -STDCALL -NtUserGetMessage( - LPMSG lpMsg, - HWND hWnd, - UINT wMsgFilterMin, - UINT wMsgFilterMax) +BOOL STDCALL +NtUserGetMessage(LPMSG lpMsg, + HWND hWnd, + UINT wMsgFilterMin, + UINT wMsgFilterMax) { - UNIMPLEMENTED - return FALSE; }