Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. range.h
  5. Abstract:
  6. Kernel-mode range list support for arbiters
  7. Author:
  8. Andy Thornton (andrewth) 02/17/97
  9. Revision History:
  10. --*/
  11. #ifndef _RANGE_
  12. #define _RANGE_
  13. //
  14. // Debugging options
  15. //
  16. #if DBG && !defined(NTOS_KERNEL_RUNTIME)
  17. #include <stdio.h>
  18. #endif
  19. #undef MAX_ULONGLONG
  20. #define MAX_ULONGLONG ((ULONGLONG)-1)
  21. #define RTL_RANGE_LIST_ENTRY_TAG 'elRR'
  22. #define RTL_RANGE_LIST_MISC_TAG 'mlRR'
  23. #if DBG
  24. #define DEBUG_PRINT(Level, Message) \
  25. if (Level <= RtlRangeDebugLevel) DbgPrint Message
  26. #else
  27. #define DEBUG_PRINT(Level, Message)
  28. #endif // DBG
  29. //
  30. // Range list structures
  31. //
  32. #define RTLP_RANGE_LIST_ENTRY_MERGED 0x0001
  33. typedef struct _RTLP_RANGE_LIST_ENTRY {
  34. //
  35. // Common data
  36. //
  37. ULONGLONG Start;
  38. ULONGLONG End;
  39. union {
  40. //
  41. // An Allocated range
  42. //
  43. struct {
  44. //
  45. // Data from the user given in AddRange
  46. //
  47. PVOID UserData;
  48. //
  49. // The owner of the range
  50. //
  51. PVOID Owner;
  52. } Allocated;
  53. //
  54. // A Merged range
  55. //
  56. struct {
  57. //
  58. // List of ranges that overlap between Start and End
  59. //
  60. LIST_ENTRY ListHead;
  61. } Merged;
  62. };
  63. //
  64. // User defined flags given in AddRange
  65. //
  66. UCHAR Attributes;
  67. //
  68. // Range descriptors
  69. //
  70. UCHAR PublicFlags; // use RANGE_*
  71. //
  72. // Control information
  73. //
  74. USHORT PrivateFlags; // use RANGE_LIST_ENTRY_*
  75. //
  76. // Main linked list entry
  77. //
  78. LIST_ENTRY ListEntry;
  79. } RTLP_RANGE_LIST_ENTRY, *PRTLP_RANGE_LIST_ENTRY;
  80. //
  81. // Useful macros for dealing with range list entries
  82. //
  83. #define MERGED(Entry) (BOOLEAN)((Entry)->PrivateFlags & RTLP_RANGE_LIST_ENTRY_MERGED)
  84. #define SHARED(Entry) (BOOLEAN)((Entry)->PublicFlags & RTL_RANGE_SHARED)
  85. #define CONFLICT(Entry) (BOOLEAN)((Entry)->PublicFlags & RTL_RANGE_CONFLICT)
  86. //
  87. // List Traversing Macros
  88. //
  89. #define FOR_ALL_IN_LIST(Type, Head, Current) \
  90. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
  91. (Head) != &(Current)->ListEntry; \
  92. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  93. Type, \
  94. ListEntry) \
  95. )
  96. #define FOR_ALL_IN_LIST_SAFE(Type, Head, Current, Next) \
  97. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry), \
  98. (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  99. Type, ListEntry); \
  100. (Head) != &(Current)->ListEntry; \
  101. (Current) = (Next), \
  102. (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  103. Type, ListEntry) \
  104. )
  105. #define FOR_REST_IN_LIST(Type, Head, Current) \
  106. for(; \
  107. (Head) != &(Current)->ListEntry; \
  108. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  109. Type, \
  110. ListEntry) \
  111. )
  112. #define FOR_REST_IN_LIST_SAFE(Type, Head, Current, Next) \
  113. for((Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  114. Type, ListEntry); \
  115. (Head) != &(Current)->ListEntry; \
  116. (Current) = (Next), \
  117. (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  118. Type, ListEntry) \
  119. )
  120. //
  121. // Backwards List Traversing Macros
  122. //
  123. #define FOR_ALL_IN_LIST_BACKWARDS(Type, Head, Current) \
  124. for((Current) = CONTAINING_RECORD((Head)->Blink, Type, ListEntry); \
  125. (Head) != &(Current)->ListEntry; \
  126. (Current) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  127. Type, \
  128. ListEntry) \
  129. )
  130. #define FOR_ALL_IN_LIST_SAFE_BACKWARDS(Type, Head, Current, Next) \
  131. for((Current) = CONTAINING_RECORD((Head)->Blink, Type, ListEntry), \
  132. (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  133. Type, ListEntry); \
  134. (Head) != &(Current)->ListEntry; \
  135. (Current) = (Next), \
  136. (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  137. Type, ListEntry) \
  138. )
  139. #define FOR_REST_IN_LIST_BACKWARDS(Type, Head, Current) \
  140. for(; \
  141. (Head) != &(Current)->ListEntry; \
  142. (Current) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  143. Type, \
  144. ListEntry) \
  145. )
  146. #define FOR_REST_IN_LIST_SAFE_BACKWARDS(Type, Head, Current, Next) \
  147. for((Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  148. Type, ListEntry); \
  149. (Head) != &(Current)->ListEntry; \
  150. (Current) = (Next), \
  151. (Next) = CONTAINING_RECORD((Current)->ListEntry.Blink, \
  152. Type, ListEntry) \
  153. )
  154. //
  155. // Misc Macros
  156. //
  157. #define LAST_IN_LIST(ListHead, Entry) \
  158. ( (Entry)->ListEntry.Flink == ListHead )
  159. #define FIRST_IN_LIST(ListHead, Entry) \
  160. ( (Entry)->ListEntry.Blink == ListHead )
  161. #define RANGE_DISJOINT(a,b) \
  162. ( ((a)->Start < (b)->Start && (a)->End < (b)->Start) \
  163. ||((b)->Start < (a)->Start && (b)->End < (a)->Start) )
  164. #define RANGE_INTERSECT(a,b) \
  165. !RANGE_DISJOINT((a),(b))
  166. #define RANGE_LIMITS_DISJOINT(s1,e1,s2,e2) \
  167. ( ((s1) < (s2) && (e1) < (s2)) \
  168. ||((s2) < (s1) && (e2) < (s1)) )
  169. #define RANGE_LIMITS_INTERSECT(s1,e1,s2,e2) \
  170. !RANGE_LIMITS_DISJOINT((s1),(e1),(s2),(e2))
  171. #define RANGE_LIST_ENTRY_FROM_LIST_ENTRY(Entry) \
  172. CONTAINING_RECORD((Entry), RTLP_RANGE_LIST_ENTRY, ListEntry)
  173. #define RANGE_LIST_FROM_LIST_HEAD(Head) \
  174. CONTAINING_RECORD((Head), RTL_RANGE_LIST, ListHead)
  175. #define FOR_REST_OF_RANGES(_Iterator, _Current, _Forward) \
  176. for ((_Current) = (PRTL_RANGE)(_Iterator)->Current; \
  177. (_Current) != NULL; \
  178. RtlGetNextRange((_Iterator), &(_Current), (_Forward)) \
  179. )
  180. //
  181. // VOID
  182. // InsertEntryList(
  183. // PLIST_ENTRY Previous,
  184. // PLIST_ENTRY Entry
  185. // );
  186. //
  187. #define InsertEntryList(Previous, Entry) { \
  188. PLIST_ENTRY _EX_Next = (Previous)->Flink; \
  189. PLIST_ENTRY _EX_Previous = (Previous); \
  190. (Entry)->Flink = _EX_Next; \
  191. (Entry)->Blink = _EX_Previous; \
  192. _EX_Next->Blink = (Entry); \
  193. _EX_Previous->Flink = (Entry); \
  194. }
  195. #endif