1 | /* |
2 | * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #include "jni.h" |
27 | #include "jni_util.h" |
28 | #include "jvm.h" |
29 | #include "jlong.h" |
30 | #include "java_nio_MappedByteBuffer.h" |
31 | #include <assert.h> |
32 | #include <sys/mman.h> |
33 | #include <stddef.h> |
34 | #include <stdlib.h> |
35 | |
36 | #ifdef _AIX |
37 | #include <unistd.h> |
38 | #endif |
39 | |
40 | /* Output type for mincore(2) */ |
41 | #ifdef __linux__ |
42 | typedef unsigned char mincore_vec_t; |
43 | #else |
44 | typedef char mincore_vec_t; |
45 | #endif |
46 | |
47 | #ifdef _AIX |
48 | static long calculate_number_of_pages_in_range(void* address, size_t len, size_t pagesize) { |
49 | uintptr_t address_unaligned = (uintptr_t) address; |
50 | uintptr_t address_aligned = address_unaligned & (~(pagesize - 1)); |
51 | size_t len2 = len + (address_unaligned - address_aligned); |
52 | long numPages = (len2 + pagesize - 1) / pagesize; |
53 | return numPages; |
54 | } |
55 | #endif |
56 | |
57 | JNIEXPORT jboolean JNICALL |
58 | Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address, |
59 | jlong len, jint numPages) |
60 | { |
61 | jboolean loaded = JNI_TRUE; |
62 | int result = 0; |
63 | int i = 0; |
64 | void *a = (void *) jlong_to_ptr(address); |
65 | mincore_vec_t* vec = NULL; |
66 | |
67 | #ifdef _AIX |
68 | /* See JDK-8186665 */ |
69 | size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); |
70 | if ((long)pagesize == -1) { |
71 | return JNI_FALSE; |
72 | } |
73 | numPages = (jint) calculate_number_of_pages_in_range(a, len, pagesize); |
74 | #endif |
75 | |
76 | /* Include space for one sentinel byte at the end of the buffer |
77 | * to catch overflows. */ |
78 | vec = (mincore_vec_t*) malloc(numPages + 1); |
79 | |
80 | if (vec == NULL) { |
81 | JNU_ThrowOutOfMemoryError(env, NULL); |
82 | return JNI_FALSE; |
83 | } |
84 | |
85 | vec[numPages] = '\x7f'; /* Write sentinel. */ |
86 | result = mincore(a, (size_t)len, vec); |
87 | assert(vec[numPages] == '\x7f'); /* Check sentinel. */ |
88 | |
89 | if (result == -1) { |
90 | JNU_ThrowIOExceptionWithLastError(env, "mincore failed" ); |
91 | free(vec); |
92 | return JNI_FALSE; |
93 | } |
94 | |
95 | for (i=0; i<numPages; i++) { |
96 | if (vec[i] == 0) { |
97 | loaded = JNI_FALSE; |
98 | break; |
99 | } |
100 | } |
101 | free(vec); |
102 | return loaded; |
103 | } |
104 | |
105 | |
106 | JNIEXPORT void JNICALL |
107 | Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, |
108 | jlong len) |
109 | { |
110 | char *a = (char *)jlong_to_ptr(address); |
111 | int result = madvise((caddr_t)a, (size_t)len, MADV_WILLNEED); |
112 | if (result == -1) { |
113 | JNU_ThrowIOExceptionWithLastError(env, "madvise failed" ); |
114 | } |
115 | } |
116 | |
117 | |
118 | JNIEXPORT void JNICALL |
119 | Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo, |
120 | jlong address, jlong len) |
121 | { |
122 | void* a = (void *)jlong_to_ptr(address); |
123 | int result = msync(a, (size_t)len, MS_SYNC); |
124 | if (result == -1) { |
125 | JNU_ThrowIOExceptionWithLastError(env, "msync failed" ); |
126 | } |
127 | } |
128 | |