summaryrefslogtreecommitdiffstats
path: root/src/H5FD.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-02-10 17:26:09 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-02-10 17:26:09 (GMT)
commit24d8506dd564c5cc0fdebb5ebdfaec7bda5a7435 (patch)
tree6b2eb3bb1e782c40718204882428e6471b6281ac /src/H5FD.c
parent738661ab9f409b8d961ba1402d6c4dd5f99ecb43 (diff)
downloadhdf5-24d8506dd564c5cc0fdebb5ebdfaec7bda5a7435.zip
hdf5-24d8506dd564c5cc0fdebb5ebdfaec7bda5a7435.tar.gz
hdf5-24d8506dd564c5cc0fdebb5ebdfaec7bda5a7435.tar.bz2
[svn-r6387] Purpose:
Bug Fix Description: Metadata cache in parallel I/O can cause hangs in applications which perform independent I/O on chunked datasets, because the metadata cache can attempt to flush out dirty metadata from only a single process, instead of collectively from all processes. Solution: Pass a dataset transfer property list down from every API function which could possibly trigger metadata I/O. Then, split the metadata cache into two sets of entries to allow dirty metadata to be set aside when a hash table collision occurs during independent I/O. Platforms tested: Tested h5committest {arabica (fortran), eirene (fortran, C++) modi4 (parallel, fortran)} FreeBSD 4.7 (sleipnir) serial & parallel Misc. update: Updated release_docs/RELEASE
Diffstat (limited to 'src/H5FD.c')
-rw-r--r--src/H5FD.c132
1 files changed, 78 insertions, 54 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index 7c2c701..c4ff8f8 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -33,7 +33,7 @@ static int interface_initialize_g = 0;
/* static prototypes */
static herr_t H5FD_init_interface(void);
static herr_t H5FD_free_cls(H5FD_class_t *cls);
-static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size);
+static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
/* Declare a free list to manage the H5FD_free_t struct */
H5FL_DEFINE(H5FD_free_t);
@@ -596,32 +596,34 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *
-H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl)
+herr_t
+H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl, void **copied_dxpl)
{
void *new_dxpl = NULL;
H5FD_class_t *driver=NULL;
- void *ret_value; /* Return value */
+ herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_dxpl_copy, NULL);
+ FUNC_ENTER_NOAPI(H5FD_dxpl_copy, FAIL);
/* Check args */
if (NULL==(driver=H5I_object(driver_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver ID");
- if (!old_dxpl)
- HGOTO_DONE(NULL); /*but no error*/
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID");
- /* Allow the driver to copy or do it ourselves */
- if (driver->dxpl_copy) {
- new_dxpl = (driver->dxpl_copy)(old_dxpl);
- } else if (driver->dxpl_size>0) {
- new_dxpl = H5MM_malloc(driver->dxpl_size);
- HDmemcpy(new_dxpl, old_dxpl, driver->dxpl_size);
- } else
- HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "no way to copy driver file access property list");
+ /* Copy old dxpl, if one exists */
+ if (old_dxpl) {
+ /* Allow the driver to copy or do it ourselves */
+ if (driver->dxpl_copy) {
+ new_dxpl = (driver->dxpl_copy)(old_dxpl);
+ } else if (driver->dxpl_size>0) {
+ new_dxpl = H5MM_malloc(driver->dxpl_size);
+ assert(new_dxpl);
+ HDmemcpy(new_dxpl, old_dxpl, driver->dxpl_size);
+ } else
+ HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "no way to copy driver file access property list");
+ } /* end if */
- /* Set return value */
- ret_value=new_dxpl;
+ /* Set copied value */
+ *copied_dxpl=new_dxpl;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1171,7 +1173,7 @@ done:
*-------------------------------------------------------------------------
*/
haddr_t
-H5FDalloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
+H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
{
haddr_t ret_value = HADDR_UNDEF;
@@ -1185,9 +1187,14 @@ H5FDalloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid request type");
if (size<=0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "zero-size request");
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list");
/* Do the real work */
- if (HADDR_UNDEF==(ret_value=H5FD_alloc(file, type, size)))
+ if (HADDR_UNDEF==(ret_value=H5FD_alloc(file, type, dxpl_id, size)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "unable to allocate file memory");
done:
@@ -1214,7 +1221,7 @@ done:
*-------------------------------------------------------------------------
*/
haddr_t
-H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
+H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
{
haddr_t ret_value = HADDR_UNDEF;
H5FD_mem_t mapped_type;
@@ -1451,7 +1458,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
/* Check if the block asked for is too large for a metadata block */
if(size>=file->def_meta_block_size) {
/* Allocate more room for this new block the regular way */
- new_meta=H5FD_real_alloc(file,type,size);
+ new_meta=H5FD_real_alloc(file,type,dxpl_id,size);
/* Check if the new metadata is at the end of the current metadata block */
if(file->eoma+file->cur_meta_block_size==new_meta) {
@@ -1470,7 +1477,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
} /* end if */
else {
/* Allocate another metadata block */
- new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,file->def_meta_block_size);
+ new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,dxpl_id,file->def_meta_block_size);
/* Check if the new metadata is at the end of the current metadata block */
if(file->eoma+file->cur_meta_block_size==new_meta) {
@@ -1479,7 +1486,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
else {
/* Return the unused portion of the metadata block to a free list */
if(file->eoma!=0)
- if(H5FD_free(file,H5FD_MEM_DEFAULT,file->eoma,file->cur_meta_block_size)<0)
+ if(H5FD_free(file,H5FD_MEM_DEFAULT,dxpl_id,file->eoma,file->cur_meta_block_size)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free metadata block");
/* Point the metadata block at the newly allocated block */
@@ -1502,7 +1509,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
} /* end else */
} /* end if */
else { /* Allocate data the regular way */
- ret_value=H5FD_real_alloc(file,type,size);
+ ret_value=H5FD_real_alloc(file,type,dxpl_id,size);
} /* end else */
} /* end if */
else { /* Allocate "raw" data */
@@ -1519,7 +1526,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
/* Check if the block asked for is too large for the "small data" block */
if(size>=file->def_sdata_block_size) {
/* Allocate more room for this new block the regular way */
- new_data=H5FD_real_alloc(file,type,size);
+ new_data=H5FD_real_alloc(file,type,dxpl_id,size);
/* Check if the new raw data is at the end of the current "small data" block */
if(file->eosda+file->cur_sdata_block_size==new_data) {
@@ -1539,7 +1546,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
} /* end if */
else {
/* Allocate another "small data" block */
- new_data=H5FD_real_alloc(file,type,file->def_sdata_block_size);
+ new_data=H5FD_real_alloc(file,type,dxpl_id,file->def_sdata_block_size);
/* Check if the new raw data is at the end of the current "small data" block */
if(file->eosda+file->cur_sdata_block_size==new_data) {
@@ -1548,7 +1555,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
else {
/* Return the unused portion of the "small data" block to a free list */
if(file->eosda!=0)
- if(H5FD_free(file,H5FD_MEM_DRAW,file->eosda,file->cur_sdata_block_size)<0)
+ if(H5FD_free(file,H5FD_MEM_DRAW,dxpl_id,file->eosda,file->cur_sdata_block_size)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free 'small data' block");
/* Point the "small data" block at the newly allocated block */
@@ -1571,7 +1578,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
} /* end else */
} /* end if */
else { /* Allocate data the regular way */
- ret_value=H5FD_real_alloc(file,type,size);
+ ret_value=H5FD_real_alloc(file,type,dxpl_id,size);
} /* end else */
} /* end else */
@@ -1599,7 +1606,7 @@ done:
*-------------------------------------------------------------------------
*/
static haddr_t
-H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
+H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
{
haddr_t ret_value = HADDR_UNDEF;
@@ -1615,7 +1622,7 @@ H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
* marker
*/
if (file->cls->alloc) {
- ret_value = (file->cls->alloc)(file, type, size);
+ ret_value = (file->cls->alloc)(file, type, dxpl_id, size);
if (HADDR_UNDEF==ret_value)
HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver allocation request failed");
} else {
@@ -1653,7 +1660,7 @@ H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
/* Free the wasted memory */
if (wasted)
- H5FDfree(file, type, oldeoa, wasted);
+ H5FD_free(file, type, dxpl_id, oldeoa, wasted);
#ifdef H5F_DEBUG
if (file->alignment * file->threshold != 1 && H5DEBUG(F)) {
@@ -1692,7 +1699,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FDfree(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
+H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -1704,9 +1711,14 @@ H5FDfree(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer");
if (type<0 || type>=H5FD_MEM_NTYPES)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request type");
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
/* Do the real work */
- if (H5FD_free(file, type, addr, size)<0)
+ if (H5FD_free(file, type, dxpl_id, addr, size)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file deallocation request failed");
done:
@@ -1731,7 +1743,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
+H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
{
H5FD_mem_t mapped_type;
herr_t ret_value=SUCCEED; /* Return value */
@@ -1812,7 +1824,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
H5_ASSIGN_OVERFLOW(tail_size,(file->accum_loc+file->accum_size)-tail_addr,haddr_t,size_t);
/* Write out the part of the accumulator after the block to free */
- if (H5FD_write(file, H5FD_MEM_DEFAULT, H5P_DATASET_XFER_DEFAULT, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0)
+ if (H5FD_write(file, H5FD_MEM_DEFAULT, dxpl_id, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0)
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed");
} /* end if */
@@ -1937,7 +1949,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
}
}
} else if (file->cls->free) {
- if ((file->cls->free)(file, type, addr, size)<0)
+ if ((file->cls->free)(file, type, dxpl_id, addr, size)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed");
} else {
/* leak memory */
@@ -1967,7 +1979,7 @@ done:
*-------------------------------------------------------------------------
*/
haddr_t
-H5FDrealloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
+H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
hsize_t new_size)
{
haddr_t ret_value=HADDR_UNDEF;
@@ -1975,7 +1987,14 @@ H5FDrealloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
FUNC_ENTER_API(H5FDrealloc, HADDR_UNDEF);
H5TRACE5("a","xMtahh",file,type,old_addr,old_size,new_size);
- if (HADDR_UNDEF==(ret_value=H5FD_realloc(file, type, old_addr, old_size, new_size)))
+ /* Check args */
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list");
+
+ if (HADDR_UNDEF==(ret_value=H5FD_realloc(file, type, dxpl_id, old_addr, old_size, new_size)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file reallocation request failed");
done:
@@ -2001,7 +2020,7 @@ done:
*-------------------------------------------------------------------------
*/
haddr_t
-H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
+H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
hsize_t new_size)
{
haddr_t new_addr=old_addr;
@@ -2017,17 +2036,17 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
} else if (0==old_size) {
/* allocate memory */
assert(!H5F_addr_defined(old_addr));
- if (HADDR_UNDEF==(new_addr=H5FDalloc(file, type, new_size)))
+ if (HADDR_UNDEF==(new_addr=H5FD_alloc(file, type, dxpl_id, new_size)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed");
} else if (0==new_size) {
/* free memory */
assert(H5F_addr_defined(old_addr));
- H5FDfree(file, type, old_addr, old_size);
+ H5FD_free(file, type, dxpl_id, old_addr, old_size);
new_addr = HADDR_UNDEF;
} else if (new_size<old_size) {
/* free the end of the block */
- H5FDfree(file, type, old_addr+old_size, old_size-new_size);
+ H5FD_free(file, type, dxpl_id, old_addr+old_size, old_size-new_size);
} else {
/* move memory to new location */
/* Note! This may fail if sizeof(hsize_t)>sizeof(size_t) and the
@@ -2036,23 +2055,23 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
* to move pieces of the realloced data through a fixed size buffer, etc.
* -QAK, 6/20/01
*/
- if (HADDR_UNDEF==(new_addr=H5FDalloc(file, type, new_size)))
+ if (HADDR_UNDEF==(new_addr=H5FD_alloc(file, type, dxpl_id, new_size)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed");
H5_CHECK_OVERFLOW(old_size,hsize_t,size_t);
if (old_size>sizeof(_buf) && NULL==(buf=H5MM_malloc((size_t)old_size))) {
- H5FDfree(file, type, new_addr, new_size);
+ H5FD_free(file, type, dxpl_id, new_addr, new_size);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed");
}
- if (H5FDread(file, type, H5P_DEFAULT, old_addr, (size_t)old_size, buf)<0 ||
- H5FDwrite(file, type, H5P_DEFAULT, new_addr, (size_t)old_size, buf)<0) {
- H5FDfree(file, type, new_addr, new_size);
+ if (H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf)<0 ||
+ H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf)<0) {
+ H5FD_free(file, type, dxpl_id, new_addr, new_size);
H5MM_xfree(buf);
HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block");
}
if (buf!=_buf)
H5MM_xfree(buf);
- H5FDfree(file, type, old_addr, old_size);
+ H5FD_free(file, type, dxpl_id, old_addr, old_size);
}
/* Set return value */
@@ -2846,7 +2865,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FDflush(H5FD_t *file, unsigned closing)
+H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -2856,9 +2875,14 @@ H5FDflush(H5FD_t *file, unsigned closing)
/* Check args */
if (!file || !file->cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer");
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
/* Do the real work */
- if (H5FD_flush(file,closing)<0)
+ if (H5FD_flush(file,dxpl_id,closing)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file flush request failed");
done:
@@ -2885,7 +2909,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_flush(H5FD_t *file, unsigned closing)
+H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -2897,14 +2921,14 @@ H5FD_flush(H5FD_t *file, unsigned closing)
if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) && file->accum_dirty && file->accum_size>0) {
/* Flush the metadata contents */
/* Not certain if the type and dxpl should be the way they are... -QAK */
- if ((file->cls->write)(file, H5FD_MEM_DEFAULT, H5P_DATASET_XFER_DEFAULT, file->accum_loc, file->accum_size, file->meta_accum)<0)
+ if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed");
/* Reset the dirty flag */
file->accum_dirty=FALSE;
} /* end if */
- if (file->cls->flush && (file->cls->flush)(file,closing)<0)
+ if (file->cls->flush && (file->cls->flush)(file,dxpl_id,closing)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed");
done: