56 |
#include <fcntl.h> |
#include <fcntl.h> |
57 |
#endif /* HAVE_FCNTL_H */ |
#endif /* HAVE_FCNTL_H */ |
58 |
|
|
59 |
|
#ifdef HAVE_SYS_MMAN_H |
60 |
|
#include <sys/mman.h> |
61 |
|
#endif /* HAVE_SYS_MMAN_H */ |
62 |
|
|
63 |
/* These values must be kept in sync with FileChannelImpl.java. */ |
/* These values must be kept in sync with FileChannelImpl.java. */ |
64 |
#define FILECHANNELIMPL_READ 1 |
#define FILECHANNELIMPL_READ 1 |
65 |
#define FILECHANNELIMPL_WRITE 2 |
#define FILECHANNELIMPL_WRITE 2 |
95 |
#define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF)) |
#define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF)) |
96 |
#define CONVERT_JINT_TO_SSIZE_T(x) (x) |
#define CONVERT_JINT_TO_SSIZE_T(x) (x) |
97 |
|
|
98 |
|
/* Align a value up or down to a multiple of the pagesize. */ |
99 |
|
#define ALIGN_DOWN(p,s) ((p) - ((p) % (s))) |
100 |
|
#define ALIGN_UP(p,s) ((p) + ((s) - ((p) % (s)))) |
101 |
|
|
102 |
/* cached fieldID of gnu.java.nio.channels.FileChannelImpl.fd */ |
/* cached fieldID of gnu.java.nio.channels.FileChannelImpl.fd */ |
103 |
static jfieldID native_fd_fieldID; |
static jfieldID native_fd_fieldID; |
104 |
|
|
511 |
} |
} |
512 |
|
|
513 |
JNIEXPORT jobject JNICALL |
JNIEXPORT jobject JNICALL |
514 |
Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv * env, |
Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv *env, jobject obj, |
515 |
jobject obj |
jchar mode, jlong position, jint size) |
|
__attribute__ ((__unused__)), jchar mode __attribute__ ((__unused__)), jlong position __attribute__ ((__unused__)), jint size __attribute__ ((__unused__))) |
|
516 |
{ |
{ |
517 |
|
#ifdef HAVE_MMAP |
518 |
|
jclass MappedByteBufferImpl_class; |
519 |
|
jclass RawData_class; |
520 |
|
jmethodID MappedByteBufferImpl_init; |
521 |
|
jmethodID RawData_init; |
522 |
|
jobject RawData_instance; |
523 |
|
jobject buffer; |
524 |
|
long pagesize; |
525 |
|
int prot, flags; |
526 |
|
int fd; |
527 |
|
void *p; |
528 |
|
void *address; |
529 |
|
|
530 |
|
/* FIXME: should we just assume we're on an OS modern enough to |
531 |
|
have 'sysconf'? And not check for 'getpagesize'? */ |
532 |
|
#if defined(HAVE_GETPAGESIZE) |
533 |
|
pagesize = getpagesize (); |
534 |
|
#elif defined(HAVE_SYSCONF) |
535 |
|
pagesize = sysconf (_SC_PAGESIZE); |
536 |
|
#else |
537 |
|
JCL_ThrowException (env, IO_EXCEPTION, |
538 |
|
"can't determine memory page size"); |
539 |
|
return NULL; |
540 |
|
#endif /* HAVE_GETPAGESIZE/HAVE_SYSCONF */ |
541 |
|
|
542 |
|
#if (SIZEOF_VOID_P == 4) |
543 |
|
RawData_class = (*env)->FindClass (env, "gnu/classpath/RawData32"); |
544 |
|
if (RawData_class != NULL) |
545 |
|
{ |
546 |
|
RawData_init = (*env)->GetMethodID (env, RawData_class, |
547 |
|
"<init>", "(I)V"); |
548 |
|
} |
549 |
|
#elif (SIZEOF_VOID_P == 8) |
550 |
|
RawData_class = (*env)->FindClass (env, "gnu/classpath/RawData64"); |
551 |
|
if (RawData_class != NULL) |
552 |
|
{ |
553 |
|
RawData_init = (*env)->GetMethodID (env, RawData_class, |
554 |
|
"<init>", "(J)V"); |
555 |
|
} |
556 |
|
#else |
557 |
|
JCL_ThrowException (env, IO_EXCEPTION, |
558 |
|
"pointer size not supported"); |
559 |
|
return NULL; |
560 |
|
#endif /* SIZEOF_VOID_P */ |
561 |
|
|
562 |
|
if ((*env)->ExceptionOccurred (env)) |
563 |
|
{ |
564 |
|
return NULL; |
565 |
|
} |
566 |
|
|
567 |
|
prot = PROT_READ; |
568 |
|
if (mode == '+') |
569 |
|
prot |= PROT_WRITE; |
570 |
|
flags = (mode == 'c' ? MAP_PRIVATE : MAP_SHARED); |
571 |
|
fd = get_native_fd (env, obj); |
572 |
|
p = mmap (NULL, (size_t) ALIGN_UP (size, pagesize), prot, flags, |
573 |
|
fd, ALIGN_DOWN (position, pagesize)); |
574 |
|
if (p == MAP_FAILED) |
575 |
|
{ |
576 |
|
JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); |
577 |
|
return NULL; |
578 |
|
} |
579 |
|
|
580 |
|
/* Unalign the mapped value back up, since we aligned offset |
581 |
|
down to a multiple of the page size. */ |
582 |
|
address = p + (position % pagesize); |
583 |
|
|
584 |
|
#if (SIZEOF_VOID_P == 4) |
585 |
|
RawData_instance = (*env)->NewObject (env, RawData_class, |
586 |
|
RawData_init, (jint) address); |
587 |
|
#elif (SIZEOF_VOID_P == 8) |
588 |
|
RawData_instance = (*env)->NewObject (env, RawData_class, |
589 |
|
RawData_init, (jlong) address); |
590 |
|
#endif /* SIZEOF_VOID_P */ |
591 |
|
|
592 |
|
MappedByteBufferImpl_class = (*env)->FindClass (env, |
593 |
|
"java/nio/MappedByteBufferImpl"); |
594 |
|
if (MappedByteBufferImpl_class != NULL) |
595 |
|
{ |
596 |
|
MappedByteBufferImpl_init = |
597 |
|
(*env)->GetMethodID (env, MappedByteBufferImpl_class, |
598 |
|
"<init>", "(Lgnu/classpath/RawData;IZ)V"); |
599 |
|
} |
600 |
|
|
601 |
|
if ((*env)->ExceptionOccurred (env)) |
602 |
|
{ |
603 |
|
munmap (p, ALIGN_UP (size, pagesize)); |
604 |
|
return NULL; |
605 |
|
} |
606 |
|
|
607 |
|
buffer = (*env)->NewObject (env, MappedByteBufferImpl_class, |
608 |
|
MappedByteBufferImpl_init, RawData_instance, |
609 |
|
(jint) size, mode == 'r'); |
610 |
|
return buffer; |
611 |
|
#else |
612 |
|
(void) obj; |
613 |
|
(void) mode; |
614 |
|
(void) position; |
615 |
|
(void) size; |
616 |
JCL_ThrowException (env, IO_EXCEPTION, |
JCL_ThrowException (env, IO_EXCEPTION, |
617 |
"java.nio.FileChannelImpl.nio_mmap_file(): not implemented"); |
"memory-mapped files not implemented"); |
618 |
return 0; |
return 0; |
619 |
|
#endif /* HAVE_MMAP */ |
620 |
} |
} |
621 |
|
|
622 |
/* |
/* |