/*++ Copyright (c) 1997 Microsoft Corporation Module Name: range.h Abstract: Kernel-mode range list support for arbiters Author: Andy Thornton (andrewth) 02/17/97 Revision History: --*/ #ifndef _RANGE_ #define _RANGE_ // // Debugging options // #if DBG && !defined(NTOS_KERNEL_RUNTIME) #include #endif #undef MAX_ULONGLONG #define MAX_ULONGLONG ((ULONGLONG)-1) #define RTL_RANGE_LIST_ENTRY_TAG 'elRR' #define RTL_RANGE_LIST_MISC_TAG 'mlRR' #if DBG #define DEBUG_PRINT(Level, Message) \ if (Level <= RtlRangeDebugLevel) DbgPrint Message #else #define DEBUG_PRINT(Level, Message) #endif // DBG // // Range list structures // #define RTLP_RANGE_LIST_ENTRY_MERGED 0x0001 typedef struct _RTLP_RANGE_LIST_ENTRY { // // Common data // ULONGLONG Start; ULONGLONG End; union { // // An Allocated range // struct { // // Data from the user given in AddRange // PVOID UserData; // // The owner of the range // PVOID Owner; } Allocated; // // A Merged range // struct { // // List of ranges that overlap between Start and End // LIST_ENTRY ListHead; } Merged; }; // // User defined flags given in AddRange // UCHAR Attributes; // // Range descriptors // UCHAR PublicFlags; // use RANGE_* // // Control information // USHORT PrivateFlags; // use RANGE_LIST_ENTRY_* // // Main linked list entry // LIST_ENTRY ListEntry; } RTLP_RANGE_LIST_ENTRY, *PRTLP_RANGE_LIST_ENTRY; // // Useful macros for dealing with range list entries // #define MERGED(Entry) (BOOLEAN)((Entry)->PrivateFlags & RTLP_RANGE_LIST_ENTRY_MERGED) #define SHARED(Entry) (BOOLEAN)((Entry)->PublicFlags & RTL_RANGE_SHARED) #define CONFLICT(Entry) (BOOLEAN)((Entry)->PublicFlags & RTL_RANGE_CONFLICT) // // List Traversing Macros // #define FOR_ALL_IN_LIST(Type, Head, Current) \ for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, \ ListEntry) \ ) #define FOR_ALL_IN_LIST_SAFE(Type, Head, Current, Next) \ for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = (Next), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, ListEntry) \ ) #define FOR_REST_IN_LIST(Type, Head, Current) \ for(; \ (Head) != &(Current)->ListEntry; \ (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, \ ListEntry) \ ) #define FOR_REST_IN_LIST_SAFE(Type, Head, Current, Next) \ for((Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = (Next), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, ListEntry) \ ) // // Backwards List Traversing Macros // #define FOR_ALL_IN_LIST_BACKWARDS(Type, Head, Current) \ for((Current) = CONTAINING_RECORD((Head)->Blink, Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, \ ListEntry) \ ) #define FOR_ALL_IN_LIST_SAFE_BACKWARDS(Type, Head, Current, Next) \ for((Current) = CONTAINING_RECORD((Head)->Blink, Type, ListEntry), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = (Next), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, ListEntry) \ ) #define FOR_REST_IN_LIST_BACKWARDS(Type, Head, Current) \ for(; \ (Head) != &(Current)->ListEntry; \ (Current) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, \ ListEntry) \ ) #define FOR_REST_IN_LIST_SAFE_BACKWARDS(Type, Head, Current, Next) \ for((Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = (Next), \ (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \ Type, ListEntry) \ ) // // Misc Macros // #define LAST_IN_LIST(ListHead, Entry) \ ( (Entry)->ListEntry.Flink == ListHead ) #define FIRST_IN_LIST(ListHead, Entry) \ ( (Entry)->ListEntry.Blink == ListHead ) #define RANGE_DISJOINT(a,b) \ ( ((a)->Start < (b)->Start && (a)->End < (b)->Start) \ ||((b)->Start < (a)->Start && (b)->End < (a)->Start) ) #define RANGE_INTERSECT(a,b) \ !RANGE_DISJOINT((a),(b)) #define RANGE_LIMITS_DISJOINT(s1,e1,s2,e2) \ ( ((s1) < (s2) && (e1) < (s2)) \ ||((s2) < (s1) && (e2) < (s1)) ) #define RANGE_LIMITS_INTERSECT(s1,e1,s2,e2) \ !RANGE_LIMITS_DISJOINT((s1),(e1),(s2),(e2)) #define RANGE_LIST_ENTRY_FROM_LIST_ENTRY(Entry) \ CONTAINING_RECORD((Entry), RTLP_RANGE_LIST_ENTRY, ListEntry) #define RANGE_LIST_FROM_LIST_HEAD(Head) \ CONTAINING_RECORD((Head), RTL_RANGE_LIST, ListHead) #define FOR_REST_OF_RANGES(_Iterator, _Current, _Forward) \ for ((_Current) = (PRTL_RANGE)(_Iterator)->Current; \ (_Current) != NULL; \ RtlGetNextRange((_Iterator), &(_Current), (_Forward)) \ ) // // VOID // InsertEntryList( // PLIST_ENTRY Previous, // PLIST_ENTRY Entry // ); // #define InsertEntryList(Previous, Entry) { \ PLIST_ENTRY _EX_Next = (Previous)->Flink; \ PLIST_ENTRY _EX_Previous = (Previous); \ (Entry)->Flink = _EX_Next; \ (Entry)->Blink = _EX_Previous; \ _EX_Next->Blink = (Entry); \ _EX_Previous->Flink = (Entry); \ } #endif