2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/zone.c
5 * PURPOSE: Implements zone buffers
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * David Welch (welch@mcmail.com)
10 /* INCLUDES ****************************************************************/
16 /* FUNCTIONS ***************************************************************/
23 ExExtendZone(PZONE_HEADER Zone
,
31 * BlockSize and Segment must be 8-byte aligned.
32 * Blocksize cannot exceed Segment Size.
34 if (((ULONG_PTR
)Segment
& 7) ||
36 (Zone
->BlockSize
> SegmentSize
))
38 DPRINT1("Invalid ExExtendZone Alignment and/or Size\n");
39 return STATUS_INVALID_PARAMETER
;
42 /* Link the Zone and Segment */
43 PushEntryList(&Zone
->SegmentList
,
44 &((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
;
73 ExInterlockedExtendZone(PZONE_HEADER Zone
,
82 KeAcquireSpinLock(Lock
, &OldIrql
);
85 Status
= ExExtendZone(Zone
, Segment
, SegmentSize
);
87 /* Release lock and return status */
88 KeReleaseSpinLock(Lock
, OldIrql
);
93 * FUNCTION: Initializes a zone header
95 * Zone = zone header to be initialized
96 * BlockSize = Size (in bytes) of the allocation size of the zone
97 * InitialSegment = Initial segment of storage allocated by the
99 * InitialSegmentSize = Initial size of the segment
105 ExInitializeZone(PZONE_HEADER Zone
,
107 PVOID InitialSegment
,
108 ULONG InitialSegmentSize
)
114 * BlockSize and Segment must be 8-byte aligned.
115 * Blocksize cannot exceed Segment Size.
117 if (((ULONG_PTR
)InitialSegment
& 7) ||
118 (InitialSegmentSize
& 7) ||
119 (BlockSize
> InitialSegmentSize
))
121 DPRINT1("Invalid ExInitializeZone Alignment and/or Size\n");
122 return STATUS_INVALID_PARAMETER
;
125 /* Set the Zone Header */
126 Zone
->BlockSize
= BlockSize
;
128 /* Link empty list */
129 Zone
->FreeList
.Next
= NULL
;
130 Zone
->SegmentList
.Next
= NULL
;
131 PushEntryList(&Zone
->SegmentList
,
132 &((PZONE_SEGMENT_HEADER
)InitialSegment
)->SegmentList
);
133 ((PZONE_SEGMENT_HEADER
)InitialSegment
)->Reserved
= NULL
;
135 /* Get first entry */
136 Entry
= (ULONG_PTR
)InitialSegment
+ sizeof(ZONE_SEGMENT_HEADER
);
138 /* Loop through the segments */
139 for (i
= sizeof(ZONE_SEGMENT_HEADER
);
140 i
<= InitialSegmentSize
- BlockSize
;
143 /* Link the Free and Segment Lists */
144 PushEntryList(&Zone
->FreeList
, (PSINGLE_LIST_ENTRY
)Entry
);
146 /* Go to the next entry */
147 Entry
+= Zone
->BlockSize
;
150 /* Set Segment Size */
151 Zone
->TotalSegmentSize
= i
;
154 return STATUS_SUCCESS
;