summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2006-11-06 22:17:46 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2006-11-06 22:17:46 (GMT)
commit8e0a4a03c0a7923057eeb2b8b2ac16338fc87e76 (patch)
treee95317e9f70ba1bcfaab80b88e1368038ba1b2b1
parent2e8e42d6c9a229d0490cd97e9711fb707ad67578 (diff)
downloadhdf5-8e0a4a03c0a7923057eeb2b8b2ac16338fc87e76.zip
hdf5-8e0a4a03c0a7923057eeb2b8b2ac16338fc87e76.tar.gz
hdf5-8e0a4a03c0a7923057eeb2b8b2ac16338fc87e76.tar.bz2
[svn-r12870] Add a new macro H5_HAVE_DIRECT_ALIGN in configure.in. Some systems like copper and sleipnir
doesn't require alignment for Direct I/O. If this's true, write or read data just like sec2 does.
-rwxr-xr-xconfigure83
-rw-r--r--configure.in42
-rw-r--r--src/H5FDdirect.c86
-rw-r--r--src/H5config.h.in3
-rw-r--r--test/h5test.c2
-rw-r--r--test/vfd.c6
6 files changed, 215 insertions, 7 deletions
diff --git a/configure b/configure
index d4377b5..91c8792 100755
--- a/configure
+++ b/configure
@@ -51071,6 +51071,89 @@ else
fi
+
+if test ${hdf5_direct_io} = "yes"; then
+ echo "$as_me:$LINENO: checking for Direct VFD alignment requirement" >&5
+echo $ECHO_N "checking for Direct VFD alignment requirement... $ECHO_C" >&6
+
+ if test "${hdf5_direct_align+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ int main(void)
+ {
+ int *buf;
+ int fid;
+ fid=open("tst_file", O_CREAT | O_TRUNC | O_DIRECT | O_RDWR, 0755);
+ buf = (int*)malloc(sizeof(int));
+ if(write(fid, (void*)buf, sizeof(int))<0) {
+ close(fid);
+ free(buf);
+ remove("tst_file");
+ exit(1);
+ }
+ close(fid);
+ remove("tst_file");
+ free(buf);
+ exit (0);
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ hdf5_direct_align=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+hdf5_direct_align=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+
+ if test ${hdf5_direct_align} = "yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DIRECT_ALIGN 1
+_ACEOF
+
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+fi
+
echo "$as_me:$LINENO: checking whether exception handling functions is checked during data conversions" >&5
echo $ECHO_N "checking whether exception handling functions is checked during data conversions... $ECHO_C" >&6
# Check whether --enable-dconv-exception or --disable-dconv-exception was given.
diff --git a/configure.in b/configure.in
index fa13ecd..ff618c7 100644
--- a/configure.in
+++ b/configure.in
@@ -2572,7 +2572,7 @@ if test "$STREAM_VFD" = "yes"; then
fi
dnl ----------------------------------------------------------------------
-dnl Check if Direct I/O driver is wanted by --enable-direct-vfd
+dnl Check if Direct I/O driver is enabled by --enable-direct-vfd
dnl
AC_MSG_CHECKING([for Direct Virtual File Driver support])
@@ -2612,6 +2612,46 @@ else
fi
AM_CONDITIONAL([DIRECT_VFD_CONDITIONAL], [test "X$DIRECT_VFD" = "Xyes"])
+
+dnl ----------------------------------------------------------------------
+dnl Check if Direct I/O driver requires alignment.
+dnl
+
+if test ${hdf5_direct_io} = "yes"; then
+ AC_MSG_CHECKING([for Direct VFD alignment requirement])
+
+ AC_CACHE_VAL([hdf5_direct_align],
+ [AC_TRY_RUN([
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ int main(void)
+ {
+ int *buf;
+ int fid;
+ fid=open("tst_file", O_CREAT | O_TRUNC | O_DIRECT | O_RDWR, 0755);
+ buf = (int*)malloc(sizeof(int));
+ if(write(fid, (void*)buf, sizeof(int))<0) {
+ close(fid);
+ free(buf);
+ remove("tst_file");
+ exit(1);
+ }
+ close(fid);
+ remove("tst_file");
+ free(buf);
+ exit (0);
+ }], [hdf5_direct_align=no], [hdf5_direct_align=yes],)])
+
+ if test ${hdf5_direct_align} = "yes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_DIRECT_ALIGN], [1],
+ [Define if the direct I/O VFD requires alignment])
+ else
+ AC_MSG_RESULT([no])
+ fi
+fi
dnl ----------------------------------------------------------------------
dnl Decide whether the presence of user's exception handling functions is
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index 8a6a27a..89bf099 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -861,6 +861,8 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
{
H5FD_direct_t *file = (H5FD_direct_t*)_file;
ssize_t nbytes;
+ herr_t ret_value=SUCCEED; /* Return value */
+#ifdef H5_HAVE_DIRECT_ALIGN
size_t alloc_size;
void *copy_buf, *p2, *p3;
size_t _boundary;
@@ -868,7 +870,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
size_t _cbsize;
haddr_t copy_addr = addr;
size_t copy_size = size;
- herr_t ret_value=SUCCEED; /* Return value */
+#endif /*H5_HAVE_DIRECT_ALIGN*/
FUNC_ENTER_NOAPI(H5FD_direct_read, FAIL)
@@ -883,6 +885,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
if (addr+size>file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
+#ifdef H5_HAVE_DIRECT_ALIGN /* If the system requires data to be aligned */
/* Get the memory boundary for alignment, file system block size, and maximal
* copy buffer size.
*/
@@ -928,7 +931,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
else
alloc_size = _cbsize;
if (HDposix_memalign(&copy_buf, _boundary, alloc_size) != 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "posix_memalign failed")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "HDposix_memalign failed")
/* look for the aligned position for reading the data */
if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0)
@@ -985,6 +988,42 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
HDfree(copy_buf);
}
+#else /*H5_HAVE_DIRECT_ALIGN*/
+ /* If the system doesn't require data to be aligned, read the data in
+ * the same way as sec2 driver.
+ */
+
+ /* Seek to the correct location */
+ if ((addr!=file->pos || OP_READ!=file->op) &&
+ file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0)
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+
+ /*
+ * Read data, being careful of interrupted system calls, partial results,
+ * and the end of the file.
+ */
+ while (size>0) {
+ do {
+ nbytes = HDread(file->fd, buf, size);
+ } while (-1==nbytes && EINTR==errno);
+ if (-1==nbytes) /* error */
+ HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
+ if (0==nbytes) {
+ /* end of file but not end of format address space */
+ HDmemset(buf, 0, size);
+ break;
+ }
+ assert(nbytes>=0);
+ assert((size_t)nbytes<=size);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ size -= (size_t)nbytes;
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ addr += (haddr_t)nbytes;
+ buf = (char*)buf + nbytes;
+ }
+
+#endif /*H5_HAVE_DIRECT_ALIGN*/
+
/* Update current position */
file->pos = addr;
file->op = OP_READ;
@@ -1024,6 +1063,8 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
{
H5FD_direct_t *file = (H5FD_direct_t*)_file;
ssize_t nbytes;
+ herr_t ret_value=SUCCEED; /* Return value */
+#ifdef H5_HAVE_DIRECT_ALIGN
size_t alloc_size;
void *copy_buf, *p1, *p3;
size_t _boundary;
@@ -1031,7 +1072,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
size_t _cbsize;
haddr_t copy_addr = addr;
size_t copy_size = size;
- herr_t ret_value=SUCCEED; /* Return value */
+#endif /*H5_HAVE_DIRECT_ALIGN*/
FUNC_ENTER_NOAPI(H5FD_direct_write, FAIL)
@@ -1046,6 +1087,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
if (addr+size>file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
+#ifdef H5_HAVE_DIRECT_ALIGN /* If the system requires data to be aligned */
/* Get the memory boundary for alignment, file system block size, and maximal
* copy buffer size.
*/
@@ -1088,7 +1130,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
alloc_size = _cbsize;
if (HDposix_memalign(&copy_buf, _boundary, alloc_size) != 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "posix_memalign failed")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "HDposix_memalign failed")
/* look for the right position for reading the data */
if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0)
@@ -1162,6 +1204,37 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
HDfree(copy_buf);
}
+#else /*H5_HAVE_DIRECT_ALIGN*/
+ /* If the system doesn't require data to be aligned, write the data in
+ * the same way as sec2 driver.
+ */
+
+ /* Seek to the correct location */
+ if ((addr!=file->pos || OP_WRITE!=file->op) &&
+ file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0)
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+
+ /*
+ * Write the data, being careful of interrupted system calls and partial
+ * results
+ */
+ while (size>0) {
+ do {
+ nbytes = HDwrite(file->fd, buf, size);
+ } while (-1==nbytes && EINTR==errno);
+ if (-1==nbytes) /* error */
+ HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ assert(nbytes>0);
+ assert((size_t)nbytes<=size);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ size -= (size_t)nbytes;
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ addr += (haddr_t)nbytes;
+ buf = (const char*)buf + nbytes;
+ }
+
+#endif /*H5_HAVE_DIRECT_ALIGN*/
+
/* Update current position and eof */
file->pos = addr;
file->op = OP_WRITE;
@@ -1232,13 +1305,16 @@ H5FD_direct_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
/* Reset last file I/O information */
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
- } else {
+ }
+#ifdef H5_HAVE_DIRECT_ALIGN
+ else {
/*Even though eof is equal to eoa, file is still truncated because Direct I/O
*write introduces some extra data for alignment.
*/
if (-1==file_truncate(file->fd, (file_offset_t)file->eof))
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
}
+#endif /*H5_HAVE_DIRECT_ALIGN*/
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 0853964..998a616 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -57,6 +57,9 @@
/* Define if the direct I/O virtual file driver should be compiled */
#undef HAVE_DIRECT
+/* Define if the direct I/O VFD requires alignment */
+#undef HAVE_DIRECT_ALIGN
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
diff --git a/test/h5test.c b/test/h5test.c
index 840e126..93f992e 100644
--- a/test/h5test.c
+++ b/test/h5test.c
@@ -581,7 +581,7 @@ h5_fileaccess(void)
#ifdef H5_HAVE_DIRECT
/* Linux direct read() and write() system calls. Set memory boundary, file block size,
* and copy buffer size to the default values. */
- if (H5Pset_fapl_direct(fapl, 1024, 4096, 7*4096)<0) return -1;
+ if (H5Pset_fapl_direct(fapl, 1024, 4096, 8*4096)<0) return -1;
#endif
} else {
/* Unknown driver */
diff --git a/test/vfd.c b/test/vfd.c
index fdd710d..c8b67f7 100644
--- a/test/vfd.c
+++ b/test/vfd.c
@@ -214,6 +214,7 @@ test_direct(void)
if(file_size<1*KB || file_size>4*KB)
TEST_ERROR;
+#ifdef H5_HAVE_DIRECT_ALIGN
/* Allocate aligned memory for data set 1. For data set 1, everything is aligned including
* memory address, size of data, and file address. */
if(posix_memalign(&points, (size_t)FBSIZE, (size_t)(DSET1_DIM1*DSET1_DIM2*sizeof(int)))!=0)
@@ -221,6 +222,11 @@ test_direct(void)
if(posix_memalign(&check, (size_t)FBSIZE, (size_t)(DSET1_DIM1*DSET1_DIM2*sizeof(int)))!=0)
TEST_ERROR;
+#else
+ /* Allocate aligned memory for data set 1. No need for alignment. */
+ points=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int));
+ check=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int));
+#endif
/* Initialize the dset1 */
p1 = points;