/* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * Test if a file exists in the file system cache */ #include #include #include #include #include #include #include "jni.h" /* * Throws an exception with the given class name and detail message */ static void ThrowException(JNIEnv *env, const char *name, const char *msg) { jclass cls = (*env)->FindClass(env, name); if (cls != NULL) { (*env)->ThrowNew(env, cls, msg); } } /* * Class: DirectIO * Method: isFileInCache0 * Signature: (ILjava/lang/String;)Z */ JNIEXPORT jboolean Java_DirectIOTest_isFileInCache0(JNIEnv *env, jclass cls, jint file_size, jstring file_path) { void *f_mmap; #ifdef __linux__ unsigned char *f_seg; #else char *f_seg; #endif #ifdef __APPLE__ size_t mask = MINCORE_INCORE; #else size_t mask = 0x1; #endif size_t page_size = getpagesize(); size_t index = (file_size + page_size - 1) /page_size; jboolean result = JNI_FALSE; const char* path = (*env)->GetStringUTFChars(env, file_path, JNI_FALSE); int fd = open(path, O_RDWR); (*env)->ReleaseStringUTFChars(env, file_path, path); f_mmap = mmap(0, file_size, PROT_NONE, MAP_SHARED, fd, 0); if (f_mmap == MAP_FAILED) { close(fd); ThrowException(env, "java/io/IOException", "test of whether file exists in cache failed"); } f_seg = malloc(index); if (f_seg != NULL) { if(mincore(f_mmap, file_size, f_seg) == 0) { size_t i; for (i = 0; i < index; i++) { if (f_seg[i] & mask) { result = JNI_TRUE; break; } } } free(f_seg); } else { ThrowException(env, "java/io/IOException", "test of whether file exists in cache failed"); } close(fd); munmap(f_mmap, file_size); return result; }