Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

zone.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 zone.c 00008 00009 Abstract: 00010 00011 This module implements a simple zone buffer manager. The primary 00012 consumer of this module is local LPC. 00013 00014 The zone package provides a fast and efficient memory allocator for 00015 fixed-size 64-bit aligned blocks of storage. The zone package does 00016 not provide any serialization over access to the zone header and 00017 associated free list and segment list. It is the responsibility of 00018 the caller to provide any necessary serialization. 00019 00020 The zone package views a zone as a set of fixed-size blocks of 00021 storage. The block size of a zone is specified during zone 00022 initialization. Storage is assigned to a zone during zone 00023 initialization and when a zone is extended. In both of these cases, 00024 a segment and length are specified. 00025 00026 The zone package uses the first ZONE_SEGMENT_HEADER portion of the 00027 segment for zone overhead. The remainder of the segment is carved 00028 up into fixed-size blocks and each block is added to the free list 00029 maintained in the zone header. 00030 00031 As long as a block is on the free list, the first SINGLE_LIST_ENTRY 00032 (32 bit) sized piece of the block is used as zone overhead. The 00033 rest of the block is not used by the zone package and may be used by 00034 applications to cache information. When a block is not on the free 00035 list, its entire contents are available to the application. 00036 00037 Author: 00038 00039 Mark Lucovsky (markl) 13-May-1989 00040 00041 Revision History: 00042 00043 --*/ 00044 00045 #include "exp.h" 00046 00047 NTSTATUS 00048 ExInitializeZone( 00049 IN PZONE_HEADER Zone, 00050 IN ULONG BlockSize, 00051 IN PVOID InitialSegment, 00052 IN ULONG InitialSegmentSize 00053 ) 00054 00055 /*++ 00056 00057 Routine Description: 00058 00059 This function initializes a zone header. Once successfully 00060 initialized, blocks can be allocated and freed from the zone, and 00061 the zone can be extended. 00062 00063 Arguments: 00064 00065 Zone - Supplies the address of a zone header to be initialized. 00066 00067 BlockSize - Supplies the block size of the allocatable unit within 00068 the zone. The size must be larger that the size of the 00069 initial segment, and must be 64-bit aligned. 00070 00071 InitialSegment - Supplies the address of a segment of storage. The 00072 first ZONE_SEGMENT_HEADER-sized portion of the segment 00073 is used by the zone allocator. The remainder of 00074 the segment is carved up into fixed size 00075 (BlockSize) blocks and is made available for 00076 allocation and deallocation from the zone. The 00077 address of the segment must be aligned on a 64-bit 00078 boundary. 00079 00080 InitialSegmentSize - Supplies the size in bytes of the InitialSegment. 00081 00082 Return Value: 00083 00084 STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on 00085 64-bit boundaries, or BlockSize was larger than 00086 the initial segment size. 00087 00088 STATUS_SUCCESS - The zone was successfully initialized. 00089 00090 --*/ 00091 00092 { 00093 ULONG i; 00094 PCH p; 00095 00096 if ( (BlockSize & 7) || ((ULONG_PTR)InitialSegment & 7) || 00097 (BlockSize > InitialSegmentSize) ) { 00098 #if DBG 00099 DbgPrint( "EX: ExInitializeZone( %x, %x, %x, %x ) - Invalid parameters.\n", 00100 Zone, BlockSize, InitialSegment, InitialSegmentSize 00101 ); 00102 DbgBreakPoint(); 00103 #endif 00104 return STATUS_INVALID_PARAMETER; 00105 } 00106 00107 Zone->BlockSize = BlockSize; 00108 00109 Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList; 00110 ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL; 00111 ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL; 00112 00113 Zone->FreeList.Next = NULL; 00114 00115 p = (PCH)InitialSegment + sizeof(ZONE_SEGMENT_HEADER); 00116 00117 for (i = sizeof(ZONE_SEGMENT_HEADER); 00118 i <= InitialSegmentSize - BlockSize; 00119 i += BlockSize 00120 ) { 00121 ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next; 00122 Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p; 00123 p += BlockSize; 00124 } 00125 Zone->TotalSegmentSize = i; 00126 00127 #if 0 00128 DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n", 00129 Zone, InitialSegment, InitialSegmentSize, 00130 BlockSize, p 00131 ); 00132 #endif 00133 00134 return STATUS_SUCCESS; 00135 } 00136 00137 NTSTATUS 00138 ExExtendZone( 00139 IN PZONE_HEADER Zone, 00140 IN PVOID Segment, 00141 IN ULONG SegmentSize 00142 ) 00143 00144 /*++ 00145 00146 Routine Description: 00147 00148 This function extends a zone by adding another segment's worth of 00149 blocks to the zone. 00150 00151 Arguments: 00152 00153 Zone - Supplies the address of a zone header to be extended. 00154 00155 Segment - Supplies the address of a segment of storage. The first 00156 ZONE_SEGMENT_HEADER-sized portion of the segment is used by the 00157 zone allocator. The remainder of the segment is carved up 00158 into fixed-size (BlockSize) blocks and is added to the 00159 zone. The address of the segment must be aligned on a 64- 00160 bit boundary. 00161 00162 SegmentSize - Supplies the size in bytes of Segment. 00163 00164 Return Value: 00165 00166 STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on 00167 64-bit boundaries, or BlockSize was larger than 00168 the segment size. 00169 00170 STATUS_SUCCESS - The zone was successfully extended. 00171 00172 --*/ 00173 00174 { 00175 ULONG i; 00176 PCH p; 00177 00178 if ( ((ULONG_PTR)Segment & 7) || 00179 (SegmentSize & 7) || 00180 (Zone->BlockSize > SegmentSize) ) { 00181 return STATUS_UNSUCCESSFUL; 00182 } 00183 00184 ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next; 00185 Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList; 00186 00187 p = (PCH)Segment + sizeof(ZONE_SEGMENT_HEADER); 00188 00189 for (i = sizeof(ZONE_SEGMENT_HEADER); 00190 i <= SegmentSize - Zone->BlockSize; 00191 i += Zone->BlockSize 00192 ) { 00193 00194 ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next; 00195 Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p; 00196 p += Zone->BlockSize; 00197 } 00198 Zone->TotalSegmentSize += i; 00199 00200 #if 0 00201 DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n", 00202 Zone, Segment, SegmentSize, Zone->BlockSize, p 00203 ); 00204 #endif 00205 00206 return STATUS_SUCCESS; 00207 } 00208 00209 00210 00211 NTSTATUS 00212 ExInterlockedExtendZone( 00213 IN PZONE_HEADER Zone, 00214 IN PVOID Segment, 00215 IN ULONG SegmentSize, 00216 IN PKSPIN_LOCK Lock 00217 ) 00218 00219 /*++ 00220 00221 Routine Description: 00222 00223 This function extends a zone by adding another segment's worth of 00224 blocks to the zone. 00225 00226 Arguments: 00227 00228 Zone - Supplies the address of a zone header to be extended. 00229 00230 Segment - Supplies the address of a segment of storage. The first 00231 ZONE_SEGMENT_HEADER-sized portion of the segment is used by the 00232 zone allocator. The remainder of the segment is carved up 00233 into fixed-size (BlockSize) blocks and is added to the 00234 zone. The address of the segment must be aligned on a 64- 00235 bit boundary. 00236 00237 SegmentSize - Supplies the size in bytes of Segment. 00238 00239 Lock - pointer to spinlock to use 00240 00241 Return Value: 00242 00243 STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on 00244 64-bit boundaries, or BlockSize was larger than 00245 the segment size. 00246 00247 STATUS_SUCCESS - The zone was successfully extended. 00248 00249 --*/ 00250 00251 { 00252 NTSTATUS Status; 00253 KIRQL OldIrql; 00254 00255 ExAcquireSpinLock( Lock, &OldIrql ); 00256 00257 Status = ExExtendZone( Zone, Segment, SegmentSize ); 00258 00259 ExReleaseSpinLock( Lock, OldIrql ); 00260 00261 return Status; 00262 }

Generated on Sat May 15 19:42:33 2004 for test by doxygen 1.3.7