Root/
Source at commit HEAD created 5 years 6 days ago. By ifabio, Few update to kernelPatcher (Credits to CrazyBirdy) | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * The contents of this file constitute Original Code as defined in and␊ |
7 | * are subject to the Apple Public Source License Version 2.0 (the␊ |
8 | * "License"). You may not use this file except in compliance with the␊ |
9 | * License. Please obtain a copy of the License at␊ |
10 | * http://www.apple.com/publicsource and read it before using this file.␊ |
11 | * ␊ |
12 | * This Original Code and all software distributed under the License are␊ |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
17 | * License for the specific language governing rights and limitations␊ |
18 | * under the License.␊ |
19 | * ␊ |
20 | * @APPLE_LICENSE_HEADER_END@␊ |
21 | */␊ |
22 | /*␊ |
23 | * cache.c - A simple cache for file systems meta-data.␊ |
24 | *␊ |
25 | * Copyright (c) 2000 Apple Computer, Inc.␊ |
26 | *␊ |
27 | * DRI: Josh de Cesare␊ |
28 | */␊ |
29 | ␊ |
30 | #include <sl.h>␊ |
31 | // #include <fs.h>␊ |
32 | ␊ |
33 | struct CacheEntry {␊ |
34 | ␉CICell ih;␊ |
35 | ␉long time;␊ |
36 | ␉long long offset;␊ |
37 | };␊ |
38 | typedef struct CacheEntry CacheEntry;␊ |
39 | ␊ |
40 | #define kCacheSize (0x100000)␊ |
41 | #define kCacheMinBlockSize (0x200)␊ |
42 | #define kCacheMaxBlockSize (0x8000)␊ |
43 | #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)␊ |
44 | ␊ |
45 | static CICell gCacheIH;␊ |
46 | static u_int32_t gCacheBlockSize;␊ |
47 | static long gCacheNumEntries;␊ |
48 | static long gCacheTime;␊ |
49 | ␊ |
50 | #ifdef __i386__␊ |
51 | ␉static CacheEntry *gCacheEntries;␊ |
52 | ␉static char *gCacheBuffer;␊ |
53 | #else␊ |
54 | ␉static CacheEntry gCacheEntries[kCacheMaxEntries];␊ |
55 | ␉static char gCacheBuffer[kCacheSize];␊ |
56 | #endif␊ |
57 | ␊ |
58 | #if CACHE_STATS␊ |
59 | ␉unsigned long gCacheHits;␊ |
60 | ␉unsigned long gCacheMisses;␊ |
61 | ␉unsigned long gCacheEvicts;␊ |
62 | #endif␊ |
63 | ␊ |
64 | void CacheReset()␊ |
65 | {␊ |
66 | ␉gCacheIH = NULL;␊ |
67 | }␊ |
68 | ␊ |
69 | void CacheInit( CICell ih, u_int32_t blockSize )␊ |
70 | {␊ |
71 | #ifdef __i386__␊ |
72 | ␉if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))␊ |
73 | ␉{␊ |
74 | ␉␉return;␊ |
75 | ␉}␊ |
76 | #endif␊ |
77 | ␊ |
78 | ␉if ((blockSize < kCacheMinBlockSize) || (blockSize > kCacheMaxBlockSize))␊ |
79 | ␉{␊ |
80 | ␉␉return;␊ |
81 | ␉}␊ |
82 | ␊ |
83 | ␉gCacheBlockSize = blockSize;␊ |
84 | ␉gCacheNumEntries = kCacheSize / gCacheBlockSize;␊ |
85 | ␉gCacheTime = 0;␊ |
86 | ␊ |
87 | #if CACHE_STATS␊ |
88 | ␉gCacheHits␉= 0;␊ |
89 | ␉gCacheMisses␉= 0;␊ |
90 | ␉gCacheEvicts␉= 0;␊ |
91 | #endif␊ |
92 | ␊ |
93 | gCacheIH = ih;␊ |
94 | ␊ |
95 | #ifdef __i386__␊ |
96 | ␉if (!gCacheBuffer)␊ |
97 | ␉{␊ |
98 | ␉␉gCacheBuffer = (char *) malloc(kCacheSize);␊ |
99 | ␉}␊ |
100 | ␊ |
101 | ␉if (!gCacheEntries)␊ |
102 | ␉{␊ |
103 | ␉␉gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));␊ |
104 | ␉}␊ |
105 | ␊ |
106 | ␉if (!gCacheBuffer || !gCacheEntries)␊ |
107 | ␉{␊ |
108 | ␉␉gCacheIH = 0; // invalidate cache␊ |
109 | ␉␉return;␊ |
110 | ␉}␊ |
111 | #endif␊ |
112 | ␊ |
113 | ␉bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));␊ |
114 | }␊ |
115 | ␊ |
116 | u_int32_t CacheRead(CICell ih, char * buffer, long long offset, u_int32_t length, long cache)␊ |
117 | {␊ |
118 | ␉long cnt, oldestEntry = 0, oldestTime, loadCache = 0;␊ |
119 | ␉CacheEntry *entry;␊ |
120 | ␊ |
121 | ␉// See if the data can be cached.␊ |
122 | ␉if (cache && (gCacheIH == ih) && (length == gCacheBlockSize))␊ |
123 | ␉{␊ |
124 | ␉␉// Look for the data in the cache.␊ |
125 | ␉␉for (cnt = 0; cnt < gCacheNumEntries; cnt++)␊ |
126 | ␉␉{␊ |
127 | ␉␉␉entry = &gCacheEntries[cnt];␊ |
128 | ␊ |
129 | ␉␉␉if ((entry->ih == ih) && (entry->offset == offset))␊ |
130 | ␉␉␉{␊ |
131 | ␉␉␉␉entry->time = ++gCacheTime;␊ |
132 | ␉␉␉␉break;␊ |
133 | ␉␉␉}␊ |
134 | ␉␉}␊ |
135 | ␊ |
136 | ␉␉// If the data was found copy it to the caller.␊ |
137 | ␉␉if (cnt != gCacheNumEntries)␊ |
138 | ␉␉{␊ |
139 | ␉␉␉bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);␊ |
140 | #if CACHE_STATS␊ |
141 | ␉␉␉gCacheHits++;␊ |
142 | #endif␊ |
143 | ␉␉␉return gCacheBlockSize;␊ |
144 | ␉␉}␊ |
145 | ␊ |
146 | ␉␉// Could not find the data in the cache.␊ |
147 | ␉␉loadCache = 1;␊ |
148 | ␉}␊ |
149 | ␊ |
150 | ␉// Read the data from the disk.␊ |
151 | ␉Seek(ih, offset);␊ |
152 | ␉Read(ih, (long)buffer, length);␊ |
153 | ␊ |
154 | #if CACHE_STATS␊ |
155 | ␉if (cache)␊ |
156 | ␉{␊ |
157 | ␉␉gCacheMisses++;␊ |
158 | ␉}␊ |
159 | #endif␊ |
160 | ␊ |
161 | ␉// Put the data from the disk in the cache if needed.␊ |
162 | ␉if (loadCache)␊ |
163 | ␉{␊ |
164 | ␉␉// Find a free entry.␊ |
165 | ␉␉oldestTime = gCacheTime;␊ |
166 | ␊ |
167 | ␉␉for (cnt = 0; cnt < gCacheNumEntries; cnt++)␊ |
168 | ␉␉{␊ |
169 | ␉␉␉entry = &gCacheEntries[cnt];␊ |
170 | ␊ |
171 | ␉␉␉// Found a free entry.␊ |
172 | ␉␉␉if (entry->ih == 0)␊ |
173 | ␉␉␉{␊ |
174 | ␉␉␉␉break;␊ |
175 | ␉␉␉}␊ |
176 | ␊ |
177 | ␉␉␉if (entry->time < oldestTime)␊ |
178 | ␉␉␉{␊ |
179 | ␉␉␉␉oldestTime = entry->time;␊ |
180 | ␉␉␉␉oldestEntry = cnt;␊ |
181 | ␉␉␉}␊ |
182 | ␉␉}␊ |
183 | ␊ |
184 | ␉␉// If no free entry was found, use the oldest.␊ |
185 | ␉␉if (cnt == gCacheNumEntries)␊ |
186 | ␉␉{␊ |
187 | ␉␉␉cnt = oldestEntry;␊ |
188 | #if CACHE_STATS␊ |
189 | ␉␉␉gCacheEvicts++;␊ |
190 | #endif␊ |
191 | ␉␉}␊ |
192 | ␊ |
193 | ␉␉// Copy the data from disk to the new entry.␊ |
194 | ␉␉entry = &gCacheEntries[cnt];␊ |
195 | ␉␉entry->ih = ih;␊ |
196 | ␉␉entry->time = ++gCacheTime;␊ |
197 | ␉␉entry->offset = offset;␊ |
198 | ␉␉bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);␊ |
199 | ␉}␊ |
200 | ␊ |
201 | ␉return length;␊ |
202 | }␊ |
203 |