76 |
76 |
77 // For mapped buffers, a FileDescriptor that may be used for mapping |
77 // For mapped buffers, a FileDescriptor that may be used for mapping |
78 // operations if valid; null if the buffer is not mapped. |
78 // operations if valid; null if the buffer is not mapped. |
79 private final FileDescriptor fd; |
79 private final FileDescriptor fd; |
80 |
80 |
|
81 // A flag true if this buffer is mapped against non-volatile |
|
82 // memory using one of the extended FileChannel.MapMode modes, |
|
83 // MapMode.READ_ONLY_SYNC or MapMode.READ_WRITE_SYNC and false if |
|
84 // it is mapped using any of the other modes. This flag only |
|
85 // determines the behavior of force operations. |
|
86 private final boolean isSync; |
|
87 |
81 // This should only be invoked by the DirectByteBuffer constructors |
88 // This should only be invoked by the DirectByteBuffer constructors |
82 // |
89 // |
83 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private |
90 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private |
84 FileDescriptor fd) |
91 FileDescriptor fd, boolean isSync) { |
85 { |
|
86 super(mark, pos, lim, cap); |
92 super(mark, pos, lim, cap); |
87 this.fd = fd; |
93 this.fd = fd; |
|
94 this.isSync = isSync; |
|
95 } |
|
96 |
|
97 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private |
|
98 boolean isSync) { |
|
99 super(mark, pos, lim, cap); |
|
100 this.fd = null; |
|
101 this.isSync = isSync; |
88 } |
102 } |
89 |
103 |
90 MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private |
104 MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private |
91 super(mark, pos, lim, cap); |
105 super(mark, pos, lim, cap); |
92 this.fd = null; |
106 this.fd = null; |
|
107 this.isSync = false; |
93 } |
108 } |
94 |
109 |
95 // Returns the distance (in bytes) of the buffer start from the |
110 // Returns the distance (in bytes) of the buffer start from the |
96 // largest page aligned address of the mapping less than or equal |
111 // largest page aligned address of the mapping less than or equal |
97 // to the start address. |
112 // to the start address. |
145 // pageSize must be a power of 2 |
160 // pageSize must be a power of 2 |
146 return address & ~(pageSize - 1); |
161 return address & ~(pageSize - 1); |
147 } |
162 } |
148 |
163 |
149 /** |
164 /** |
|
165 * Tells whether this buffer was mapped against a non-volatile |
|
166 * memory device by passing one of the sync map modes {@link |
|
167 * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC |
|
168 * ExtendedMapModeMapMode#READ_ONLY_SYNC} or {@link |
|
169 * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC |
|
170 * ExtendedMapMode#READ_WRITE_SYNC} in the call to {@link |
|
171 * java.nio.channels.FileChannel#map FileChannel.map} or was |
|
172 * mapped by passing one of the other map modes. |
|
173 * |
|
174 * @return true if the file was mapped using one of the sync map |
|
175 * modes, otherwise false. |
|
176 */ |
|
177 private boolean isSync() { |
|
178 return isSync; |
|
179 } |
|
180 |
|
181 /** |
150 * Tells whether or not this buffer's content is resident in physical |
182 * Tells whether or not this buffer's content is resident in physical |
151 * memory. |
183 * memory. |
152 * |
184 * |
153 * <p> A return value of {@code true} implies that it is highly likely |
185 * <p> A return value of {@code true} implies that it is highly likely |
154 * that all of the data in this buffer is resident in physical memory and |
186 * that all of the data in this buffer is resident in physical memory and |
166 */ |
198 */ |
167 public final boolean isLoaded() { |
199 public final boolean isLoaded() { |
168 if (fd == null) { |
200 if (fd == null) { |
169 return true; |
201 return true; |
170 } |
202 } |
|
203 // a sync mapped buffer is always loaded |
|
204 if (isSync()) { |
|
205 return true; |
|
206 } |
171 if ((address == 0) || (capacity() == 0)) |
207 if ((address == 0) || (capacity() == 0)) |
172 return true; |
208 return true; |
173 long offset = mappingOffset(); |
209 long offset = mappingOffset(); |
174 long length = mappingLength(offset); |
210 long length = mappingLength(offset); |
175 return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); |
211 return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); |
233 * |
273 * |
234 * <p> If the file does not reside on a local device then no such guarantee |
274 * <p> If the file does not reside on a local device then no such guarantee |
235 * is made. |
275 * is made. |
236 * |
276 * |
237 * <p> If this buffer was not mapped in read/write mode ({@link |
277 * <p> If this buffer was not mapped in read/write mode ({@link |
238 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this |
278 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then |
239 * method has no effect. </p> |
279 * invoking this method may have no effect. In particular, the |
|
280 * method has no effect for buffers mapped in read-only or private |
|
281 * mapping modes. This method may or may not have an effect for |
|
282 * implementation-specific mapping modes. </p> |
240 * |
283 * |
241 * @return This buffer |
284 * @return This buffer |
242 */ |
285 */ |
243 public final MappedByteBuffer force() { |
286 public final MappedByteBuffer force() { |
244 if (fd == null) { |
287 if (fd == null) { |
245 return this; |
288 return this; |
|
289 } |
|
290 if (isSync) { |
|
291 return force(0, limit()); |
246 } |
292 } |
247 if ((address != 0) && (capacity() != 0)) { |
293 if ((address != 0) && (capacity() != 0)) { |
248 long offset = mappingOffset(); |
294 long offset = mappingOffset(); |
249 force0(fd, mappingAddress(offset), mappingLength(offset)); |
295 force0(fd, mappingAddress(offset), mappingLength(offset)); |
250 } |
296 } |
269 * <p> If the file does not reside on a local device then no such |
315 * <p> If the file does not reside on a local device then no such |
270 * guarantee is made. |
316 * guarantee is made. |
271 * |
317 * |
272 * <p> If this buffer was not mapped in read/write mode ({@link |
318 * <p> If this buffer was not mapped in read/write mode ({@link |
273 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then |
319 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then |
274 * invoking this method has no effect. </p> |
320 * invoking this method may have no effect. In particular, the |
275 * |
321 * method has no effect for buffers mapped in read-only or private |
276 * @param index |
322 * mapping modes. This method may or may not have an effect for |
277 * The index of the first byte in the buffer region that is |
323 * implementation-specific mapping modes. </p> |
278 * to be written back to storage; must be non-negative |
324 * |
279 * and less than limit() |
325 * @param index |
280 * |
326 * The index of the first byte in the buffer region that is |
281 * @param length |
327 * to be written back to storage; must be non-negative |
282 * The length of the region in bytes; must be non-negative |
328 * and less than limit() |
283 * and no larger than limit() - index |
329 * |
|
330 * @param length |
|
331 * The length of the region in bytes; must be non-negative |
|
332 * and no larger than limit() - index |
284 * |
333 * |
285 * @throws IndexOutOfBoundsException |
334 * @throws IndexOutOfBoundsException |
286 * if the preconditions on the index and length do not |
335 * if the preconditions on the index and length do not |
287 * hold. |
336 * hold. |
288 * |
337 * |
295 return this; |
344 return this; |
296 } |
345 } |
297 if ((address != 0) && (limit() != 0)) { |
346 if ((address != 0) && (limit() != 0)) { |
298 // check inputs |
347 // check inputs |
299 Objects.checkFromIndexSize(index, length, limit()); |
348 Objects.checkFromIndexSize(index, length, limit()); |
300 long offset = mappingOffset(index); |
349 if (isSync) { |
301 force0(fd, mappingAddress(offset, index), mappingLength(offset, length)); |
350 // simply force writeback of associated cache lines |
|
351 Unsafe.getUnsafe().writebackMemory(address + index, length); |
|
352 } else { |
|
353 // force writeback via file descriptor |
|
354 long offset = mappingOffset(index); |
|
355 force0(fd, mappingAddress(offset, index), mappingLength(offset, length)); |
|
356 } |
302 } |
357 } |
303 return this; |
358 return this; |
304 } |
359 } |
305 |
360 |
306 private native boolean isLoaded0(long address, long length, int pageCount); |
361 private native boolean isLoaded0(long address, long length, int pageCount); |