- Fix compile issues caused by previous patch.
[reactos.git] / reactos / ntoskrnl / ex / zone.c
1 /*
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 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 * David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES ****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* FUNCTIONS ***************************************************************/
18
19 /*
20 * @implemented
21 */
22 NTSTATUS
23 STDCALL
24 ExExtendZone(PZONE_HEADER Zone,
25 PVOID Segment,
26 ULONG SegmentSize)
27 {
28 ULONG_PTR Entry;
29 ULONG i;
30
31 /*
32 * BlockSize and Segment must be 8-byte aligned.
33 * Blocksize cannot exceed Segment Size.
34 */
35 if (((ULONG_PTR)Segment & 7) ||
36 (SegmentSize & 7) ||
37 (Zone->BlockSize > SegmentSize))
38 {
39 DPRINT1("Invalid ExExtendZone Alignment and/or Size\n");
40 return STATUS_INVALID_PARAMETER;
41 }
42
43 /* Link the Zone and Segment */
44 PushEntryList(&Zone->SegmentList,&((PZONE_SEGMENT_HEADER)Segment)->SegmentList);
45
46 /* Get to the first entry */
47 Entry = (ULONG_PTR)Segment + sizeof(ZONE_SEGMENT_HEADER);
48
49 /* Loop through the segments */
50 for (i = sizeof(ZONE_SEGMENT_HEADER);
51 i <= SegmentSize - Zone->BlockSize;
52 i+= Zone->BlockSize)
53 {
54 /* Link the Free and Segment Lists */
55 PushEntryList(&Zone->FreeList, (PSINGLE_LIST_ENTRY)Entry);
56
57 /* Go to the next entry */
58 Entry += Zone->BlockSize;
59 }
60
61 /* Update Segment Size */
62 Zone->TotalSegmentSize += i;
63
64 /* Return Success */
65 return STATUS_SUCCESS;
66 }
67
68
69 /*
70 * @implemented
71 */
72 NTSTATUS
73 STDCALL
74 ExInterlockedExtendZone(PZONE_HEADER Zone,
75 PVOID Segment,
76 ULONG SegmentSize,
77 PKSPIN_LOCK Lock)
78 {
79 NTSTATUS Status;
80 KIRQL OldIrql;
81
82 /* Get the lock */
83 KeAcquireSpinLock(Lock, &OldIrql);
84
85 /* Extend the Zone */
86 Status = ExExtendZone(Zone, Segment, SegmentSize);
87
88 /* Release lock and return status */
89 KeReleaseSpinLock(Lock, OldIrql);
90 return Status;
91 }
92
93
94 /*
95 * FUNCTION: Initalizes a zone header
96 * ARGUMENTS:
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
100 * caller
101 * InitialSegmentSize = Initial size of the segment
102 *
103 * @implemented
104 */
105 NTSTATUS
106 STDCALL
107 ExInitializeZone(PZONE_HEADER Zone,
108 ULONG BlockSize,
109 PVOID InitialSegment,
110 ULONG InitialSegmentSize)
111 {
112 ULONG i;
113 ULONG_PTR Entry;
114
115 /*
116 * BlockSize and Segment must be 8-byte aligned.
117 * Blocksize cannot exceed Segment Size.
118 */
119 if (((ULONG_PTR)InitialSegment & 7) ||
120 (InitialSegmentSize & 7) ||
121 (BlockSize > InitialSegmentSize))
122 {
123 DPRINT1("Invalid ExInitializeZone Alignment and/or Size\n");
124 return STATUS_INVALID_PARAMETER;
125 }
126
127 /* Set the Zone Header */
128 Zone->BlockSize = BlockSize;
129
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;
135
136 /* Get first entry */
137 Entry = (ULONG_PTR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
138
139 /* Loop through the segments */
140 for (i = sizeof(ZONE_SEGMENT_HEADER);
141 i <= InitialSegmentSize - BlockSize;
142 i+= BlockSize)
143 {
144 /* Link the Free and Segment Lists */
145 PushEntryList(&Zone->FreeList, (PSINGLE_LIST_ENTRY)Entry);
146
147 /* Go to the next entry */
148 Entry += Zone->BlockSize;
149 }
150
151 /* Update Segment Size */
152 Zone->TotalSegmentSize += i;
153
154 /* Return success */
155 return STATUS_SUCCESS;
156 }
157
158 /* EOF */