30 #include <unistd.h>
31
32 #if defined(__linux__) || defined(__solaris__)
33 #include <sys/sendfile.h>
34 #elif defined(_AIX)
35 #include <sys/socket.h>
36 #elif defined(_ALLBSD_SOURCE)
37 #include <sys/socket.h>
38 #include <sys/uio.h>
39 #define lseek64 lseek
40 #define mmap64 mmap
41 #endif
42
43 #include "jni.h"
44 #include "jni_util.h"
45 #include "jlong.h"
46 #include "nio.h"
47 #include "nio_util.h"
48 #include "sun_nio_ch_FileChannelImpl.h"
49 #include "java_lang_Integer.h"
50
51 static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
52
53 JNIEXPORT jlong JNICALL
54 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
55 {
56 jlong pageSize = sysconf(_SC_PAGESIZE);
57 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
58 return pageSize;
59 }
60
61 static jlong
62 handle(JNIEnv *env, jlong rv, char *msg)
63 {
64 if (rv >= 0)
65 return rv;
66 if (errno == EINTR)
67 return IOS_INTERRUPTED;
68 JNU_ThrowIOExceptionWithLastError(env, msg);
69 return IOS_THROWN;
70 }
71
72
73 JNIEXPORT jlong JNICALL
74 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
75 jint prot, jlong off, jlong len)
76 {
77 void *mapAddress = 0;
78 jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
79 jint fd = fdval(env, fdo);
80 int protections = 0;
81 int flags = 0;
82
83 if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
84 protections = PROT_READ;
85 flags = MAP_SHARED;
86 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
87 protections = PROT_WRITE | PROT_READ;
88 flags = MAP_SHARED;
89 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
90 protections = PROT_WRITE | PROT_READ;
91 flags = MAP_PRIVATE;
92 }
93
94 mapAddress = mmap64(
95 0, /* Let OS decide location */
96 len, /* Number of bytes to map */
97 protections, /* File permissions */
98 flags, /* Changes are shared */
99 fd, /* File descriptor of mapped file */
100 off); /* Offset into file */
101
102 if (mapAddress == MAP_FAILED) {
103 if (errno == ENOMEM) {
104 JNU_ThrowOutOfMemoryError(env, "Map failed");
105 return IOS_THROWN;
106 }
107 return handle(env, -1, "Map failed");
108 }
109
110 return ((jlong) (unsigned long) mapAddress);
111 }
112
113
114 JNIEXPORT jint JNICALL
115 Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
116 jlong address, jlong len)
117 {
118 void *a = (void *)jlong_to_ptr(address);
119 return handle(env,
120 munmap(a, (size_t)len),
121 "Unmap failed");
122 }
|
30 #include <unistd.h>
31
32 #if defined(__linux__) || defined(__solaris__)
33 #include <sys/sendfile.h>
34 #elif defined(_AIX)
35 #include <sys/socket.h>
36 #elif defined(_ALLBSD_SOURCE)
37 #include <sys/socket.h>
38 #include <sys/uio.h>
39 #define lseek64 lseek
40 #define mmap64 mmap
41 #endif
42
43 #include "jni.h"
44 #include "jni_util.h"
45 #include "jlong.h"
46 #include "nio.h"
47 #include "nio_util.h"
48 #include "sun_nio_ch_FileChannelImpl.h"
49 #include "java_lang_Integer.h"
50 #include <assert.h>
51
52 static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
53
54 JNIEXPORT jlong JNICALL
55 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
56 {
57 jlong pageSize = sysconf(_SC_PAGESIZE);
58 chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
59 return pageSize;
60 }
61
62 static jlong
63 handle(JNIEnv *env, jlong rv, char *msg)
64 {
65 if (rv >= 0)
66 return rv;
67 if (errno == EINTR)
68 return IOS_INTERRUPTED;
69 JNU_ThrowIOExceptionWithLastError(env, msg);
70 return IOS_THROWN;
71 }
72
73
74 JNIEXPORT jlong JNICALL
75 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
76 jint prot, jlong off, jlong len, jboolean map_sync)
77 {
78 void *mapAddress = 0;
79 jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
80 jint fd = fdval(env, fdo);
81 int protections = 0;
82 int flags = 0;
83
84 // should never be called with map_sync and prot == PRIVATE
85 assert((prot != sun_nio_ch_FileChannelImpl_MAP_PV) ||! map_sync);
86
87 if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
88 protections = PROT_READ;
89 flags = MAP_SHARED;
90 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
91 protections = PROT_WRITE | PROT_READ;
92 flags = MAP_SHARED;
93 } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
94 protections = PROT_WRITE | PROT_READ;
95 flags = MAP_PRIVATE;
96 }
97
98 // TODO - remove the following defines
99 // for testing we need to define the extra MAP_XXX flags used for
100 // persistent memory. they will eventually get defined by the
101 // system and included via sys/mman.h
102
103 #ifndef MAP_SYNC
104 #define MAP_SYNC 0x80000
105 #define MAP_SHARED_VALIDATE 0x03;
106 #define __NEEDS_MAP_SYNC_UNDEF__
107 #endif
108
109 if (map_sync) {
110 // ensure
111 // 1) this is Linux on AArch64 or x86_64
112 // 2) the mmap APIs are available/ at compile time
113 #if !defined(LINUX) || ! (defined(aarch64) || (defined(amd64) && defined(_LP64))) || ! defined(MAP_SYNC) || ! defined(MAP_SHARED_VALIDATE)
114 // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
115 JNU_ThrowIOException(env, "map_persistent is not implemented");
116 return IOS_THROWN;
117 #else
118 flags |= MAP_SYNC | MAP_SHARED_VALIDATE;
119 #endif
120 }
121
122 #ifdef __NEEDS_MAP_SYNC_UNDEF__
123 #undef MAP_SYNC
124 #undef MAP_SHARED_VALIDATE
125 #undef __NEEDS_MAP_SYNC_UNDEF__
126 #endif
127
128 mapAddress = mmap64(
129 0, /* Let OS decide location */
130 len, /* Number of bytes to map */
131 protections, /* File permissions */
132 flags, /* Changes are shared */
133 fd, /* File descriptor of mapped file */
134 off); /* Offset into file */
135
136 if (mapAddress == MAP_FAILED) {
137 if (map_sync && errno == ENOTSUP) {
138 JNU_ThrowIOExceptionWithLastError(env, "map_persistent is not supported");
139 return IOS_THROWN;
140 }
141
142 if (errno == ENOMEM) {
143 JNU_ThrowOutOfMemoryError(env, "Map failed");
144 return IOS_THROWN;
145 }
146 return handle(env, -1, "Map failed");
147 }
148
149 return ((jlong) (unsigned long) mapAddress);
150 }
151
152
153 JNIEXPORT jint JNICALL
154 Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
155 jlong address, jlong len)
156 {
157 void *a = (void *)jlong_to_ptr(address);
158 return handle(env,
159 munmap(a, (size_t)len),
160 "Unmap failed");
161 }
|