261 lines
7.9 KiB
C
261 lines
7.9 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
|