diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2007-02-28 16:54:50 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2007-02-28 16:54:50 (GMT) |
commit | c8ba250a1e2db0d4d66705a131841f5cc1c86a2d (patch) | |
tree | 3143dad02fe5398332cd5c1bd8f457d19190f90c | |
parent | a9d32e4896e6577a0fa8380632f45b7f82a34fcb (diff) | |
download | hdf5-c8ba250a1e2db0d4d66705a131841f5cc1c86a2d.zip hdf5-c8ba250a1e2db0d4d66705a131841f5cc1c86a2d.tar.gz hdf5-c8ba250a1e2db0d4d66705a131841f5cc1c86a2d.tar.bz2 |
[svn-r13432] Changed the detection of alignment requirement for Direct I/O from configuration to run-time
detection in H5FD_direct_open in H5FDdirect.c.
-rwxr-xr-x | configure | 94 | ||||
-rw-r--r-- | configure.in | 40 | ||||
-rw-r--r-- | src/H5FDdirect.c | 46 | ||||
-rw-r--r-- | src/H5config.h.in | 3 | ||||
-rw-r--r-- | test/dtypes.c | 2 | ||||
-rw-r--r-- | test/vfd.c | 6 |
6 files changed, 34 insertions, 157 deletions
@@ -58016,100 +58016,6 @@ 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 { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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 core.conftest.* 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 was given. diff --git a/configure.in b/configure.in index ae39c27..eadf1fe 100644 --- a/configure.in +++ b/configure.in @@ -2644,46 +2644,6 @@ 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 dnl checked and data conversion exceptions are returned. This is mainly dnl for the speed optimization of hard conversions. Soft conversions can diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 1e87484..81bd5df 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -54,6 +54,7 @@ typedef struct H5FD_direct_fapl_t { size_t mboundary; /* Memory boundary for alignment */ size_t fbsize; /* File system block size */ size_t cbsize; /* Maximal buffer size for copying user data */ + hbool_t must_align; /* Decides if data alignment is required */ } H5FD_direct_fapl_t; /* @@ -332,6 +333,9 @@ H5Pset_fapl_direct(hid_t fapl_id, size_t boundary, size_t block_size, size_t cbu else fa.cbsize = CBSIZE_DEF; + /* Set the default to be true for data alignment */ + fa.must_align = TRUE; + /* Copy buffer size must be a multiple of file block size */ if(fa.cbsize % fa.fbsize != 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "copy buffer size must be a multiple of block size") @@ -493,6 +497,7 @@ H5FD_direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxadd #endif h5_stat_t sb; H5P_genplist_t *plist; /* Property list */ + int *buf; H5FD_t *ret_value; FUNC_ENTER_NOAPI(H5FD_direct_open, NULL) @@ -556,6 +561,27 @@ H5FD_direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxadd file->fa.fbsize = fa->fbsize; file->fa.cbsize = fa->cbsize; + /* Try to decide if data alignment is required. The reason to check it here + * is to handle correctly the case that the file is in a different file system + * than the one where the program is running. + */ + buf = (int*)HDmalloc(sizeof(int)); + if(o_flags &= O_CREAT) { + if(write(file->fd, (void*)buf, sizeof(int))<0) + file->fa.must_align = TRUE; + else { + file->fa.must_align = FALSE; + file_truncate(file->fd, (file_offset_t)0); + } + } else { + if(read(file->fd, (void*)buf, sizeof(int))<0) + file->fa.must_align = TRUE; + else + file->fa.must_align = FALSE; + } + if(buf) + HDfree(buf); + /* Set return value */ ret_value=(H5FD_t*)file; @@ -868,7 +894,7 @@ 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; - hbool_t must_align = TRUE; + hbool_t _must_align = TRUE; herr_t ret_value=SUCCEED; /* Return value */ size_t alloc_size; void *copy_buf, *p2, *p3; @@ -891,12 +917,10 @@ 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") -#ifndef H5_HAVE_DIRECT_ALIGN /* If the system doesn't require data to be aligned, read the data in * the same way as sec2 driver. */ - must_align = FALSE; -#endif + _must_align = file->fa.must_align; /* Get the memory boundary for alignment, file system block size, and maximal * copy buffer size. @@ -909,7 +933,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha * read it directly from the file. If not, read a bigger * and aligned data first, then copy the data into memory buffer. */ - if(!must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) { + if(!_must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) { /* Seek to the correct location */ if ((addr!=file->pos || OP_READ!=file->op) && file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) @@ -1040,7 +1064,7 @@ 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; - hbool_t must_align = TRUE; + hbool_t _must_align = TRUE; herr_t ret_value=SUCCEED; /* Return value */ size_t alloc_size; void *copy_buf, *p1, *p3; @@ -1063,12 +1087,10 @@ 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") -#ifndef H5_HAVE_DIRECT_ALIGN /* If the system doesn't require data to be aligned, read the data in * the same way as sec2 driver. */ - must_align = FALSE; -#endif + _must_align = file->fa.must_align; /* Get the memory boundary for alignment, file system block size, and maximal * copy buffer size. @@ -1081,7 +1103,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h * write it directly to the file. If not, read a bigger and aligned data * first, update buffer with user data, then write the data out. */ - if(!must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) { + if(!_must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) { /* Seek to the correct location */ if ((addr!=file->pos || OP_WRITE!=file->op) && file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) @@ -1257,15 +1279,13 @@ H5FD_direct_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) file->pos = HADDR_UNDEF; file->op = OP_UNKNOWN; } -#ifdef H5_HAVE_DIRECT_ALIGN - else { + else if (file->fa.must_align){ /*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 b373565..2804109 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -61,9 +61,6 @@ /* 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/dtypes.c b/test/dtypes.c index fba910b..e32a0a9 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1965,7 +1965,7 @@ test_compound_11(void) for(u=0; u<NTESTELEM; u++) { ((big_t *)buf)[u].d1=(double)u*(double)1.5; ((big_t *)buf)[u].d2=(double)u*(double)2.5; - ((big_t *)buf)[u].d2=(double)u*(double)3.5; + ((big_t *)buf)[u].d3=(double)u*(double)3.5; ((big_t *)buf)[u].i1=u*3; ((big_t *)buf)[u].i2=u*5; ((big_t *)buf)[u].s1=HDmalloc(32); @@ -215,7 +215,6 @@ 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) @@ -223,11 +222,6 @@ 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; |