summaryrefslogtreecommitdiffstats
path: root/src/H5Dearray.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-06-04 19:24:21 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-06-04 19:24:21 (GMT)
commit94594831a96183fb7fcfa77697379db5df834ab5 (patch)
tree1c409db32a1dc1e7fff680b2f1e56de368a817d2 /src/H5Dearray.c
parent3972bca34060b2691c51d461cb51d22892b76046 (diff)
downloadhdf5-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
Diffstat (limited to 'src/H5Dearray.c')
-rw-r--r--src/H5Dearray.c152
1 files changed, 140 insertions, 12 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;