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.

175 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. cache.h
  5. Abstract:
  6. This module contains declarations for a simple cache system.
  7. Cache entries are stored as void pointers with 2 32-bit keys.
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 19-Feb-1998
  10. Revision History:
  11. rajeshd : 17-Sep-1999 : Modified the cache parameters.
  12. Notes:
  13. This code is copied from the NAT's implementation of cache and modified to accept
  14. two cache keys.
  15. --*/
  16. #ifndef _CACHE_H_
  17. #define _CACHE_H_
  18. #define CACHE_SHIFT 0
  19. #define CACHE_SIZE (1 << (8 - CACHE_SHIFT))
  20. #define CACHE_INDEX(k1,k2) (((unsigned char)(k1) & (0xF)) | (((unsigned char)(k2) & (0xF)) << 4))
  21. typedef struct _CACHE_ENTRY {
  22. unsigned long Key1;
  23. unsigned long Key2;
  24. void* Value;
  25. long Hits;
  26. long Misses;
  27. } CACHE_ENTRY, *PCACHE_ENTRY;
  28. __inline
  29. void
  30. InitializeCache(
  31. CACHE_ENTRY Cache[]
  32. )
  33. {
  34. memset(Cache, 0, CACHE_SIZE * sizeof(CACHE_ENTRY));
  35. TRACE2("ipfltdrv: CacheSize=%d, CacheEntry=%d\n", CACHE_SIZE, sizeof(CACHE_ENTRY));
  36. }
  37. __inline
  38. void
  39. CleanCache(
  40. CACHE_ENTRY Cache[],
  41. unsigned long Key1,
  42. unsigned long Key2
  43. )
  44. {
  45. long Index = CACHE_INDEX(Key1, Key2);
  46. TRACE3("ipfltdrv: Clearing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  47. Cache[Index].Key1 = 0;
  48. Cache[Index].Key2 = 0;
  49. Cache[Index].Value = 0;
  50. Cache[Index].Hits = 0;
  51. Cache[Index].Misses = 0;
  52. }
  53. __inline
  54. void*
  55. ProbeCache(
  56. CACHE_ENTRY Cache[],
  57. unsigned long Key1,
  58. unsigned long Key2
  59. )
  60. {
  61. long Index = CACHE_INDEX(Key1, Key2);
  62. //TRACE3("ipfltdrv: Probing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  63. if ((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) {
  64. Cache[Index].Hits++;
  65. //TRACE1("ipfltdrv: Probing Cache, Found Value=%8x\n", Cache[Index].Value);
  66. return Cache[Index].Value;
  67. }
  68. Cache[Index].Misses++;
  69. return NULL;
  70. }
  71. __inline
  72. int
  73. UpdateCache(
  74. CACHE_ENTRY Cache[],
  75. unsigned long Key1,
  76. unsigned long Key2,
  77. void* Value
  78. )
  79. {
  80. long Index = CACHE_INDEX(Key1, Key2);
  81. TRACE3("ipfltdrv: Updating Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  82. if (((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) ||
  83. Cache[Index].Hits >=
  84. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  85. Cache[Index].Key1 = Key1;
  86. Cache[Index].Key2 = Key2;
  87. Cache[Index].Value = Value;
  88. Cache[Index].Hits = 0;
  89. Cache[Index].Misses = 0;
  90. return 1;
  91. }
  92. __inline
  93. void
  94. InterlockedCleanCache(
  95. CACHE_ENTRY Cache[],
  96. unsigned long Key1,
  97. unsigned long Key2
  98. )
  99. {
  100. long Index = CACHE_INDEX(Key1, Key2);
  101. TRACE3("ipfltdrv: ILocked Clearing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  102. InterlockedExchange(&Cache[Index].Key1, 0);
  103. InterlockedExchange(&Cache[Index].Key2, 0);
  104. InterlockedExchangePointer(&Cache[Index].Value, 0);
  105. InterlockedExchange(&Cache[Index].Hits, 0);
  106. InterlockedExchange(&Cache[Index].Misses, 0);
  107. }
  108. __inline
  109. void*
  110. InterlockedProbeCache(
  111. CACHE_ENTRY Cache[],
  112. unsigned long Key1,
  113. unsigned long Key2
  114. )
  115. {
  116. long Index = CACHE_INDEX(Key1, Key2);
  117. //TRACE3("ipfltdrv: ILocked Probing Cache at Index=%d, Key1=%d, Key2=%d\n", Index, Key1, Key2);
  118. if ((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) {
  119. InterlockedIncrement(&Cache[Index].Hits);
  120. //TRACE1("ipfltdrv: ILocked Probing Cache, Found Value=%8x\n", Cache[Index].Value);
  121. return Cache[Index].Value;
  122. }
  123. InterlockedIncrement(&Cache[Index].Misses);
  124. return NULL;
  125. }
  126. __inline
  127. int
  128. InterlockedUpdateCache(
  129. CACHE_ENTRY Cache[],
  130. unsigned long Key1,
  131. unsigned long Key2,
  132. void* Value
  133. )
  134. {
  135. long Index = CACHE_INDEX(Key1, Key2);
  136. TRACE4("ipfltdrv: ILocked Updating Cache at Index=%d, Key1=%d, Key2=%d, Value=%08x\n", Index, Key1, Key2, Value);
  137. if (((Key1 == Cache[Index].Key1) && (Key2 == Cache[Index].Key2)) ||
  138. Cache[Index].Hits >=
  139. (Cache[Index].Misses - (Cache[Index].Misses >> 2))) { return 0; }
  140. InterlockedExchange(&Cache[Index].Key1, Key1);
  141. InterlockedExchange(&Cache[Index].Key2, Key2);
  142. InterlockedExchangePointer(&Cache[Index].Value, Value);
  143. InterlockedExchange(&Cache[Index].Hits, 0);
  144. InterlockedExchange(&Cache[Index].Misses, 0);
  145. return 1;
  146. }
  147. #endif // _CACHE_H_