]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/fs.subproj/cache.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * cache.c - A simple cache for file systems meta-data.
28 * Copyright (c) 2000 - 2003 Apple Computer, Inc.
41 typedef struct CacheEntry CacheEntry
;
43 #define kCacheSize (kFSCacheSize)
44 #define kCacheMinBlockSize (0x200)
45 #define kCacheMaxBlockSize (0x4000)
46 #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)
48 static CICell gCacheIH
;
49 static long gCacheBlockSize
;
50 static long gCacheNumEntries
;
51 static long gCacheTime
;
52 static CacheEntry gCacheEntries
[kCacheMaxEntries
];
53 static char *gCacheBuffer
= (char *)kFSCacheAddr
;
55 unsigned long gCacheHits
;
56 unsigned long gCacheMisses
;
57 unsigned long gCacheEvicts
;
59 void CacheInit(CICell ih
, long blockSize
)
61 if ((blockSize
< kCacheMinBlockSize
) ||
62 (blockSize
>= kCacheMaxBlockSize
))
65 gCacheBlockSize
= blockSize
;
66 gCacheNumEntries
= kCacheSize
/ gCacheBlockSize
;
73 bzero(gCacheEntries
, sizeof(gCacheEntries
));
79 long CacheRead(CICell ih
, char *buffer
, long long offset
,
80 long length
, long cache
)
82 long cnt
, oldestEntry
, oldestTime
, loadCache
= 0;
85 // See if the data can be cached.
86 if (cache
&& (gCacheIH
== ih
) && (length
== gCacheBlockSize
)) {
87 // Look for the data in the cache.
88 for (cnt
= 0; cnt
< gCacheNumEntries
; cnt
++) {
89 entry
= &gCacheEntries
[cnt
];
90 if ((entry
->ih
== ih
) && (entry
->offset
== offset
)) {
91 entry
->time
= ++gCacheTime
;
96 // If the data was found copy it to the caller.
97 if (cnt
!= gCacheNumEntries
) {
98 bcopy(gCacheBuffer
+ cnt
* gCacheBlockSize
, buffer
, gCacheBlockSize
);
100 return gCacheBlockSize
;
103 // Could not find the data in the cache.
107 // Read the data from the disk.
109 Read(ih
, (CICell
)buffer
, length
);
110 if (cache
) gCacheMisses
++;
112 // Put the data from the disk in the cache if needed.
114 // Find a free entry.
115 oldestTime
= gCacheTime
;
116 for (cnt
= 0; cnt
< gCacheNumEntries
; cnt
++) {
117 entry
= &gCacheEntries
[cnt
];
119 // Found a free entry.
120 if (entry
->ih
== 0) break;
122 if (entry
->time
< oldestTime
) {
123 oldestTime
= entry
->time
;
128 // If no free entry was found, use the oldest.
129 if (cnt
== gCacheNumEntries
) {
134 // Copy the data from disk to the new entry.
135 entry
= &gCacheEntries
[cnt
];
137 entry
->time
= ++gCacheTime
;
138 entry
->offset
= offset
;
139 bcopy(buffer
, gCacheBuffer
+ cnt
* gCacheBlockSize
, gCacheBlockSize
);