diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2009-06-04 19:24:21 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2009-06-04 19:24:21 (GMT) |
commit | 94594831a96183fb7fcfa77697379db5df834ab5 (patch) | |
tree | 1c409db32a1dc1e7fff680b2f1e56de368a817d2 | |
parent | 3972bca34060b2691c51d461cb51d22892b76046 (diff) | |
download | hdf5-94594831a96183fb7fcfa77697379db5df834ab5.zip hdf5-94594831a96183fb7fcfa77697379db5df834ab5.tar.gz hdf5-94594831a96183fb7fcfa77697379db5df834ab5.tar.bz2 |
[svn-r17007] Description:
Final stage of connecting all the pieces of a chunked dataset with
an extensible array index together to fully enable SWMR-write access properly.
This change makes the dataset's object header depend on the extensible array
header, so that the extensible array must be fully synchronized to disk before
the object header (which contains possibly updated dimensions for the dataset)
is written to disk.
Tested on:
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Mac OS X/32 10.5.7 (amazon) in debug mode
Mac OS X/32 10.5.7 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
-rw-r--r-- | src/H5Dearray.c | 152 | ||||
-rw-r--r-- | src/H5Dpkg.h | 8 | ||||
-rw-r--r-- | src/H5Dproxy.c | 4 |
3 files changed, 146 insertions, 18 deletions
diff --git a/src/H5Dearray.c b/src/H5Dearray.c index bca9bb0..a1271f4 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -134,9 +134,9 @@ static herr_t H5D_earray_idx_copy_shutdown(H5O_layout_t *layout_src, static herr_t H5D_earray_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *size); static herr_t H5D_earray_idx_reset(H5O_layout_t *layout, hbool_t reset_addr); -static herr_t H5D_earray_idx_depend(const H5D_chk_idx_info_t *idx_info, +static herr_t H5D_earray_idx_support(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry); -static herr_t H5D_earray_idx_undepend(const H5D_chk_idx_info_t *idx_info, +static herr_t H5D_earray_idx_unsupport(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry); static herr_t H5D_earray_idx_dump(const H5D_chk_idx_info_t *idx_info, FILE *stream); @@ -162,8 +162,8 @@ const H5D_chunk_ops_t H5D_COPS_EARRAY[1] = {{ H5D_earray_idx_copy_shutdown, H5D_earray_idx_size, H5D_earray_idx_reset, - H5D_earray_idx_depend, - H5D_earray_idx_undepend, + H5D_earray_idx_support, + H5D_earray_idx_unsupport, H5D_earray_idx_dump, H5D_earray_idx_dest }}; @@ -598,6 +598,116 @@ H5D_earray_filt_debug(FILE *stream, int indent, int fwidth, hsize_t idx, /*------------------------------------------------------------------------- + * Function: H5D_earray_idx_depend + * + * Purpose: Create flush dependency between extensible array and dataset's + * object header. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, June 2, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_earray_idx_depend(const H5D_chk_idx_info_t *idx_info) +{ + H5O_loc_t oloc; /* Temporary object header location for dataset */ + H5O_t *oh = NULL; /* Dataset's object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_depend) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(H5D_CHUNK_EARRAY == idx_info->layout->u.chunk.idx_type); + HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.earray.addr)); + HDassert(idx_info->layout->u.chunk.u.earray.ea); + + /* Set up object header location for dataset */ + H5O_loc_reset(&oloc); + oloc.file = idx_info->f; + oloc.addr = idx_info->layout->u.chunk.u.earray.dset_ohdr_addr; + + /* Pin the dataset's object header */ + if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") + + /* Make the extensible array a child flush dependency of the dataset's object header */ + if(H5EA_depend((H5AC_info_t *)oh, idx_info->layout->u.chunk.u.earray.ea) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency on object header") + +done: + /* Unpin the dataset's object header */ + if(oh && H5O_unpin(&oloc, oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_earray_idx_depend() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_earray_idx_undepend + * + * Purpose: Remove flush dependency between extensible array and dataset's + * object header. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, June 2, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_earray_idx_undepend(const H5D_chk_idx_info_t *idx_info) +{ + H5O_loc_t oloc; /* Temporary object header location for dataset */ + H5O_t *oh = NULL; /* Dataset's object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_undepend) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(H5D_CHUNK_EARRAY == idx_info->layout->u.chunk.idx_type); + HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.earray.addr)); + HDassert(idx_info->layout->u.chunk.u.earray.ea); + + /* Set up object header location for dataset */ + H5O_loc_reset(&oloc); + oloc.file = idx_info->f; + oloc.addr = idx_info->layout->u.chunk.u.earray.dset_ohdr_addr; + + /* Pin the dataset's object header */ + if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") + + /* Remove the extensible array as a child flush dependency of the dataset's object header */ + if(H5EA_undepend((H5AC_info_t *)oh, idx_info->layout->u.chunk.u.earray.ea) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTUNDEPEND, FAIL, "unable to remove flush dependency on object header") + +done: + /* Unpin the dataset's object header */ + if(oh && H5O_unpin(&oloc, oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_earray_idx_undepend() */ + + +/*------------------------------------------------------------------------- * Function: H5D_earray_idx_open * * Purpose: Opens an existing extensible array. @@ -642,6 +752,12 @@ H5D_earray_idx_open(const H5D_chk_idx_info_t *idx_info) if(NULL == (idx_info->layout->u.chunk.u.earray.ea = H5EA_open(idx_info->f, idx_info->dxpl_id, idx_info->layout->u.chunk.u.earray.addr, cls, &udata))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open extensible array") + /* Check for SWMR writes to the file */ + if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) { + if(H5D_earray_idx_depend(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency on object header") + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_earray_idx_open() */ @@ -749,6 +865,12 @@ H5D_earray_idx_create(const H5D_chk_idx_info_t *idx_info) if(H5EA_get_addr(idx_info->layout->u.chunk.u.earray.ea, &(idx_info->layout->u.chunk.u.earray.addr)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query extensible array address") + /* Check for SWMR writes to the file */ + if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) { + if(H5D_earray_idx_depend(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency on object header") + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_earray_idx_create() */ @@ -1474,7 +1596,7 @@ H5D_earray_idx_reset(H5O_layout_t *layout, hbool_t reset_addr) /*------------------------------------------------------------------------- - * Function: H5D_earray_idx_depend + * Function: H5D_earray_idx_support * * Purpose: Create a dependency between a chunk [proxy] and the index * metadata that contains the record for the chunk. @@ -1487,14 +1609,14 @@ H5D_earray_idx_reset(H5O_layout_t *layout, hbool_t reset_addr) *------------------------------------------------------------------------- */ static herr_t -H5D_earray_idx_depend(const H5D_chk_idx_info_t *idx_info, +H5D_earray_idx_support(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry) { H5EA_t *ea; /* Pointer to extensible array structure */ hsize_t idx; /* Array index of chunk */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_depend) + FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_support) HDassert(idx_info); HDassert(udata); @@ -1521,11 +1643,11 @@ H5D_earray_idx_depend(const H5D_chk_idx_info_t *idx_info, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_earray_idx_depend() */ +} /* end H5D_earray_idx_support() */ /*------------------------------------------------------------------------- - * Function: H5D_earray_idx_undepend + * Function: H5D_earray_idx_unsupport * * Purpose: Remove a dependency between a chunk [proxy] and the index * metadata that contains the record for the chunk. @@ -1538,14 +1660,14 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_earray_idx_undepend(const H5D_chk_idx_info_t *idx_info, +H5D_earray_idx_unsupport(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry) { H5EA_t *ea; /* Pointer to extensible array structure */ hsize_t idx; /* Array index of chunk */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_undepend) + FUNC_ENTER_NOAPI_NOINIT(H5D_earray_idx_unsupport) HDassert(idx_info); HDassert(udata); @@ -1572,7 +1694,7 @@ H5D_earray_idx_undepend(const H5D_chk_idx_info_t *idx_info, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_earray_idx_undepend() */ +} /* end H5D_earray_idx_unsupport() */ /*------------------------------------------------------------------------- @@ -1631,6 +1753,12 @@ H5D_earray_idx_dest(const H5D_chk_idx_info_t *idx_info) /* Sanity check */ HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.earray.dset_ohdr_addr)); + /* Check for SWMR writes to the file */ + if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) { + if(H5D_earray_idx_undepend(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTUNDEPEND, FAIL, "unable to remove flush dependency on object header") + } /* end if */ + if(H5EA_close(idx_info->layout->u.chunk.u.earray.ea, idx_info->dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close extensible array") idx_info->layout->u.chunk.u.earray.ea = NULL; diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 6e15c16..b4bd631 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -285,9 +285,9 @@ typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_layout_t *layout_src, typedef herr_t (*H5D_chunk_size_func_t)(const H5D_chk_idx_info_t *idx_info, hsize_t *idx_size); typedef herr_t (*H5D_chunk_reset_func_t)(H5O_layout_t *layout, hbool_t reset_addr); -typedef herr_t (*H5D_chunk_depend_func_t)(const H5D_chk_idx_info_t *idx_info, +typedef herr_t (*H5D_chunk_support_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry); -typedef herr_t (*H5D_chunk_undepend_func_t)(const H5D_chk_idx_info_t *idx_info, +typedef herr_t (*H5D_chunk_unsupport_func_t)(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry); typedef herr_t (*H5D_chunk_dump_func_t)(const H5D_chk_idx_info_t *idx_info, FILE *stream); @@ -308,8 +308,8 @@ typedef struct H5D_chunk_ops_t { H5D_chunk_copy_shutdown_func_t copy_shutdown; /* Routine to perform any necessary shutdown for copying chunks */ H5D_chunk_size_func_t size; /* Routine to get size of indexing information */ H5D_chunk_reset_func_t reset; /* Routine to reset indexing information */ - H5D_chunk_depend_func_t depend; /* Routine to create dependency between chunk [proxy] and index metadata */ - H5D_chunk_undepend_func_t undepend; /* Routine to remove dependency between chunk [proxy] and index metadata */ + H5D_chunk_support_func_t support; /* Routine to create dependency between chunk [proxy] and index metadata */ + H5D_chunk_unsupport_func_t unsupport; /* Routine to remove dependency between chunk [proxy] and index metadata */ H5D_chunk_dump_func_t dump; /* Routine to dump indexing information */ H5D_chunk_dest_func_t dest; /* Routine to destroy indexing information in memory */ } H5D_chunk_ops_t; diff --git a/src/H5Dproxy.c b/src/H5Dproxy.c index 7d57ac2..784f7e7 100644 --- a/src/H5Dproxy.c +++ b/src/H5Dproxy.c @@ -359,7 +359,7 @@ HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); /* Create a flush dependency between the proxy (as the child) and the * metadata object in the index (as the parent). */ - if((dset->shared->layout.u.chunk.ops->depend)(&idx_info, udata, (H5AC_info_t *)proxy) < 0) + if((dset->shared->layout.u.chunk.ops->support)(&idx_info, udata, (H5AC_info_t *)proxy) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency for chunk proxy") done: @@ -419,7 +419,7 @@ HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); /* Remove flush dependency between the proxy (as the child) and the * metadata object in the index (as the parent). */ - if((dset->shared->layout.u.chunk.ops->undepend)(&idx_info, &udata, (H5AC_info_t *)proxy) < 0) + if((dset->shared->layout.u.chunk.ops->unsupport)(&idx_info, &udata, (H5AC_info_t *)proxy) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency for chunk proxy") /* Unpin & delete chunk proxy from metadata cache, taking ownership of it */ |