summaryrefslogtreecommitdiffstats
path: root/src/H5FDdirect.c
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2006-10-27 02:41:19 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2006-10-27 02:41:19 (GMT)
commit0f040c40f0b8759ea7af6b2dcbf6bb75e92e34dd (patch)
tree2721acae3ea82a76bc35e814b4ab129184052f94 /src/H5FDdirect.c
parent469f6d30b1b6641f62bda85f31ca2b3c03dba428 (diff)
downloadhdf5-0f040c40f0b8759ea7af6b2dcbf6bb75e92e34dd.zip
hdf5-0f040c40f0b8759ea7af6b2dcbf6bb75e92e34dd.tar.gz
hdf5-0f040c40f0b8759ea7af6b2dcbf6bb75e92e34dd.tar.bz2
[svn-r12820] Added fragmental copy buffer to H5FD_direct_write. This buffer size is set through
H5Pset_fapl_direct. It's been added to H5FD_direct_read in the previous checkin. Still, a test is needed at later checkin.
Diffstat (limited to 'src/H5FDdirect.c')
-rw-r--r--src/H5FDdirect.c218
1 files changed, 131 insertions, 87 deletions
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index 93a64f5..bf826aa 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -50,9 +50,9 @@ static hid_t H5FD_DIRECT_g = 0;
/* Driver-specific file access properties */
typedef struct H5FD_direct_fapl_t {
- hsize_t mboundary; /* Memory boundary for alignment */
- hsize_t fbsize; /* File system block size */
- hsize_t cbsize; /* Maximal buffer size for copying user data */
+ size_t mboundary; /* Memory boundary for alignment */
+ size_t fbsize; /* File system block size */
+ size_t cbsize; /* Maximal buffer size for copying user data */
} H5FD_direct_fapl_t;
/*
@@ -306,7 +306,7 @@ H5FD_direct_term(void)
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_fapl_direct(hid_t fapl_id, hsize_t boundary, hsize_t block_size, hsize_t cbuf_size)
+H5Pset_fapl_direct(hid_t fapl_id, size_t boundary, size_t block_size, size_t cbuf_size)
{
H5P_genplist_t *plist; /* Property list pointer */
H5FD_direct_fapl_t fa;
@@ -360,8 +360,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Pget_fapl_direct(hid_t fapl_id, hsize_t *boundary/*out*/, hsize_t *block_size/*out*/,
- hsize_t *cbuf_size/*out*/)
+H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/, size_t *block_size/*out*/,
+ size_t *cbuf_size/*out*/)
{
H5FD_direct_fapl_t *fa;
H5P_genplist_t *plist; /* Property list pointer */
@@ -861,13 +861,13 @@ 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;
- size_t alloc_size, tmp_size;
+ size_t alloc_size, dup_size;
void *copy_buf, *p1, *p2, *p3;
- hsize_t _boundary;
- hsize_t _fbsize;
- hsize_t _cbsize;
+ size_t _boundary;
+ size_t _fbsize;
+ size_t _cbsize;
haddr_t copy_addr = addr;
- hsize_t copy_size = size;
+ size_t copy_size = size;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_direct_read, FAIL)
@@ -893,7 +893,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
/* if the data is aligned, read it directly from the file. If not, read a bigger
* and aligned data first, then copy the data into memory buffer.
*/
- if((addr%_fbsize==0) && (size%_fbsize==0) && ((haddr_t)buf%_boundary==0)) {
+ if((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)
@@ -945,10 +945,10 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
* partial results, and the end of the file. */
memset(copy_buf, 0, alloc_size);
p1 = copy_buf;
- tmp_size = alloc_size;
- while(tmp_size > 0) {
+ dup_size = alloc_size;
+ while(dup_size > 0) {
do {
- nbytes = HDread(file->fd, p1, tmp_size);
+ nbytes = HDread(file->fd, p1, dup_size);
} while(-1==nbytes && EINTR==errno);
if (-1==nbytes) /* error */
@@ -958,10 +958,10 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
break;
} else {
assert(nbytes>0);
- assert((size_t)nbytes<=tmp_size);
+ assert((size_t)nbytes<=dup_size);
H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- tmp_size -= (size_t)nbytes;
+ dup_size -= (size_t)nbytes;
p1 = (unsigned char*)p1 + nbytes;
}
}
@@ -970,29 +970,30 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
* Consider all possible situations here: file address is not aligned on
* file block size; the end of data address is not aligned; the end of data
* address is aligned; data size is smaller or bigger than maximal copy size.*/
- p2 = (unsigned char*)copy_buf + copy_addr % _fbsize;
+ p2 = (unsigned char*)copy_buf + (size_t)(copy_addr % _fbsize);
if(size < _cbsize)
memcpy(p3, p2, size);
- else if(size >= _cbsize && copy_size <= alloc_size)
+ else if(size >= _cbsize && copy_size <= (alloc_size-(size_t)(copy_addr%_fbsize)))
memcpy(p3, p2, copy_size);
- else if(size >= _cbsize && copy_size > alloc_size) {
- memcpy(p3, p2, (alloc_size - copy_addr % _fbsize));
- p3 = (unsigned char*)p3 + (alloc_size - copy_addr % _fbsize);
+ else if(size >= _cbsize && copy_size > (alloc_size-(size_t)(copy_addr%_fbsize))) {
+ memcpy(p3, p2, (alloc_size - (size_t)(copy_addr % _fbsize)));
+ p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
}
/* update the size and address of data being read. */
- if(copy_size > (alloc_size - copy_addr % _fbsize))
- copy_size -= (alloc_size - copy_addr % _fbsize);
+ if(copy_size > (alloc_size - (size_t)(copy_addr % _fbsize)))
+ copy_size -= (alloc_size - (size_t)(copy_addr % _fbsize));
else
copy_size = 0;
- copy_addr += (alloc_size - copy_addr % _fbsize);
+ copy_addr += (alloc_size - (size_t)(copy_addr % _fbsize));
} while (copy_size > 0);
/*Final step: update address and buffer*/
addr += (haddr_t)size;
buf = (unsigned char*)buf + size;
- HDfree(copy_buf);
+ if(copy_buf)
+ HDfree(copy_buf);
}
/* Update current position */
@@ -1035,10 +1036,12 @@ 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;
size_t alloc_size, dup_size;
- void *copy_buf, *p1, *p2;
- hsize_t _boundary;
- hsize_t _fbsize;
- hsize_t _cbsize;
+ void *copy_buf, *p1, *p2, *p3;
+ size_t _boundary;
+ size_t _fbsize;
+ size_t _cbsize;
+ haddr_t copy_addr = addr;
+ size_t copy_size = size;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_direct_write, FAIL)
@@ -1065,7 +1068,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
* the aligned data first, update buffer with user data, then write the
* data out.
*/
- if((addr%_fbsize==0) && (size%_fbsize==0) && ((haddr_t)buf%_boundary==0)) {
+ if((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)
@@ -1086,78 +1089,119 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
buf = (const char*)buf + nbytes;
}
} else {
- /* allocate memory needed for the Direct IO option. Make a
- * bigger buffer for aligned I/O
+ /* allocate memory needed for the Direct IO option up to the maximal
+ * copy buffer size. Make a bigger buffer for aligned I/O if size is
+ * smaller than maximal copy buffer.
*/
- alloc_size = (size / _fbsize + 1) * _fbsize + _fbsize;
+ if(size < _cbsize)
+ alloc_size = (size / _fbsize + 1) * _fbsize + _fbsize;
+ else
+ alloc_size = _cbsize;
+/*printf("alloc_size=%ld, size=%ld, _fbsize=%ld, _cbsize=%ld\n", alloc_size, size, _fbsize,
+_cbsize);*/
if (posix_memalign(&copy_buf, _boundary, alloc_size) != 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "posix_memalign failed")
- memset(copy_buf, 0, alloc_size);
/* look for the right position for reading the data */
- if(file_seek(file->fd, (file_offset_t)(addr - addr % _fbsize), SEEK_SET) < 0)
+ if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0)
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- /*
- * Read the aligned data first, being careful of interrupted system calls,
- * partial results, and the end of the file.
- */
- p2 = copy_buf;
- dup_size = alloc_size;
- while(dup_size > 0) {
- do {
- nbytes = read(file->fd, p2, dup_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 */
- break;
- } else {
- assert(nbytes>0);
- assert((size_t)nbytes<=dup_size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- dup_size -= (size_t)nbytes;
- p2 = (unsigned char*)p2 + nbytes;
+ p3 = buf;
+ do {
+ /*
+ * Read the aligned data first if the aligned region doesn't fall entirely in
+ * the range to be writen. Be careful of interrupted system calls, partial
+ * results, and the end of the file.
+ */
+ memset(copy_buf, 0, alloc_size);
+ p2 = copy_buf;
+ dup_size = alloc_size;
+ if(copy_addr <= addr || (copy_addr + alloc_size) >= (addr + size)) {
+ while(dup_size > 0) {
+ do {
+ nbytes = read(file->fd, p2, dup_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 */
+ break;
+ } else {
+ assert(nbytes>0);
+ assert((size_t)nbytes<=dup_size);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ dup_size -= (size_t)nbytes;
+ p2 = (unsigned char*)p2 + nbytes;
+ }
+ }
}
- }
- /*append or copy the data to be written to the aligned buffer.*/
- p1 = (unsigned char*)copy_buf + addr % _fbsize;
- memcpy(p1, buf, size);
+ /* look for the right position and append or copy the data to be written to
+ * the aligned buffer.
+ * Consider all possible situations here: file address is not aligned on
+ * file block size; the end of data address is not aligned; the end of data
+ * address is aligned; data size is smaller or bigger than maximal copy size.
+ */
+ p1 = (unsigned char*)copy_buf + (size_t)(copy_addr % _fbsize);
+ if(size < _cbsize)
+ memcpy(p1, p3, size);
+ else if(size >= _cbsize && copy_size <= (alloc_size-(size_t)(copy_addr%_fbsize))) {
+/*printf("copy_size=%d, alloc_size=%d, size=%d, copy_addr%_fbsize=%ld\n", copy_size, alloc_size,
+size, copy_addr%_fbsize);*/
+ memcpy(p1, p3, copy_size);
+ }else if(size >= _cbsize && copy_size > (alloc_size-(size_t)(copy_addr%_fbsize))) {
+ memcpy(p1, p3, (alloc_size - (size_t)(copy_addr % _fbsize)));
+ p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
+ }
+
+ /*look for the aligned position for writing the data*/
+ if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), 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 write.
+ * It doesn't truncate the extra data introduced by alignment because that step
+ * is done in H5FD_direct_flush.
+ */
+ p2 = copy_buf;
+ dup_size = alloc_size;
+ while (dup_size>0) {
+ do {
+ nbytes = HDwrite(file->fd, p2, dup_size);
+ } while (-1==nbytes && EINTR==errno);
- /*look for the aligned position for writing the data*/
- if(file_seek(file->fd, (file_offset_t)(addr - addr % _fbsize), SEEK_SET) < 0)
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+ if (-1==nbytes) { /* error */
+ HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ }
+ if (0==nbytes) {
+ /* end of file but not end of format address space */
+ break;
+ } else {
+ assert(nbytes>0);
+ assert((size_t)nbytes<=dup_size);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ dup_size -= (size_t)nbytes;
+ p2 = (unsigned char*)p2 + nbytes;
+ }
+ }
- /*
- * Write the data, being careful of interrupted system calls and partial write.
- * It doesn't truncate the extra data introduced by alignment because that step
- * is done in H5FD_direct_flush.
- */
- p2 = copy_buf;
- while (alloc_size>0) {
- do {
- nbytes = HDwrite(file->fd, p2, alloc_size);
- } while (-1==nbytes && EINTR==errno);
+ /* update the size and address of data being read. */
+ if(copy_size > (alloc_size - (size_t)(copy_addr % _fbsize)))
+ copy_size -= (alloc_size - (size_t)(copy_addr % _fbsize));
+ else
+ copy_size = 0;
- if (-1==nbytes) { /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
- }
- assert(nbytes>0);
- assert((size_t)nbytes<=alloc_size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- alloc_size -= (size_t)nbytes;
- p2 = (unsigned char*)p2 + nbytes;
- }
+ copy_addr += (alloc_size - (size_t)(copy_addr % _fbsize));
+ } while (copy_size > 0);
/*Update the address and size*/
addr += (haddr_t)size;
buf = (const char*)buf + size;
-
- HDfree(copy_buf);
+
+ if(copy_buf)
+ HDfree(copy_buf);
}
/* Update current position and eof */