Root/
Source at commit 307 created 12 years 11 months ago. By ifabio, merge changes from trunk (929). Also merge the module changes from Azimutz branche (fix compile error) Also edited the info.plist into AHCIPortInjector.kext: http://forum.voodooprojects.org/index.php/topic,1170.0.html | |
---|---|
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 long 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, long blockSize )␊ |
70 | {␊ |
71 | #ifdef __i386__␊ |
72 | if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))␊ |
73 | return;␊ |
74 | #endif␊ |
75 | ␊ |
76 | if ((blockSize < kCacheMinBlockSize) ||␊ |
77 | (blockSize > kCacheMaxBlockSize))␊ |
78 | return;␊ |
79 | ␊ |
80 | gCacheBlockSize = blockSize;␊ |
81 | gCacheNumEntries = kCacheSize / gCacheBlockSize;␊ |
82 | gCacheTime = 0;␊ |
83 | ␊ |
84 | #if CACHE_STATS␊ |
85 | gCacheHits = 0;␊ |
86 | gCacheMisses = 0;␊ |
87 | gCacheEvicts = 0;␊ |
88 | #endif␊ |
89 | ␊ |
90 | gCacheIH = ih;␊ |
91 | ␊ |
92 | #ifdef __i386__␊ |
93 | if (!gCacheBuffer) gCacheBuffer = (char *) malloc(kCacheSize);␊ |
94 | if (!gCacheEntries) gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));␊ |
95 | if ( !gCacheBuffer || !gCacheEntries )␊ |
96 | {␊ |
97 | gCacheIH = 0; // invalidate cache␊ |
98 | return;␊ |
99 | }␊ |
100 | #endif␊ |
101 | ␊ |
102 | bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));␊ |
103 | }␊ |
104 | ␊ |
105 | long CacheRead( CICell ih, char * buffer, long long offset,␊ |
106 | ␉ long length, long cache )␊ |
107 | {␊ |
108 | long cnt, oldestEntry = 0, oldestTime, loadCache = 0;␊ |
109 | CacheEntry *entry;␊ |
110 | ␊ |
111 | // See if the data can be cached.␊ |
112 | if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) {␊ |
113 | // Look for the data in the cache.␊ |
114 | for (cnt = 0; cnt < gCacheNumEntries; cnt++) {␊ |
115 | entry = &gCacheEntries[cnt];␊ |
116 | if ((entry->ih == ih) && (entry->offset == offset)) {␊ |
117 | entry->time = ++gCacheTime;␊ |
118 | break;␊ |
119 | }␊ |
120 | }␊ |
121 | ␊ |
122 | // If the data was found copy it to the caller.␊ |
123 | if (cnt != gCacheNumEntries) {␊ |
124 | bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);␊ |
125 | #if CACHE_STATS␊ |
126 | gCacheHits++;␊ |
127 | #endif␊ |
128 | return gCacheBlockSize;␊ |
129 | }␊ |
130 | ␊ |
131 | // Could not find the data in the cache.␊ |
132 | loadCache = 1;␊ |
133 | }␊ |
134 | ␊ |
135 | // Read the data from the disk.␊ |
136 | Seek(ih, offset);␊ |
137 | Read(ih, (long)buffer, length);␊ |
138 | #if CACHE_STATS␊ |
139 | if (cache) gCacheMisses++;␊ |
140 | #endif␊ |
141 | ␊ |
142 | // Put the data from the disk in the cache if needed.␊ |
143 | if (loadCache) {␊ |
144 | // Find a free entry.␊ |
145 | oldestTime = gCacheTime;␊ |
146 | for (cnt = 0; cnt < gCacheNumEntries; cnt++) {␊ |
147 | entry = &gCacheEntries[cnt];␊ |
148 | ␊ |
149 | // Found a free entry.␊ |
150 | if (entry->ih == 0) break;␊ |
151 | ␊ |
152 | if (entry->time < oldestTime) {␊ |
153 | oldestTime = entry->time;␊ |
154 | oldestEntry = cnt;␊ |
155 | }␊ |
156 | }␊ |
157 | ␊ |
158 | // If no free entry was found, use the oldest.␊ |
159 | if (cnt == gCacheNumEntries) {␊ |
160 | cnt = oldestEntry;␊ |
161 | #if CACHE_STATS␊ |
162 | gCacheEvicts++;␊ |
163 | #endif␊ |
164 | }␊ |
165 | ␊ |
166 | // Copy the data from disk to the new entry.␊ |
167 | entry = &gCacheEntries[cnt];␊ |
168 | entry->ih = ih;␊ |
169 | entry->time = ++gCacheTime;␊ |
170 | entry->offset = offset;␊ |
171 | bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);␊ |
172 | }␊ |
173 | ␊ |
174 | return length;␊ |
175 | }␊ |
176 |