diff --git a/reactos/ntoskrnl/ex/zone.c b/reactos/ntoskrnl/ex/zone.c index e70f3c3f7ac..16405705983 100644 --- a/reactos/ntoskrnl/ex/zone.c +++ b/reactos/ntoskrnl/ex/zone.c @@ -1,57 +1,68 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/zone.c + * FILE: ntoskrnl/ex/zone.c * PURPOSE: Implements zone buffers * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * David Welch (welch@mcmail.com) */ /* INCLUDES ****************************************************************/ #include +#define NDEBUG +#include /* FUNCTIONS ***************************************************************/ -// undocumented? from extypes.h in here for now... - -//typedef struct _ZONE_ENTRY -//{ -// SINGLE_LIST_ENTRY Entry; -//} ZONE_ENTRY, *PZONE_ENTRY; - - - /* * @implemented */ NTSTATUS STDCALL -ExExtendZone ( - PZONE_HEADER Zone, - PVOID Segment, - ULONG SegmentSize - ) +ExExtendZone(PZONE_HEADER Zone, + PVOID Segment, + ULONG SegmentSize) { - PZONE_SEGMENT_HEADER entry; - PZONE_SEGMENT_HEADER seg; - unsigned int i; + ULONG_PTR Entry; + ULONG i; - seg = (PZONE_SEGMENT_HEADER)Segment; - seg->Reserved = (PVOID) SegmentSize; + /* + * BlockSize and Segment must be 8-byte aligned. + * Blocksize cannot exceed Segment Size. + */ + if (((ULONG_PTR)Segment & 7) || + (SegmentSize & 7) || + (Zone->BlockSize > SegmentSize)) + { + DPRINT1("Invalid ExExtendZone Alignment and/or Size\n"); + return STATUS_INVALID_PARAMETER; + } - PushEntryList(&Zone->SegmentList,&seg->SegmentList); + /* Link the Zone and Segment */ + PushEntryList(&Zone->SegmentList,&((PZONE_SEGMENT_HEADER)Segment)->SegmentList); - entry = (PZONE_SEGMENT_HEADER)( ((char*)seg) + sizeof(ZONE_SEGMENT_HEADER) ); + /* Get to the first entry */ + Entry = (ULONG_PTR)Segment + sizeof(ZONE_SEGMENT_HEADER); - for (i=0;i<(SegmentSize / Zone->BlockSize);i++) - { - PushEntryList(&Zone->FreeList,&entry->SegmentList); - entry = (PZONE_SEGMENT_HEADER)(((char*)entry) + sizeof(PZONE_SEGMENT_HEADER) + - Zone->BlockSize); - } - return(STATUS_SUCCESS); + /* Loop through the segments */ + for (i = sizeof(ZONE_SEGMENT_HEADER); + i <= SegmentSize - Zone->BlockSize; + i+= Zone->BlockSize) + { + /* Link the Free and Segment Lists */ + PushEntryList(&Zone->FreeList, (PSINGLE_LIST_ENTRY)Entry); + + /* Go to the next entry */ + Entry += Zone->BlockSize; + } + + /* Update Segment Size */ + Zone->TotalSegmentSize += i; + + /* Return Success */ + return STATUS_SUCCESS; } @@ -60,34 +71,26 @@ ExExtendZone ( */ NTSTATUS STDCALL -ExInterlockedExtendZone ( - PZONE_HEADER Zone, - PVOID Segment, - ULONG SegmentSize, - PKSPIN_LOCK Lock - ) +ExInterlockedExtendZone(PZONE_HEADER Zone, + PVOID Segment, + ULONG SegmentSize, + PKSPIN_LOCK Lock) { - NTSTATUS ret; - KIRQL oldlvl; + NTSTATUS Status; + KIRQL OldIrql; - KeAcquireSpinLock(Lock,&oldlvl); - ret = ExExtendZone(Zone,Segment,SegmentSize); - KeReleaseSpinLock(Lock,oldlvl); - return(ret); + /* Get the lock */ + KeAcquireSpinLock(Lock, &OldIrql); + + /* Extend the Zone */ + Status = ExExtendZone(Zone, Segment, SegmentSize); + + /* Release lock and return status */ + KeReleaseSpinLock(Lock, OldIrql); + return Status; } -/* - * @implemented - */ -NTSTATUS -STDCALL -ExInitializeZone ( - PZONE_HEADER Zone, - ULONG BlockSize, - PVOID InitialSegment, - ULONG InitialSegmentSize - ) /* * FUNCTION: Initalizes a zone header * ARGUMENTS: @@ -96,31 +99,60 @@ ExInitializeZone ( * InitialSegment = Initial segment of storage allocated by the * caller * InitialSegmentSize = Initial size of the segment + * + * @implemented */ +NTSTATUS +STDCALL +ExInitializeZone(PZONE_HEADER Zone, + ULONG BlockSize, + PVOID InitialSegment, + ULONG InitialSegmentSize) { - unsigned int i; - PZONE_SEGMENT_HEADER seg; - PZONE_SEGMENT_HEADER entry; + ULONG i; + ULONG_PTR Entry; - Zone->FreeList.Next=NULL; - Zone->SegmentList.Next=NULL; - Zone->BlockSize=BlockSize; - Zone->TotalSegmentSize = InitialSegmentSize; + /* + * BlockSize and Segment must be 8-byte aligned. + * Blocksize cannot exceed Segment Size. + */ + if (((ULONG_PTR)InitialSegment & 7) || + (InitialSegmentSize & 7) || + (BlockSize > InitialSegmentSize)) + { + DPRINT1("Invalid ExInitializeZone Alignment and/or Size\n"); + return STATUS_INVALID_PARAMETER; + } - seg = (PZONE_SEGMENT_HEADER)InitialSegment; - seg->Reserved = (PVOID*) InitialSegmentSize; + /* Set the Zone Header */ + Zone->BlockSize = BlockSize; - PushEntryList(&Zone->SegmentList,&seg->SegmentList); + /* Link empty list */ + Zone->FreeList.Next = NULL; + Zone->SegmentList.Next = NULL; + PushEntryList(&Zone->SegmentList, &((PZONE_SEGMENT_HEADER)InitialSegment)->SegmentList); + ((PZONE_SEGMENT_HEADER)InitialSegment)->Reserved = NULL; - entry = (PZONE_SEGMENT_HEADER)( ((char*)seg) + sizeof(ZONE_SEGMENT_HEADER) ); + /* Get first entry */ + Entry = (ULONG_PTR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER); - for (i=0;i<(InitialSegmentSize / BlockSize);i++) - { - PushEntryList(&Zone->FreeList,&entry->SegmentList); - entry = (PZONE_SEGMENT_HEADER)(((char*)entry) + sizeof(PZONE_SEGMENT_HEADER) + BlockSize); - } + /* Loop through the segments */ + for (i = sizeof(ZONE_SEGMENT_HEADER); + i <= InitialSegmentSize - BlockSize; + i+= BlockSize) + { + /* Link the Free and Segment Lists */ + PushEntryList(&Zone->FreeList, (PSINGLE_LIST_ENTRY)Entry); - return(STATUS_SUCCESS); + /* Go to the next entry */ + Entry += Zone->BlockSize; + } + + /* Update Segment Size */ + Zone->TotalSegmentSize += i; + + /* Return success */ + return STATUS_SUCCESS; } /* EOF */