summaryrefslogtreecommitdiffstats
path: root/src/H5Ocache.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2016-11-12 09:05:47 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2016-11-12 09:05:47 (GMT)
commit1c6924f18bd8fdad63c4f191c00605092c17fa6e (patch)
treecfa3351ffe9a04b46e2ed226da6a5c00a80b4caa /src/H5Ocache.c
parent70938cbf28ca91a17d8d975d5b5ebcd44648e1c9 (diff)
downloadhdf5-1c6924f18bd8fdad63c4f191c00605092c17fa6e.zip
hdf5-1c6924f18bd8fdad63c4f191c00605092c17fa6e.tar.gz
hdf5-1c6924f18bd8fdad63c4f191c00605092c17fa6e.tar.bz2
Refactor H5O code to clean up message allocation, align cache deserialize code
with revise_chunks changes, and remove unused "message locking" code.
Diffstat (limited to 'src/H5Ocache.c')
-rw-r--r--src/H5Ocache.c289
1 files changed, 144 insertions, 145 deletions
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 0bb0bdf..f1a128d 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -88,9 +88,6 @@ static herr_t H5O__cache_chk_serialize(const H5F_t *f, void *image, size_t len,
static herr_t H5O__cache_chk_free_icr(void *thing);
static herr_t H5O__cache_chk_clear(const H5F_t *f, void *thing, hbool_t about_to_destroy);
-/* Chunk proxy routines */
-static herr_t H5O__chunk_proxy_dest(H5O_chunk_proxy_t *chunk_proxy);
-
/* Chunk routines */
static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len,
const uint8_t *image, H5O_common_cache_ud_t *udata, hbool_t *dirty);
@@ -99,6 +96,7 @@ static herr_t H5O__chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno);
/* Misc. routines */
static herr_t H5O__add_cont_msg(H5O_cont_msgs_t *cont_msg_info,
const H5O_cont_t *cont);
+static herr_t H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata);
/*********************/
@@ -160,99 +158,48 @@ H5FL_SEQ_DEFINE(H5O_cont_t);
/*-------------------------------------------------------------------------
- * Function: H5O__cache_get_load_size()
+ * Function: H5O_decode_prefix
*
- * Purpose: Tell the metadata cache how much data to read from file in
- * the first speculative read for the object header. Note that we do
- * not have to be concerned about reading past the end of file, as the
- * cache will clamp the read to avoid this if needed.
+ * Purpose: To decode the object header prefix.
+ * The coding is extracted fromt H5O__cache_deserialize() to this routine.
*
- * Return: Success: SUCCEED
- * Failure: FAIL
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: John Mainzer
- * 7/28/14
+ * Programmer: Vailin Choi; Aug 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5O__cache_get_load_size(const void H5_ATTR_UNUSED *_udata, size_t *image_len)
-{
- FUNC_ENTER_STATIC_NOERR
-
- /* Check arguments */
- HDassert(image_len);
-
- *image_len = H5O_SPEC_READ_SIZE;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O__cache_get_load_size() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O__cache_deserialize
- *
- * Purpose: Attempt to deserialize the object header contained in the
- * supplied buffer, load the data into an instance of H5O_t, and
- * return a pointer to the new instance.
- *
- * Note that the object header is read with with a speculative read.
- * If the initial read is too small, make note of this fact and return
- * without error. H5C_load_entry() will note the size discrepency
- * and retry the deserialize operation with the correct size read.
- *
- * Return: Success: Pointer to in core representation
- * Failure: NULL
- *
- * Programmer: John Mainzer
- * 7/28/14
- *
- *-------------------------------------------------------------------------
- */
-static void *
-H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
- hbool_t *dirty)
+H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata)
{
- H5O_t *oh = NULL; /* Object header read in */
- H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
- const uint8_t *image = (const uint8_t *)_image; /* Pointer into buffer to decode */
- size_t prefix_size; /* Size of object header prefix */
- size_t buf_size; /* Size of prefix+chunk #0 buffer */
- void * ret_value = NULL; /* Return value */
+ H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
+ const uint8_t *p = buf; /* Pointer into buffer to decode */
+ size_t prefix_size; /* Size of object header prefix */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI_NOINIT
/* Check arguments */
- HDassert(image);
- HDassert(len > 0);
+ HDassert(f);
+ HDassert(oh);
+ HDassert(buf);
HDassert(udata);
- HDassert(udata->common.f);
- HDassert(udata->common.cont_msg_info);
- HDassert(dirty);
-
- /* Allocate space for the object header data structure */
- if(NULL == (oh = H5FL_CALLOC(H5O_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* File-specific, non-stored information */
- oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f);
- oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f);
/* Check for presence of magic number */
/* (indicates version 2 or later) */
- if(!HDmemcmp(image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
/* Magic number */
- image += H5_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
- oh->version = *image++;
- if(H5O_VERSION_2 != oh->version)
- HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")
+ oh->version = *p++;
+ if(H5O_VERSION_2 != oh->version)
+ HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
/* Flags */
- oh->flags = *image++;
- if(oh->flags & ~H5O_HDR_ALL_FLAGS)
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)")
+ oh->flags = *p++;
+ if(oh->flags & ~H5O_HDR_ALL_FLAGS)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unknown object header status flag(s)")
/* Number of links to object (unless overridden by refcount message) */
oh->nlink = 1;
@@ -261,13 +208,13 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
if(oh->flags & H5O_HDR_STORE_TIMES) {
uint32_t tmp; /* Temporary value */
- UINT32DECODE(image, tmp);
+ UINT32DECODE(p, tmp);
oh->atime = (time_t)tmp;
- UINT32DECODE(image, tmp);
+ UINT32DECODE(p, tmp);
oh->mtime = (time_t)tmp;
- UINT32DECODE(image, tmp);
+ UINT32DECODE(p, tmp);
oh->ctime = (time_t)tmp;
- UINT32DECODE(image, tmp);
+ UINT32DECODE(p, tmp);
oh->btime = (time_t)tmp;
} /* end if */
else
@@ -275,11 +222,10 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
/* Attribute fields */
if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
- UINT16DECODE(image, oh->max_compact);
- UINT16DECODE(image, oh->min_dense);
-
+ UINT16DECODE(p, oh->max_compact);
+ UINT16DECODE(p, oh->min_dense);
if(oh->max_compact < oh->min_dense)
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header attribute phase change values")
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header attribute phase change values")
} /* end if */
else {
oh->max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF;
@@ -289,44 +235,44 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
/* First chunk size */
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
case 0: /* 1 byte size */
- oh->chunk0_size = *image++;
+ oh->chunk0_size = *p++;
break;
case 1: /* 2 byte size */
- UINT16DECODE(image, oh->chunk0_size);
+ UINT16DECODE(p, oh->chunk0_size);
break;
case 2: /* 4 byte size */
- UINT32DECODE(image, oh->chunk0_size);
+ UINT32DECODE(p, oh->chunk0_size);
break;
case 3: /* 8 byte size */
- UINT64DECODE(image, oh->chunk0_size);
+ UINT64DECODE(p, oh->chunk0_size);
break;
default:
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad size for chunk 0")
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad size for chunk 0")
} /* end switch */
if(oh->chunk0_size > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh))
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size")
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header chunk size")
} /* end if */
else {
/* Version */
- oh->version = *image++;
+ oh->version = *p++;
if(H5O_VERSION_1 != oh->version)
- HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")
+ HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
/* Flags */
oh->flags = H5O_CRT_OHDR_FLAGS_DEF;
/* Reserved */
- image++;
+ p++;
/* Number of messages */
- UINT16DECODE(image, udata->v1_pfx_nmesgs);
+ UINT16DECODE(p, udata->v1_pfx_nmesgs);
/* Link count */
- UINT32DECODE(image, oh->nlink);
+ UINT32DECODE(p, oh->nlink);
/* Reset unused time fields */
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
@@ -336,24 +282,110 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
oh->min_dense = 0;
/* First chunk size */
- UINT32DECODE(image, oh->chunk0_size);
-
- if((udata->v1_pfx_nmesgs > 0 &&
- oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) ||
- (udata->v1_pfx_nmesgs == 0 && oh->chunk0_size > 0))
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size")
+ UINT32DECODE(p, oh->chunk0_size);
+ if((udata->v1_pfx_nmesgs > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) ||
+ (udata->v1_pfx_nmesgs == 0 && oh->chunk0_size > 0))
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header chunk size")
/* Reserved, in version 1 (for 8-byte alignment padding) */
- image += 4;
+ p += 4;
} /* end else */
/* Determine object header prefix length */
- prefix_size = (size_t)(image - (const uint8_t *)_image);
+ prefix_size = (size_t)(p - buf);
HDassert((size_t)prefix_size == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_decode_prefix() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O__cache_get_load_size()
+ *
+ * Purpose: Tell the metadata cache how much data to read from file in
+ * the first speculative read for the object header. Note that we do
+ * not have to be concerned about reading past the end of file, as the
+ * cache will clamp the read to avoid this if needed.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 7/28/14
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O__cache_get_load_size(const void H5_ATTR_UNUSED *_udata, size_t *image_len)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check arguments */
+ HDassert(image_len);
+
+ *image_len = H5O_SPEC_READ_SIZE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O__cache_get_load_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O__cache_deserialize
+ *
+ * Purpose: Attempt to deserialize the object header contained in the
+ * supplied buffer, load the data into an instance of H5O_t, and
+ * return a pointer to the new instance.
+ *
+ * Note that the object header is read with with a speculative read.
+ * If the initial read is too small, make note of this fact and return
+ * without error. H5C_load_entry() will note the size discrepency
+ * and retry the deserialize operation with the correct size read.
+ *
+ * Return: Success: Pointer to in core representation
+ * Failure: NULL
+ *
+ * Programmer: John Mainzer
+ * 7/28/14
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
+ hbool_t *dirty)
+{
+ H5O_t *oh = NULL; /* Object header read in */
+ H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
+ const uint8_t *image = (const uint8_t *)_image; /* Pointer into buffer to decode */
+ size_t buf_size; /* Size of prefix+chunk #0 buffer */
+ void * ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ HDassert(image);
+ HDassert(len > 0);
+ HDassert(udata);
+ HDassert(udata->common.f);
+ HDassert(udata->common.cont_msg_info);
+ HDassert(dirty);
+
+ /* Allocate space for the object header data structure */
+ if(NULL == (oh = H5FL_CALLOC(H5O_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* File-specific, non-stored information */
+ oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f);
+ oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f);
+
+ /* Decode header prefix */
+ if(H5O_decode_prefix(udata->common.f, oh, image, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header prefix")
+
/* Compute the size of the buffer used */
buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh);
+
/* Check to see if the buffer provided is large enough to contain both
* the prefix and the first chunk. If it isn't, make note of the desired
* size, but otherwise do nothing. H5C_load_entry() will notice the
@@ -768,32 +800,35 @@ H5O__cache_chk_deserialize(const void *image, size_t len, void *_udata,
if(H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, &(udata->common), dirty) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk")
- /* Set the fields for the chunk proxy */
- chk_proxy->oh = udata->oh;
+ /* Set the chunk number for the chunk proxy */
H5_CHECKED_ASSIGN(chk_proxy->chunkno, unsigned, udata->oh->nchunks - 1, size_t);
} /* end if */
else {
/* Sanity check */
HDassert(udata->chunkno < udata->oh->nchunks);
- /* Set the fields for the chunk proxy */
- chk_proxy->oh = udata->oh;
+ /* Set the chunk number for the chunk proxy */
chk_proxy->chunkno = udata->chunkno;
/* Sanity check that the chunk representation we have in memory is
* the same as the one being brought in from disk.
*/
- HDassert(0 == HDmemcmp(image, chk_proxy->oh->chunk[chk_proxy->chunkno].image, chk_proxy->oh->chunk[chk_proxy->chunkno].size));
+ HDassert(0 == HDmemcmp(image, udata->oh->chunk[chk_proxy->chunkno].image, udata->oh->chunk[chk_proxy->chunkno].size));
} /* end else */
/* Increment reference count of object header */
if(H5O_inc_rc(udata->oh) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
+ chk_proxy->oh = udata->oh;
/* Set return value */
ret_value = chk_proxy;
done:
+ if(NULL == ret_value)
+ if(chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header chunk")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O__cache_chk_deserialize() */
@@ -920,7 +955,7 @@ H5O__cache_chk_free_icr(void *_thing)
HDassert(chk_proxy->cache_info.type == H5AC_OHDR_CHK);
/* Destroy object header chunk proxy */
- if(H5O__chunk_proxy_dest(chk_proxy) < 0)
+ if(H5O__chunk_dest(chk_proxy) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk proxy")
done:
@@ -1453,39 +1488,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O__chunk_serialize() */
-
-/*-------------------------------------------------------------------------
- * Function: H5O__chunk_proxy_dest
- *
- * Purpose: Destroy a chunk proxy object
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * July 13, 2008
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O__chunk_proxy_dest(H5O_chunk_proxy_t *chk_proxy)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC
-
- /* Check arguments */
- HDassert(chk_proxy);
-
- /* Decrement reference count of object header */
- if(chk_proxy->oh && H5O_dec_rc(chk_proxy->oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement reference count on object header")
-
- /* Release the chunk proxy object */
- chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O__chunk_proxy_dest() */
-