|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-89BCF9A5-ABBD-5523-BA76-FDB00B806A30" xml:lang="en"><title>Migration |
|
13 Tutorial: Fair Scheduling and File Caching</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>Describes how to implement and configure the <xref href="GUID-5B24741C-7CE0-58E8-98C9-1D1CACCD476F.dita">fair |
|
15 scheduling and file caching</xref> features for file systems implementations. </p> |
|
16 <section id="GUID-450D57A3-928B-5389-B941-595DB20A7CEA"><title>Enabling fair |
|
17 scheduling</title><p>The <codeph>MExtendedFileInterface</codeph> API enables |
|
18 fair scheduling. The FAT, FAT32 and LFFS file systems support <codeph>MExtendedFileInterface</codeph>, |
|
19 this API allows requests to be split into one or more segments with the <codeph>aOffset</codeph> parameter. |
|
20 Support has been built in for large files by changing the file’s position |
|
21 parameter (<codeph>aPos</codeph>) from a <xref href="GUID-7A2A43EC-6125-3BFE-834B-23C37F7B40D5.dita"><apiname>TInt</apiname></xref> to a <xref href="GUID-AAE85115-A8AA-3F6C-BA8C-69F5A23B0D90.dita"><apiname>TInt64</apiname></xref>. </p> <p>To |
|
22 enable fair scheduling, the file system mounted on a particular drive must |
|
23 support <xref href="GUID-63DF657C-434D-353D-A536-8AF9D97C8260.dita#GUID-63DF657C-434D-353D-A536-8AF9D97C8260/GUID-E57D0ED6-C351-37F4-8E80-5A64144B6655"><apiname>CFileCB::MExtendedFileInterface</apiname></xref>. The object returned |
|
24 by <xref href="GUID-0012B043-9FC4-3953-928E-CB6107E0486A.dita#GUID-0012B043-9FC4-3953-928E-CB6107E0486A/GUID-EFDD2A6C-1319-30FC-9FC6-9653E0A2F827"><apiname>CFileSystem::NewFileL()</apiname></xref> must be derived from <codeph>CFileCB</codeph> and <codeph>CFileCB::MExtendedFileInterface</codeph>. |
|
25 The file server determines whether this is the case by calling <xref href="GUID-63DF657C-434D-353D-A536-8AF9D97C8260.dita#GUID-63DF657C-434D-353D-A536-8AF9D97C8260/GUID-D3628A6F-8E6D-39CA-8D36-EB3BC4154DF2"><apiname>CFileCB::GetInterface</apiname></xref>. </p> <p>The <xref href="GUID-63DF657C-434D-353D-A536-8AF9D97C8260.dita#GUID-63DF657C-434D-353D-A536-8AF9D97C8260/GUID-E57D0ED6-C351-37F4-8E80-5A64144B6655"><apiname>CFileCB::MExtendedFileInterface</apiname></xref> interface is as follows: </p><codeblock id="GUID-27EC7D5D-7BB6-5427-9EF0-71561F7AB847" xml:space="preserve">class MExtendedFileInterface |
|
26 { |
|
27 public: |
|
28 virtual void ReadL(TInt64 aPos, TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset) = 0; |
|
29 virtual void WriteL(TInt64 aPos, TInt& aLength, const TDesC8* aDes, const RMessagePtr2& aMessage, TInt aOffset) = 0; |
|
30 virtual void SetSizeL(TInt64 aSize) = 0; |
|
31 };</codeblock> <p>The file system indicates its support for <codeph>MExtendedFileInterface</codeph> by |
|
32 intercepting the <xref href="GUID-63DF657C-434D-353D-A536-8AF9D97C8260.dita#GUID-63DF657C-434D-353D-A536-8AF9D97C8260/GUID-F13F53A3-502A-38E4-B8E3-4099DC44EEC0"><apiname>CFileCB::EExtendedFileInterface</apiname></xref> enumeration |
|
33 in the <xref href="GUID-63DF657C-434D-353D-A536-8AF9D97C8260.dita#GUID-63DF657C-434D-353D-A536-8AF9D97C8260/GUID-CBCFC605-C942-3D4E-8ABA-2EF454E5A44B"><apiname>CFileCB::GetInterface()</apiname></xref> method as in the following |
|
34 example: </p><codeblock id="GUID-714AB83B-0A24-5E81-92B8-CB425002B426" xml:space="preserve">TInt CFatFileCB::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput) |
|
35 { |
|
36 switch(aInterfaceId) |
|
37 { |
|
38 case EExtendedFileInterface: |
|
39 ((CFileCB::MExtendedFileInterface*&) aInterface) = this; |
|
40 return KErrNone; |
|
41 |
|
42 //etc. |
|
43 |
|
44 default: |
|
45 return CFileCB::GetInterface(aInterfaceId, aInterface, aInput); |
|
46 } |
|
47 }</codeblock> </section> |
|
48 <section id="GUID-719C7E0C-790B-5C61-9EA8-E2687397340F"><title>Enabling read |
|
49 and write caching</title><p>To enable caching, the file system must support |
|
50 reads and writes to local buffers, which are buffers created and owned by |
|
51 the file server itself rather by a client of the file server. </p><p>The local |
|
52 media subsystem already supports local messages, but the file system and any |
|
53 file system extensions need to be examined carefully to ensure that they do |
|
54 not call any <xref href="GUID-78E0DEDD-C020-3174-AD0A-E4C18C4C9213.dita"><apiname>RMessagePtr2</apiname></xref> methods, otherwise a panic results. </p> <p>The |
|
55 file server calls <xref href="GUID-FADDE053-CC1C-39BC-A52D-27093041BE20.dita#GUID-FADDE053-CC1C-39BC-A52D-27093041BE20/GUID-239159E5-1A98-3FE1-9A0D-803BEDB99DCE"><apiname>CMountCB::LocalBufferSupport()</apiname></xref> to find |
|
56 out whether the file system and all file system extensions mounted on a particular |
|
57 drive fully support local buffers before it enables caching. The file system |
|
58 handles the <xref href="GUID-FADDE053-CC1C-39BC-A52D-27093041BE20.dita#GUID-FADDE053-CC1C-39BC-A52D-27093041BE20/GUID-87F36D0F-CAA5-35ED-9E99-BB8F7B9564C2"><apiname>CMountCB::ELocalBufferSupport</apiname></xref> enumeration in |
|
59 its <xref href="GUID-FADDE053-CC1C-39BC-A52D-27093041BE20.dita#GUID-FADDE053-CC1C-39BC-A52D-27093041BE20/GUID-CABEF8F6-637C-3223-80C6-FBC8B7247030"><apiname>CMountCB::GetInterface()</apiname></xref> method and passes the request |
|
60 on to the first proxy drive, as in the following example: </p><codeblock id="GUID-969BBBAE-5C1F-5032-831D-3C17E58285AE" xml:space="preserve">TInt CFatMountCB::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* /*aInput*/) |
|
61 { |
|
62 TInt r= KErrNone; |
|
63 switch(aInterfaceId) |
|
64 { |
|
65 // file caching supported, so pass query on to first proxy drive |
|
66 case CMountCB::ELocalBufferSupport: |
|
67 r = LocalDrive()->LocalBufferSupport(); |
|
68 break; |
|
69 default: |
|
70 r=KErrNotSupported; |
|
71 } |
|
72 return r; |
|
73 }</codeblock> <p>If no file system extensions are loaded, then the query |
|
74 is eventually handled by <xref href="GUID-F47F56E4-3754-365B-B529-53C1D2A29503.dita#GUID-F47F56E4-3754-365B-B529-53C1D2A29503/GUID-7C0145B1-531A-367C-92DF-61EBB46F01CB"><apiname>CLocalProxyDrive::GetInterface()</apiname></xref>, |
|
75 which returns <codeph>KErrNone</codeph> to indicate that <xref href="GUID-32659A02-6541-3D15-AB88-B70FBD7DF9B0.dita"><apiname>TBusLocalDrive</apiname></xref> and |
|
76 the local media sub-system support local buffers. </p> <p>If there are any |
|
77 file system extensions, they must handle the <xref href="GUID-B0BD0F3D-9081-3DBE-8375-F5000D6D39ED.dita#GUID-B0BD0F3D-9081-3DBE-8375-F5000D6D39ED/GUID-53AC960F-9EE3-3410-9DD6-1BAC08C7B8E8"><apiname>CProxyDrive::ELocalBufferSupport</apiname></xref> enumeration, |
|
78 as in the following example: </p><codeblock id="GUID-67D3FAA1-9FC3-5653-B21D-73BC13AA36AE" xml:space="preserve">TInt CBitExtProxyDrive::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput) |
|
79 { |
|
80 switch(aInterfaceId) |
|
81 { |
|
82 // file caching supported, so pass query on to next proxy drive |
|
83 case ELocalBufferSupport: |
|
84 return CBaseExtProxyDrive::LocalBufferSupport(); |
|
85 |
|
86 default: |
|
87 return CBaseExtProxyDrive::GetInterface(aInterfaceId, aInterface, aInput); |
|
88 } |
|
89 }</codeblock> </section> |
|
90 <section id="GUID-020006B9-1A1E-523B-9CFA-927CDE5D5058"><title>Configuring |
|
91 caching</title><p>The global and drive-specific cache property defaults are |
|
92 defined in <filepath>f32\sfile\sf_file_cache_defs.h</filepath>. They may be |
|
93 overridden for a particular drive by appropriate entries in the Base Starter |
|
94 component's <filepath>ESTART.TXT</filepath> configuration file. The format |
|
95 of this file has been enhanced to support the<codeph> .ini</codeph> file style |
|
96 syntax: </p><codeblock id="GUID-E0DBF04F-8F7E-55E4-8210-D5697A5B3FDB" xml:space="preserve">C: 0 ELOCAL FAT 0 FS_FORMAT_COLD,FS_SYNC_DRIVE # IRAM |
|
97 D: 1 ELOCAL FAT 0 FS_SCANDRIVE # MMC (textshell) |
|
98 I: 2 ELOCAL FAT 0 FS_FORMAT_CORRUPT # NAND - USER DATA |
|
99 K: 8 ELFFS LFFS 0 FS_FORMAT_CORRUPT # LFFS |
|
100 |
|
101 [DriveD] |
|
102 FileCacheSize 256 |
|
103 FairSchedulingLen 128 |
|
104 FileCacheRead ON |
|
105 FileCacheReadAhead ON |
|
106 FileCacheWrite ON |
|
107 ClosedFileKeepAliveTime 3000 |
|
108 DirtyDataFlushTime 3000 |
|
109 FileCacheReadAsync ON |
|
110 |
|
111 [DriveI] |
|
112 FileCacheWrite ENABLED |
|
113 |
|
114 [DriveK] |
|
115 FileCacheWrite ENABLED |
|
116 |
|
117 [FileCache] |
|
118 GlobalCacheEnabled ON |
|
119 GlobalCacheSize 32768 |
|
120 GlobalCacheMaxLockedSize 1024 |
|
121 LowMemoryThreshold 10</codeblock> <p>In this example, write caching is enabled |
|
122 on drives I and K and has been turned on by default on drive D.</p><note>Most |
|
123 of the properties in the example are set to their default values: the definitions |
|
124 are redundant but are shown for illustrative purposes. </note> <p>For details, |
|
125 see <xref href="GUID-8BA1EEC2-78A3-54CC-95D9-81BF2659963D.dita">Base Starter Technology</xref>. </p> <p id="GUID-16751410-EFC2-55B8-8BC0-ED5F97F98EBB"><b>Global cache settings</b> </p><p>The |
|
126 following table holds the global caching properties: </p><table id="GUID-4CBAD2A4-52DE-5BA1-98CC-0B1F6BFC54E1"> |
|
127 <tgroup cols="4"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/><colspec colname="col3"/> |
|
128 <tbody> |
|
129 <row> |
|
130 <entry><p> <b>Property</b> </p> </entry> |
|
131 <entry><p> <b>Type</b> </p> </entry> |
|
132 <entry><p> <b>Comments</b> </p> </entry> |
|
133 <entry><p> <b>Default value</b> </p> </entry> |
|
134 </row> |
|
135 <row> |
|
136 <entry><p> <xref href="GUID-91B81C0D-72F9-3226-BEEF-2E8153104102.dita"><apiname>GlobalCacheEnabled</apiname></xref> </p></entry> |
|
137 <entry><p>boolean </p></entry> |
|
138 <entry><p>on or off</p></entry> |
|
139 <entry><p>on</p></entry> |
|
140 </row> |
|
141 <row> |
|
142 <entry><p> <xref href="GUID-BAC3ED91-7A3A-3255-B22E-6B6C0CB266E0.dita"><apiname>GlobalCacheSize</apiname></xref> </p></entry> |
|
143 <entry><p>integer </p> </entry> |
|
144 <entry><p>Size of disconnected chunk shared by all files in kilobytes.</p></entry> |
|
145 <entry><p>32768K (32MB) </p> </entry> |
|
146 </row> |
|
147 <row> |
|
148 <entry><p> <xref href="GUID-BEE48B25-B374-3348-B97C-BA2D634E0330.dita"><apiname>GlobalCacheMaxLockedSize</apiname></xref> </p></entry> |
|
149 <entry><p>integer </p> </entry> |
|
150 <entry><p>Maximum amount of locked RAM for all files in kilobytes.</p></entry> |
|
151 <entry><p>1024K (1 MB) </p> </entry> |
|
152 </row> |
|
153 <row> |
|
154 <entry><p> <xref href="GUID-36596759-4ABC-3F8E-A09E-97464094A58A.dita"><apiname>LowMemoryThreshold</apiname></xref> </p></entry> |
|
155 <entry><p>integer </p></entry> |
|
156 <entry><p>Low memory threshold expressed as a percentage of total RAM. If |
|
157 the amount of RAM drops below this value, attempts to allocate memory for |
|
158 file caching fails.</p></entry> |
|
159 <entry><p>10% </p> </entry> |
|
160 </row> |
|
161 </tbody> |
|
162 </tgroup> |
|
163 </table> <p id="GUID-E7F45784-14F2-505C-B21C-0A8010B0B232"><b>File cache settings</b> </p><p>The |
|
164 properties <xref href="GUID-9278B920-FFEF-3710-8080-B33D028B7A12.dita"><apiname>FileCacheRead</apiname></xref>, <xref href="GUID-33E32FCF-9E02-3254-A9DA-3A6D0B1A52B5.dita"><apiname>FileCacheReadAhead</apiname></xref> and <xref href="GUID-C869ED9F-7F9D-33BC-A1C2-5E21B50A6BFC.dita"><apiname>FileCacheWrite</apiname></xref> may |
|
165 each be in one of 3 states: </p><ul> |
|
166 <li id="GUID-71396310-22E1-564A-A094-3EED4721688D"><p> <codeph>OFF</codeph> - |
|
167 file caching is permanently off and cannot be turned on.</p> </li> |
|
168 <li id="GUID-032E8EB7-4291-5276-852E-BD910CEC8633"><p> <codeph>ENABLED</codeph> - |
|
169 file caching is off by default but may be turned on using an appropriate file |
|
170 open mode, such as <xref href="GUID-4310DC20-300C-3FEB-B1A5-DBA37D5FC940.dita"><apiname>EFileReadBuffered</apiname></xref> </p> </li> |
|
171 <li id="GUID-2644023A-855F-5BDE-8A43-57A534E3367A"><p> <codeph>ON</codeph> - |
|
172 file caching is on by default but may be turned off using an appropriate file |
|
173 open mode, such as <xref href="GUID-449D6D3A-3F00-35F6-BDFB-DF957F98CA8B.dita"><apiname>EFileReadDirectIO</apiname></xref>. </p> </li> |
|
174 </ul><p>See <xref href="GUID-3FEEFC4D-19B5-502A-8310-40646B9C34BC.dita">Run time |
|
175 cache settings</xref>. </p><p>If <xref href="GUID-7F7B7C49-5F60-3B10-A241-98306795A768.dita"><apiname>FileCacheReadAsync</apiname></xref> is |
|
176 set, media driver reads on this drive are asynchronous. This results in read |
|
177 ahead requests being issued before completing a client read request. However, |
|
178 if <codeph>FileCacheReadAsync</codeph> is OFF, then media driver reads on |
|
179 this drive are synchronous. So, issuing a read ahead is likely to block any |
|
180 client thread that is normally running at lower priority than the media driver's |
|
181 thread. In this case read ahead requests only happen during periods of inactivity |
|
182 to improve latency. </p><table id="GUID-B022918E-9335-5D44-B029-D48B36E45937"> |
|
183 <tgroup cols="4"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/><colspec colname="col3"/> |
|
184 <tbody> |
|
185 <row> |
|
186 <entry><p> <b>Property</b> </p> </entry> |
|
187 <entry><p> <b>Type</b> </p> </entry> |
|
188 <entry><p> <b>Comments</b> </p> </entry> |
|
189 <entry><p> <b>Default value</b> </p> </entry> |
|
190 </row> |
|
191 <row> |
|
192 <entry><p> <xref href="GUID-3B777E89-8E4C-3540-958F-C621741895C8.dita"><apiname>FileCacheSize</apiname></xref> </p> </entry> |
|
193 <entry><p>integer </p> </entry> |
|
194 <entry><p>Maximum amount of locked or unlocked RAM per file.</p></entry> |
|
195 <entry><p>128K </p> </entry> |
|
196 </row> |
|
197 <row> |
|
198 <entry><p> <xref href="GUID-23E2F01D-BD7B-39D3-B7B2-F23E20D273C5.dita"><apiname>FairSchedulingLen</apiname></xref> </p> </entry> |
|
199 <entry><p>integer </p> </entry> |
|
200 <entry><p>Read & write requests greater than this length are split up |
|
201 into 2 or more requests.</p></entry> |
|
202 <entry><p>128K </p> </entry> |
|
203 </row> |
|
204 <row> |
|
205 <entry><p> <xref href="GUID-9278B920-FFEF-3710-8080-B33D028B7A12.dita"><apiname>FileCacheRead</apiname></xref> </p></entry> |
|
206 <entry><p>string </p></entry> |
|
207 <entry><p>OFF, ENABLED or ON.</p></entry> |
|
208 <entry><p>ENABLED </p></entry> |
|
209 </row> |
|
210 <row> |
|
211 <entry><p> <xref href="GUID-33E32FCF-9E02-3254-A9DA-3A6D0B1A52B5.dita"><apiname>FileCacheReadAhead</apiname></xref> </p></entry> |
|
212 <entry><p>string </p></entry> |
|
213 <entry><p>OFF, ENABLED or ON.</p></entry> |
|
214 <entry><p>ON </p></entry> |
|
215 </row> |
|
216 <row> |
|
217 <entry><p> <xref href="GUID-C869ED9F-7F9D-33BC-A1C2-5E21B50A6BFC.dita"><apiname>FileCacheWrite</apiname></xref> </p></entry> |
|
218 <entry><p>string </p></entry> |
|
219 <entry><p>OFF, ENABLED or ON.</p></entry> |
|
220 <entry><p>ENABLED </p></entry> |
|
221 </row> |
|
222 <row> |
|
223 <entry><p> <xref href="GUID-7F7B7C49-5F60-3B10-A241-98306795A768.dita"><apiname>FileCacheReadAsync</apiname></xref> </p> </entry> |
|
224 <entry><p>boolean </p> </entry> |
|
225 <entry><p>ON or OFF. If set, media driver reads on this drive are asynchronous.</p></entry> |
|
226 <entry><p>OFF </p> </entry> |
|
227 </row> |
|
228 <row> |
|
229 <entry><p> <xref href="GUID-A91BE0A1-A79D-3828-9E86-7850839BBFE9.dita"><apiname>ClosedFileKeepAliveTime</apiname></xref> </p> </entry> |
|
230 <entry><p>integer </p> </entry> |
|
231 <entry><p>Time after which a file is removed from the closed file queue, in |
|
232 milliseconds. </p></entry> |
|
233 <entry><p>3000ms (3 secs) </p> </entry> |
|
234 </row> |
|
235 <row> |
|
236 <entry><p> <xref href="GUID-78907F25-9D0F-3B76-BDB0-514FC22CAECA.dita"><apiname>DirtyDataFlushTime</apiname></xref> </p> </entry> |
|
237 <entry><p>integer </p> </entry> |
|
238 <entry><p>Time after which a file containing dirty data is flushed, in milliseconds.</p></entry> |
|
239 <entry><p>3000ms (3 secs) </p> </entry> |
|
240 </row> |
|
241 </tbody> |
|
242 </tgroup> |
|
243 </table> </section> |
|
244 </conbody></concept> |