summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-rw-r--r--src/H5FDdirect.c86
-rw-r--r--src/H5config.h.in3
2 files changed, 84 insertions, 5 deletions
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