mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-23 16:20:57 +08:00
[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.
This commit is contained in:
parent
a9d32e4896
commit
c8ba250a1e
94
configure
vendored
94
configure
vendored
@ -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.
|
||||
|
40
configure.in
40
configure.in
@ -2643,46 +2643,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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user