16405705983d6fff9a82173068b5704e35be8f93
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/zone.c
5 * PURPOSE: Implements zone buffers
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 * David Welch (welch@mcmail.com)
11 /* INCLUDES ****************************************************************/
17 /* FUNCTIONS ***************************************************************/
24 ExExtendZone(PZONE_HEADER Zone
,
32 * BlockSize and Segment must be 8-byte aligned.
33 * Blocksize cannot exceed Segment Size.
35 if (((ULONG_PTR
)Segment
& 7) ||
37 (Zone
->BlockSize
> SegmentSize
))
39 DPRINT1("Invalid ExExtendZone Alignment and/or Size\n");
40 return STATUS_INVALID_PARAMETER
;
43 /* Link the Zone and Segment */
44 PushEntryList(&Zone
->SegmentList
,&((PZONE_SEGMENT_HEADER
)Segment
)->SegmentList
);
46 /* Get to the first entry */
47 Entry
= (ULONG_PTR
)Segment
+ sizeof(ZONE_SEGMENT_HEADER
);
49 /* Loop through the segments */
50 for (i
= sizeof(ZONE_SEGMENT_HEADER
);
51 i
<= SegmentSize
- Zone
->BlockSize
;
54 /* Link the Free and Segment Lists */
55 PushEntryList(&Zone
->FreeList
, (PSINGLE_LIST_ENTRY
)Entry
);
57 /* Go to the next entry */
58 Entry
+= Zone
->BlockSize
;
61 /* Update Segment Size */
62 Zone
->TotalSegmentSize
+= i
;
65 return STATUS_SUCCESS
;
74 ExInterlockedExtendZone(PZONE_HEADER Zone
,
83 KeAcquireSpinLock(Lock
, &OldIrql
);
86 Status
= ExExtendZone(Zone
, Segment
, SegmentSize
);
88 /* Release lock and return status */
89 KeReleaseSpinLock(Lock
, OldIrql
);
95 * FUNCTION: Initalizes a zone header
97 * Zone = zone header to be initialized
98 * BlockSize = Size (in bytes) of the allocation size of the zone
99 * InitialSegment = Initial segment of storage allocated by the
101 * InitialSegmentSize = Initial size of the segment
107 ExInitializeZone(PZONE_HEADER Zone
,
109 PVOID InitialSegment
,
110 ULONG InitialSegmentSize
)
116 * BlockSize and Segment must be 8-byte aligned.
117 * Blocksize cannot exceed Segment Size.
119 if (((ULONG_PTR
)InitialSegment
& 7) ||
120 (InitialSegmentSize
& 7) ||
121 (BlockSize
> InitialSegmentSize
))
123 DPRINT1("Invalid ExInitializeZone Alignment and/or Size\n");
124 return STATUS_INVALID_PARAMETER
;
127 /* Set the Zone Header */
128 Zone
->BlockSize
= BlockSize
;
130 /* Link empty list */
131 Zone
->FreeList
.Next
= NULL
;
132 Zone
->SegmentList
.Next
= NULL
;
133 PushEntryList(&Zone
->SegmentList
, &((PZONE_SEGMENT_HEADER
)InitialSegment
)->SegmentList
);
134 ((PZONE_SEGMENT_HEADER
)InitialSegment
)->Reserved
= NULL
;
136 /* Get first entry */
137 Entry
= (ULONG_PTR
)InitialSegment
+ sizeof(ZONE_SEGMENT_HEADER
);
139 /* Loop through the segments */
140 for (i
= sizeof(ZONE_SEGMENT_HEADER
);
141 i
<= InitialSegmentSize
- BlockSize
;
144 /* Link the Free and Segment Lists */
145 PushEntryList(&Zone
->FreeList
, (PSINGLE_LIST_ENTRY
)Entry
);
147 /* Go to the next entry */
148 Entry
+= Zone
->BlockSize
;
151 /* Update Segment Size */
152 Zone
->TotalSegmentSize
+= i
;
155 return STATUS_SUCCESS
;