[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:
Raymond Lu 2007-02-28 11:54:50 -05:00
parent a9d32e4896
commit c8ba250a1e
6 changed files with 34 additions and 157 deletions

94
configure vendored
View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;