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

region.h File Reference

Go to the source code of this file.

Classes

struct  _REGION_SEGMENT_HEADER
struct  _REGION_HEADER

Defines

#define ExInterlockedAllocateFromRegion(Region, Lock)   (PVOID)ExInterlockedPopEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, Lock)
#define ExInterlockedFreeToRegion(Region, Block, Lock)   ExInterlockedPushEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, ((PSINGLE_LIST_ENTRY)(Block)), Lock)
#define ExIsFullRegion(Region)   ((Region)->ListHead.Next == (PSINGLE_LIST_ENTRY)NULL)
#define ExIsObjectInFirstRegionSegment(Region, Object)

Typedefs

typedef _REGION_SEGMENT_HEADER REGION_SEGMENT_HEADER
typedef _REGION_SEGMENT_HEADERPREGION_SEGMENT_HEADER
typedef _REGION_HEADER REGION_HEADER
typedef _REGION_HEADERPREGION_HEADER

Functions

NTKERNELAPI VOID ExInitializeRegion (IN PREGION_HEADER Region, IN ULONG BlockSize, IN PVOID Segment, IN ULONG SegmentSize)
NTKERNELAPI VOID ExInterlockedExtendRegion (IN PREGION_HEADER Region, IN PVOID Segment, IN ULONG SegmentSize, IN PKSPIN_LOCK Lock)


Define Documentation

#define ExInterlockedAllocateFromRegion Region,
Lock   )     (PVOID)ExInterlockedPopEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, Lock)
 

Definition at line 70 of file region.h.

#define ExInterlockedFreeToRegion Region,
Block,
Lock   )     ExInterlockedPushEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, ((PSINGLE_LIST_ENTRY)(Block)), Lock)
 

Definition at line 113 of file region.h.

#define ExIsFullRegion Region   )     ((Region)->ListHead.Next == (PSINGLE_LIST_ENTRY)NULL)
 

Definition at line 140 of file region.h.

#define ExIsObjectInFirstRegionSegment Region,
Object   ) 
 

Value:

((BOOLEAN) \ (((PUCHAR)(Object) >= ((PUCHAR)((Region)->FirstSegment) + sizeof(REGION_SEGMENT_HEADER))) && \ ((PUCHAR)(Object) < ((PUCHAR)((Region)->FirstSegment) + (Region)->TotalSize + sizeof(REGION_SEGMENT_HEADER)))))

Definition at line 168 of file region.h.


Typedef Documentation

typedef struct _REGION_HEADER * PREGION_HEADER
 

Referenced by ExInitializeRegion().

typedef struct _REGION_SEGMENT_HEADER * PREGION_SEGMENT_HEADER
 

Referenced by ExInitializeRegion().

typedef struct _REGION_HEADER REGION_HEADER
 

typedef struct _REGION_SEGMENT_HEADER REGION_SEGMENT_HEADER
 

Referenced by ExInitializeRegion().


Function Documentation

NTKERNELAPI VOID ExInitializeRegion IN PREGION_HEADER  Region,
IN ULONG  BlockSize,
IN PVOID  Segment,
IN ULONG  SegmentSize
 

Definition at line 24 of file ex/region.c.

References BlockSize, ExInitializeSListHead, KeBugCheckEx(), MmQuerySystemSize(), MmSmallSystem, NULL, PAGE_SIZE, PREGION_HEADER, PREGION_SEGMENT_HEADER, and REGION_SEGMENT_HEADER.

00033 : 00034 00035 This function initializes a region header. 00036 00037 Arguments: 00038 00039 Region - Supplies the address of a region header to initialize. 00040 00041 BlockSize - Supplies the block size of the allocatable units within 00042 the region. The size must be larger that the size of the initial 00043 segment, and must be 64-bit aligned. 00044 00045 Segment - Supplies the address of a segment of storage. 00046 00047 SegmentSize - Supplies the size in bytes of the segment. 00048 00049 Return Value: 00050 00051 None. 00052 00053 --*/ 00054 00055 { 00056 00057 SINGLE_LIST_ENTRY FirstEntry; 00058 PSINGLE_LIST_ENTRY LastEntry; 00059 PSINGLE_LIST_ENTRY NextEntry; 00060 ULONG TotalSize; 00061 00062 // 00063 // If the host system is a small system and the segment size is greater 00064 // than two pages, then bugcheck. 00065 // 00066 00067 if ((MmQuerySystemSize() == MmSmallSystem) && (SegmentSize > (2 * PAGE_SIZE))) { 00068 KeBugCheckEx(NO_PAGES_AVAILABLE, 0x123, SegmentSize, 0, 0); 00069 } 00070 00071 // 00072 // If the segment address is not quadword aligned, or the block size is 00073 // greater than the segment size minus size of the segment header, then 00074 // the region is not valid - bugcheck. 00075 // 00076 00077 if ((((ULONG)Segment & 7) != 0) || 00078 ((BlockSize & 7) != 0) || 00079 (BlockSize > (SegmentSize - sizeof(REGION_SEGMENT_HEADER)))) { 00080 KeBugCheckEx(INVALID_REGION_OR_SEGMENT, (ULONG)Segment, SegmentSize, BlockSize, 0); 00081 } 00082 00083 // 00084 // Initialize the region header. 00085 // 00086 00087 ExInitializeSListHead(&Region->ListHead); 00088 Region->FirstSegment = (PREGION_SEGMENT_HEADER)Segment; 00089 Region->BlockSize = BlockSize; 00090 TotalSize = ((SegmentSize - sizeof(REGION_SEGMENT_HEADER)) / BlockSize) * BlockSize; 00091 Region->TotalSize = TotalSize; 00092 00093 // 00094 // Initialize the segment free list. 00095 // 00096 00097 FirstEntry.Next = NULL; 00098 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment + sizeof(REGION_SEGMENT_HEADER)); 00099 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + TotalSize); 00100 do { 00101 NextEntry->Next = FirstEntry.Next; 00102 FirstEntry.Next = NextEntry; 00103 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + BlockSize); 00104 } while (NextEntry != LastEntry); 00105 Region->ListHead.Next.Next = FirstEntry.Next; 00106 return; 00107 }

NTKERNELAPI VOID ExInterlockedExtendRegion IN PREGION_HEADER  Region,
IN PVOID  Segment,
IN ULONG  SegmentSize,
IN PKSPIN_LOCK  Lock
 

Definition at line 110 of file ex/region.c.

References BlockSize, KeBugCheckEx(), Lock, and NULL.

00119 : 00120 00121 This function extends a region by adding another segment's worth of 00122 blocks to the region. 00123 00124 Arguments: 00125 00126 Region - Supplies the address of a region header. 00127 00128 Segment - Supplies the address of a segment of storage. 00129 00130 SegmentSize - Supplies the size in bytes of Segment. 00131 00132 Lock - Supplies the address of a spinlock. 00133 00134 Return Value: 00135 00136 None. 00137 00138 --*/ 00139 00140 { 00141 00142 ULONG BlockSize; 00143 SINGLE_LIST_ENTRY FirstEntry; 00144 KIRQL OldIrql; 00145 PSINGLE_LIST_ENTRY LastEntry; 00146 PSINGLE_LIST_ENTRY NextEntry; 00147 ULONG TotalSize; 00148 00149 // 00150 // If the segment address is not quadword aligned, or the block size is 00151 // greater than the segment size minus size of the segment header, then 00152 // the region is not valid. 00153 // 00154 00155 BlockSize = Region->BlockSize; 00156 if ((((ULONG)Segment & 7) != 0) || 00157 ((BlockSize & 7) != 0) || 00158 (BlockSize > (SegmentSize - sizeof(REGION_SEGMENT_HEADER)))) { 00159 KeBugCheckEx(INVALID_REGION_OR_SEGMENT, (ULONG)Segment, SegmentSize, BlockSize, 0); 00160 } 00161 00162 // 00163 // Initialize the segment free list. 00164 // 00165 00166 TotalSize = ((SegmentSize - sizeof(REGION_SEGMENT_HEADER)) / BlockSize) * BlockSize; 00167 FirstEntry.Next = NULL; 00168 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment + sizeof(REGION_SEGMENT_HEADER)); 00169 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + TotalSize); 00170 do { 00171 NextEntry->Next = FirstEntry.Next; 00172 FirstEntry.Next = NextEntry; 00173 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + BlockSize); 00174 } while (NextEntry != LastEntry); 00175 00176 // 00177 // Acquire the specified spinlock, insert the next segment in the segment 00178 // list, update the total segment size, and carefully merge the new segment 00179 // list with the current list. 00180 // 00181 // N.B. The merging of the free list is done very carefully such that 00182 // manipulation of the free list can occur without using spinlocks. 00183 // 00184 00185 ExAcquireSpinLock(Lock, &OldIrql); 00186 ((PREGION_SEGMENT_HEADER)Segment)->NextSegment = Region->FirstSegment; 00187 Region->FirstSegment = (PREGION_SEGMENT_HEADER)Segment; 00188 Region->TotalSize += TotalSize; 00189 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment + sizeof(REGION_SEGMENT_HEADER)); 00190 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)LastEntry - Region->BlockSize); 00191 do { 00192 00193 // 00194 // The next entry in the region list head is a volatile entry and, 00195 // therefore, is read each time through the loop. 00196 // 00197 00198 FirstEntry.Next = Region->ListHead.Next.Next; 00199 00200 // 00201 // The last entry in the new segment list, i.e., the one with a link 00202 // of NULL, is merged with the current list by storing the captured 00203 // region next link in the free entry. A compare and exchange is then 00204 // done using the merged link address as the comparand and the head 00205 // of the new free list as the exchange value. This is safe since it 00206 // does not matter if the next link of the first region entry changes. 00207 // 00208 00209 NextEntry->Next = FirstEntry.Next; 00210 } while (InterlockedCompareExchange((PVOID)&Region->ListHead.Next, 00211 LastEntry, 00212 FirstEntry.Next) != FirstEntry.Next); 00213 00214 ExReleaseSpinLock(Lock, OldIrql); 00215 return; 00216 } }


Generated on Sat May 15 19:45:27 2004 for test by doxygen 1.3.7