ReactOS 0.4.16-dev-329-g9223134
blocklist.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for blocklist.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (CACHE)
 
PCACHE_BLOCK CacheInternalGetBlockPointer (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
PCACHE_BLOCK CacheInternalFindBlock (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
PCACHE_BLOCK CacheInternalAddBlockToCache (PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
 
BOOLEAN CacheInternalFreeBlock (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalCheckCacheSizeLimits (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalDumpBlockList (PCACHE_DRIVE CacheDrive)
 
VOID CacheInternalOptimizeBlockList (PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
 

Function Documentation

◆ CacheInternalAddBlockToCache()

PCACHE_BLOCK CacheInternalAddBlockToCache ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 91 of file blocklist.c.

92{
93 PCACHE_BLOCK CacheBlock = NULL;
94
95 TRACE("CacheInternalAddBlockToCache() BlockNumber = %d\n", BlockNumber);
96
97 // Check the size of the cache so we don't exceed our limits
99
100 // We will need to add the block to the
101 // drive's list of cached blocks. So allocate
102 // the block memory.
103 CacheBlock = FrLdrTempAlloc(sizeof(CACHE_BLOCK), TAG_CACHE_BLOCK);
104 if (CacheBlock == NULL)
105 {
106 return NULL;
107 }
108
109 // Now initialize the structure and
110 // allocate room for the block data
111 RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK));
112 CacheBlock->BlockNumber = BlockNumber;
113 CacheBlock->BlockData = FrLdrTempAlloc(CacheDrive->BlockSize * CacheDrive->BytesPerSector,
115 if (CacheBlock->BlockData ==NULL)
116 {
117 FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
118 return NULL;
119 }
120
121 // Now try to read in the block
122 if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer))
123 {
125 FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
126 return NULL;
127 }
128 RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
129
130 // Add it to our list of blocks managed by the cache
131 InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
132
133 // Update the cache data
135 CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
136
137 CacheInternalDumpBlockList(CacheDrive);
138
139 return CacheBlock;
140}
VOID CacheInternalCheckCacheSizeLimits(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:177
VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:194
#define DiskReadBuffer
Definition: hardware.h:33
#define TAG_CACHE_DATA
Definition: cache.h:23
#define TAG_CACHE_BLOCK
Definition: cache.h:24
ULONG CacheBlockCount
Definition: cache.c:33
SIZE_T CacheSizeCurrent
Definition: cache.c:35
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:126
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
#define NULL
Definition: types.h:112
#define InsertTailList(ListHead, Entry)
#define TRACE(s)
Definition: solgame.cpp:4
LIST_ENTRY ListEntry
Definition: cache.h:37
ULONG BlockNumber
Definition: cache.h:39
PVOID BlockData
Definition: cache.h:43
ULONG BytesPerSector
Definition: cache.h:57
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
ULONG BlockSize
Definition: cache.h:59
UCHAR DriveNumber
Definition: cache.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by CacheInternalGetBlockPointer().

◆ CacheInternalCheckCacheSizeLimits()

VOID CacheInternalCheckCacheSizeLimits ( PCACHE_DRIVE  CacheDrive)

Definition at line 177 of file blocklist.c.

178{
179 SIZE_T NewCacheSize;
180
181 TRACE("CacheInternalCheckCacheSizeLimits()\n");
182
183 // Calculate the size of the cache if we added a block
184 NewCacheSize = (CacheBlockCount + 1) * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
185
186 // Check the new size against the cache size limit
187 if (NewCacheSize > CacheSizeLimit)
188 {
189 CacheInternalFreeBlock(CacheDrive);
190 CacheInternalDumpBlockList(CacheDrive);
191 }
192}
BOOLEAN CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:142
SIZE_T CacheSizeLimit
Definition: cache.c:34
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by CacheInternalAddBlockToCache().

◆ CacheInternalDumpBlockList()

VOID CacheInternalDumpBlockList ( PCACHE_DRIVE  CacheDrive)

Definition at line 194 of file blocklist.c.

195{
196 PCACHE_BLOCK CacheBlock;
197
198 TRACE("Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber);
199 TRACE("BytesPerSector: %d.\n", CacheDrive->BytesPerSector);
200 TRACE("BlockSize: %d.\n", CacheDrive->BlockSize);
201 TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit);
202 TRACE("CacheSizeCurrent: %d.\n", CacheSizeCurrent);
203 TRACE("CacheBlockCount: %d.\n", CacheBlockCount);
204
205 CacheBlock = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Flink, CACHE_BLOCK, ListEntry);
206 while (&CacheBlock->ListEntry != &CacheDrive->CacheBlockHead)
207 {
208 TRACE("Cache Block: CacheBlock: 0x%x\n", CacheBlock);
209 TRACE("Cache Block: Block Number: %d\n", CacheBlock->BlockNumber);
210 TRACE("Cache Block: Access Count: %d\n", CacheBlock->AccessCount);
211 TRACE("Cache Block: Block Data: 0x%x\n", CacheBlock->BlockData);
212 TRACE("Cache Block: Locked In Cache: %d\n", CacheBlock->LockedInCache);
213
214 if (CacheBlock->BlockData == NULL)
215 {
216 BugCheck("CacheBlock->BlockData == NULL\n");
217 }
218
219 CacheBlock = CONTAINING_RECORD(CacheBlock->ListEntry.Flink, CACHE_BLOCK, ListEntry);
220 }
221}
#define BugCheck(fmt,...)
Definition: debug.h:121
BOOLEAN LockedInCache
Definition: cache.h:40
ULONG AccessCount
Definition: cache.h:41
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by CacheInternalAddBlockToCache(), and CacheInternalCheckCacheSizeLimits().

◆ CacheInternalFindBlock()

PCACHE_BLOCK CacheInternalFindBlock ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 53 of file blocklist.c.

54{
55 PCACHE_BLOCK CacheBlock = NULL;
56
57 TRACE("CacheInternalFindBlock() BlockNumber = %d\n", BlockNumber);
58
59 //
60 // Make sure the block list has entries before I start searching it.
61 //
62 if (!IsListEmpty(&CacheDrive->CacheBlockHead))
63 {
64 //
65 // Search the list and find the BIOS drive number
66 //
67 CacheBlock = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Flink, CACHE_BLOCK, ListEntry);
68
69 while (&CacheBlock->ListEntry != &CacheDrive->CacheBlockHead)
70 {
71 //
72 // We found the block, so return it
73 //
74 if (CacheBlock->BlockNumber == BlockNumber)
75 {
76 //
77 // Increment the blocks access count
78 //
79 CacheBlock->AccessCount++;
80
81 return CacheBlock;
82 }
83
84 CacheBlock = CONTAINING_RECORD(CacheBlock->ListEntry.Flink, CACHE_BLOCK, ListEntry);
85 }
86 }
87
88 return NULL;
89}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954

Referenced by CacheInternalGetBlockPointer().

◆ CacheInternalFreeBlock()

BOOLEAN CacheInternalFreeBlock ( PCACHE_DRIVE  CacheDrive)

Definition at line 142 of file blocklist.c.

143{
144 PCACHE_BLOCK CacheBlockToFree;
145
146 TRACE("CacheInternalFreeBlock()\n");
147
148 // Get a pointer to the last item in the block list
149 // that isn't forced to be in the cache and remove
150 // it from the list
151 CacheBlockToFree = CONTAINING_RECORD(CacheDrive->CacheBlockHead.Blink, CACHE_BLOCK, ListEntry);
152 while (&CacheBlockToFree->ListEntry != &CacheDrive->CacheBlockHead && CacheBlockToFree->LockedInCache)
153 {
154 CacheBlockToFree = CONTAINING_RECORD(CacheBlockToFree->ListEntry.Blink, CACHE_BLOCK, ListEntry);
155 }
156
157 // No blocks left in cache that can be freed
158 // so just return
159 if (IsListEmpty(&CacheDrive->CacheBlockHead))
160 {
161 return FALSE;
162 }
163
164 RemoveEntryList(&CacheBlockToFree->ListEntry);
165
166 // Free the block memory and the block structure
167 FrLdrTempFree(CacheBlockToFree->BlockData, TAG_CACHE_DATA);
168 FrLdrTempFree(CacheBlockToFree, TAG_CACHE_BLOCK);
169
170 // Update the cache data
172 CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
173
174 return TRUE;
175}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by CacheInternalCheckCacheSizeLimits(), and CacheReleaseMemory().

◆ CacheInternalGetBlockPointer()

PCACHE_BLOCK CacheInternalGetBlockPointer ( PCACHE_DRIVE  CacheDrive,
ULONG  BlockNumber 
)

Definition at line 28 of file blocklist.c.

29{
30 PCACHE_BLOCK CacheBlock = NULL;
31
32 TRACE("CacheInternalGetBlockPointer() BlockNumber = %d\n", BlockNumber);
33
34 CacheBlock = CacheInternalFindBlock(CacheDrive, BlockNumber);
35
36 if (CacheBlock != NULL)
37 {
38 TRACE("Cache hit! BlockNumber: %d CacheBlock->BlockNumber: %d\n", BlockNumber, CacheBlock->BlockNumber);
39
40 return CacheBlock;
41 }
42
43 TRACE("Cache miss! BlockNumber: %d\n", BlockNumber);
44
45 CacheBlock = CacheInternalAddBlockToCache(CacheDrive, BlockNumber);
46
47 // Optimize the block list so it has a LRU structure
48 CacheInternalOptimizeBlockList(CacheDrive, CacheBlock);
49
50 return CacheBlock;
51}
PCACHE_BLOCK CacheInternalFindBlock(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
Definition: blocklist.c:53
PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
Definition: blocklist.c:91
VOID CacheInternalOptimizeBlockList(PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
Definition: blocklist.c:223

Referenced by CacheReadDiskSectors().

◆ CacheInternalOptimizeBlockList()

VOID CacheInternalOptimizeBlockList ( PCACHE_DRIVE  CacheDrive,
PCACHE_BLOCK  CacheBlock 
)

Definition at line 223 of file blocklist.c.

224{
225
226 TRACE("CacheInternalOptimizeBlockList()\n");
227
228 // Don't do this if this block is already at the head of the list
229 if (&CacheBlock->ListEntry != CacheDrive->CacheBlockHead.Flink)
230 {
231 // Remove this item from the block list
232 RemoveEntryList(&CacheBlock->ListEntry);
233
234 // Re-insert it at the head of the list
235 InsertHeadList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);
236 }
237}
#define InsertHeadList(ListHead, Entry)

Referenced by CacheInternalGetBlockPointer().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( CACHE  )