windows-nt/Source/XPSP1/NT/base/ntos/rtl/range.h
2020-09-26 16:20:57 +08:00

261 lines
8.3 KiB
C

/*++
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 <stdio.h>
#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