Merge pull request #155 in HDFFV/hdf5 from ~KOZIOL/hdf5:develop_merge_revise_chunks_05 to develop

* commit '1c6924f18bd8fdad63c4f191c00605092c17fa6e':
  Refactor H5O code to clean up message allocation, align cache deserialize code with revise_chunks changes, and remove unused "message locking" code.
This commit is contained in:
Quincey Koziol 2016-11-12 13:01:58 -06:00
commit d183e9a1a2
7 changed files with 741 additions and 831 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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);
/*********************/
@ -158,6 +156,149 @@ H5FL_SEQ_DEFINE(H5O_cont_t);
/* Local Variables */
/*******************/
/*-------------------------------------------------------------------------
* Function: H5O_decode_prefix
*
* Purpose: To decode the object header prefix.
* The coding is extracted fromt H5O__cache_deserialize() to this routine.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Vailin Choi; Aug 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata)
{
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_NOAPI_NOINIT
/* Check arguments */
HDassert(f);
HDassert(oh);
HDassert(buf);
HDassert(udata);
/* Check for presence of magic number */
/* (indicates version 2 or later) */
if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
/* Magic number */
p += H5_SIZEOF_MAGIC;
/* Version */
oh->version = *p++;
if(H5O_VERSION_2 != oh->version)
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
/* Flags */
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;
/* Time fields */
if(oh->flags & H5O_HDR_STORE_TIMES) {
uint32_t tmp; /* Temporary value */
UINT32DECODE(p, tmp);
oh->atime = (time_t)tmp;
UINT32DECODE(p, tmp);
oh->mtime = (time_t)tmp;
UINT32DECODE(p, tmp);
oh->ctime = (time_t)tmp;
UINT32DECODE(p, tmp);
oh->btime = (time_t)tmp;
} /* end if */
else
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
/* Attribute fields */
if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
UINT16DECODE(p, oh->max_compact);
UINT16DECODE(p, oh->min_dense);
if(oh->max_compact < oh->min_dense)
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;
oh->min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF;
} /* end else */
/* First chunk size */
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
case 0: /* 1 byte size */
oh->chunk0_size = *p++;
break;
case 1: /* 2 byte size */
UINT16DECODE(p, oh->chunk0_size);
break;
case 2: /* 4 byte size */
UINT32DECODE(p, oh->chunk0_size);
break;
case 3: /* 8 byte size */
UINT64DECODE(p, oh->chunk0_size);
break;
default:
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, FAIL, "bad object header chunk size")
} /* end if */
else {
/* Version */
oh->version = *p++;
if(H5O_VERSION_1 != oh->version)
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
/* Flags */
oh->flags = H5O_CRT_OHDR_FLAGS_DEF;
/* Reserved */
p++;
/* Number of messages */
UINT16DECODE(p, udata->v1_pfx_nmesgs);
/* Link count */
UINT32DECODE(p, oh->nlink);
/* Reset unused time fields */
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
/* Reset unused attribute fields */
oh->max_compact = 0;
oh->min_dense = 0;
/* First 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) */
p += 4;
} /* end else */
/* Determine object header prefix length */
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()
@ -216,7 +357,6 @@ H5O__cache_deserialize(const void *_image, size_t len, 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 */
@ -238,122 +378,14 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
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)) {
/* Magic number */
image += 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")
/* Flags */
oh->flags = *image++;
if(oh->flags & ~H5O_HDR_ALL_FLAGS)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)")
/* Number of links to object (unless overridden by refcount message) */
oh->nlink = 1;
/* Time fields */
if(oh->flags & H5O_HDR_STORE_TIMES) {
uint32_t tmp; /* Temporary value */
UINT32DECODE(image, tmp);
oh->atime = (time_t)tmp;
UINT32DECODE(image, tmp);
oh->mtime = (time_t)tmp;
UINT32DECODE(image, tmp);
oh->ctime = (time_t)tmp;
UINT32DECODE(image, tmp);
oh->btime = (time_t)tmp;
} /* end if */
else
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
/* Attribute fields */
if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
UINT16DECODE(image, oh->max_compact);
UINT16DECODE(image, oh->min_dense);
if(oh->max_compact < oh->min_dense)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header attribute phase change values")
} /* end if */
else {
oh->max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF;
oh->min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF;
} /* end else */
/* First chunk size */
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
case 0: /* 1 byte size */
oh->chunk0_size = *image++;
break;
case 1: /* 2 byte size */
UINT16DECODE(image, oh->chunk0_size);
break;
case 2: /* 4 byte size */
UINT32DECODE(image, oh->chunk0_size);
break;
case 3: /* 8 byte size */
UINT64DECODE(image, oh->chunk0_size);
break;
default:
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "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")
} /* end if */
else {
/* Version */
oh->version = *image++;
if(H5O_VERSION_1 != oh->version)
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")
/* Flags */
oh->flags = H5O_CRT_OHDR_FLAGS_DEF;
/* Reserved */
image++;
/* Number of messages */
UINT16DECODE(image, udata->v1_pfx_nmesgs);
/* Link count */
UINT32DECODE(image, oh->nlink);
/* Reset unused time fields */
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
/* Reset unused attribute fields */
oh->max_compact = 0;
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")
/* Reserved, in version 1 (for 8-byte alignment padding) */
image += 4;
} /* end else */
/* Determine object header prefix length */
prefix_size = (size_t)(image - (const uint8_t *)_image);
HDassert((size_t)prefix_size == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
/* 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() */

View File

@ -93,7 +93,8 @@ H5FL_DEFINE(H5O_chunk_proxy_t);
*-------------------------------------------------------------------------
*/
herr_t
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
unsigned cont_chunkno)
{
H5O_chunk_proxy_t *chk_proxy = NULL; /* Proxy for chunk, to mark it dirty in the cache */
herr_t ret_value = SUCCEED; /* Return value */
@ -110,14 +111,16 @@ H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Set the values in the chunk proxy */
chk_proxy->oh = oh;
chk_proxy->chunkno = idx;
/* Increment reference count on object header */
if(H5O_inc_rc(oh) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header")
/* Set the values in the chunk proxy */
chk_proxy->f = f;
chk_proxy->oh = oh;
chk_proxy->chunkno = idx;
chk_proxy->cont_chunkno = cont_chunkno;
/* Insert the chunk proxy into the cache */
if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk")
@ -126,8 +129,8 @@ H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
done:
if(ret_value < 0)
if(chk_proxy)
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
if(chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk")
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_chunk_add() */
@ -172,6 +175,7 @@ H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
/* Set chunk proxy fields */
chk_proxy->f = f;
chk_proxy->oh = oh;
chk_proxy->chunkno = idx;
} /* end if */
@ -200,8 +204,8 @@ H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
done:
/* Cleanup on error */
if(!ret_value)
if(0 == idx && chk_proxy)
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
if(0 == idx && chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header chunk")
FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
} /* end H5O_chunk_protect() */
@ -409,3 +413,39 @@ done:
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_chunk_delete() */
/*-------------------------------------------------------------------------
* Function: H5O__chunk_dest
*
* Purpose: Destroy a chunk proxy object
*
* Return: Success: SUCCEED
* Failure: FAIL
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* July 13, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
H5O__chunk_dest(H5O_chunk_proxy_t *chk_proxy)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* 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_dest() */

View File

@ -2254,176 +2254,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_flush_msgs() */
/*-------------------------------------------------------------------------
* Function: H5O_msg_chunkno
*
* Purpose: Queries the object header chunk index for a message.
*
* Return: Success: >=0 value indicating the chunk number for
* the message
* Failure: <0
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Apr 22 2010
*
*-------------------------------------------------------------------------
*/
int
H5O_msg_get_chunkno(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Object header to use */
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
unsigned idx; /* Index of message to modify */
int ret_value = -1; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* check args */
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(H5O_msg_class_g));
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Get the object header */
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
/* Locate message of correct type */
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
if(type == idx_msg->type)
break;
if(idx == oh->nmesgs)
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
/* Set return value */
H5_CHECKED_ASSIGN(ret_value, int, idx_msg->chunkno, unsigned);
done:
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_msg_get_chunkno() */
/*-------------------------------------------------------------------------
* Function: H5O_msg_lock
*
* Purpose: Locks a message into a particular chunk, preventing it from
* being moved into another chunk.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Apr 22 2010
*
*-------------------------------------------------------------------------
*/
herr_t
H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Object header to use */
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
unsigned idx; /* Index of message to modify */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* check args */
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(H5O_msg_class_g));
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Get the object header */
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
/* Locate message of correct type */
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
if(type == idx_msg->type)
break;
if(idx == oh->nmesgs)
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
/* Fail if the message is already locked */
if(idx_msg->locked)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOCK, FAIL, "message already locked")
/* Make the message locked */
idx_msg->locked = TRUE;
done:
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_msg_lock() */
/*-------------------------------------------------------------------------
* Function: H5O_msg_unlock
*
* Purpose: Unlocks a message, allowing it to be moved into another chunk.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Apr 22 2010
*
*-------------------------------------------------------------------------
*/
herr_t
H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Object header to use */
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
unsigned idx; /* Index of message to modify */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* check args */
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(H5O_msg_class_g));
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Get the object header */
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
/* Locate message of correct type */
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
if(type == idx_msg->type)
break;
if(idx == oh->nmesgs)
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
/* Fail if the message is not locked */
if(!idx_msg->locked)
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNLOCK, FAIL, "message not locked")
/* Make the message unlocked */
idx_msg->locked = FALSE;
done:
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_msg_unlock() */

View File

@ -245,7 +245,6 @@ struct H5O_msg_class_t {
struct H5O_mesg_t {
const H5O_msg_class_t *type; /*type of message */
hbool_t dirty; /*raw out of date wrt native */
hbool_t locked; /*message is locked into chunk */
uint8_t flags; /*message flags */
H5O_msg_crt_idx_t crt_idx; /*message creation index */
unsigned chunkno; /*chunk number for this mesg */
@ -254,6 +253,17 @@ struct H5O_mesg_t {
size_t raw_size; /*size with alignment */
};
/* Struct for storing information about "best" message to move to new chunk */
typedef struct H5O_msg_alloc_info_t {
int msgno; /* Index in message array */
unsigned id; /* Message type ID on disk */
unsigned chunkno; /* Index in chunk array */
size_t gap_size; /* Size of any "gap" in the chunk immediately after message */
size_t null_size; /* Size of any null message in the chunk immediately after message */
size_t total_size; /* Total size of "available" space around message */
unsigned null_msgno; /* Message index of null message immediately after message */
} H5O_msg_alloc_info_t;
typedef struct H5O_chunk_t {
haddr_t addr; /*chunk file address */
size_t size; /*chunk size */
@ -369,8 +379,10 @@ typedef struct H5O_chunk_proxy_t {
H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */
/* first field in structure */
H5F_t *f; /* Pointer to file for object header/chunk */
H5O_t *oh; /* Object header for this chunk */
unsigned chunkno; /* Chunk number for this chunk */
unsigned cont_chunkno; /* Chunk number for the chunk containing the continuation message that points to this chunk */
} H5O_chunk_proxy_t;
/* Callback information for loading object header chunk from disk */
@ -559,7 +571,8 @@ H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *t
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
/* Object header chunk routines */
H5_DLL herr_t H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
H5_DLL herr_t H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
unsigned cont_chunkno);
H5_DLL H5O_chunk_proxy_t *H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
unsigned idx);
H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id,
@ -567,6 +580,7 @@ H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id,
H5_DLL herr_t H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
H5_DLL herr_t H5O_chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_proxy);
H5_DLL herr_t H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
H5_DLL herr_t H5O__chunk_dest(H5O_chunk_proxy_t *chunk_proxy);
/* Collect storage info for btree and heap */
H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
@ -574,6 +588,8 @@ H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
/* Object header allocation routines */
H5_DLL herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
H5_DLL herr_t H5O__alloc_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size,
size_t found_null, const H5O_msg_alloc_info_t *found_msg, size_t *new_idx);
H5_DLL herr_t H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_msg_class_t *type, const void *mesg, size_t *mesg_idx);
H5_DLL herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);

View File

@ -898,9 +898,6 @@ H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
unsigned type_id, const unsigned char *buf);
H5_DLL herr_t H5O_msg_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
unsigned type_id, void *mesg);
H5_DLL int H5O_msg_get_chunkno(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
/* Object metadata flush/refresh routines */
H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id);

View File

@ -811,148 +811,6 @@ main(void)
FAIL_STACK_ERROR
PASSED();
/*
* Test moving message to first chunk
*/
TESTING("locking messages");
HDmemset(&oh_loc, 0, sizeof(oh_loc));
if(H5O_create(f, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
FAIL_STACK_ERROR
if(1 != H5O_link(&oh_loc, 1, H5AC_ind_read_dxpl_id))
FAIL_STACK_ERROR
/* Create second object header, to guarantee that first object header uses multiple chunks */
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
if(H5O_create(f, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
FAIL_STACK_ERROR
if(1 != H5O_link(&oh_loc2, 1, H5AC_ind_read_dxpl_id))
FAIL_STACK_ERROR
/* Fill object header with messages, creating multiple chunks */
for(i = 0; i < 10; i++) {
time_new = (i + 1) * 1000 + 10;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
} /* end for */
/* Get # of object header chunks */
if(H5O_get_hdr_info(&oh_loc, H5AC_ind_read_dxpl_id, &hdr_info) < 0)
FAIL_STACK_ERROR
if(hdr_info.nchunks != 2)
TEST_ERROR
/* Add message to lock to object header */
time_new = 11111111;
if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Verify chunk index for message */
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
FAIL_STACK_ERROR
if(chunkno != 1)
TEST_ERROR
/* Lock the message into the chunk */
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Attempt to lock the message twice */
H5E_BEGIN_TRY {
ret = H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id);
} H5E_END_TRY;
if(ret >= 0)
TEST_ERROR
/* Delete all the other messages, which would move the message into
* chunk #0, if it wasn't locked
*/
if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Verify chunk index for message */
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
FAIL_STACK_ERROR
if(chunkno != 1)
TEST_ERROR
/* Unlock the message */
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Attempt to unlock the message twice */
H5E_BEGIN_TRY {
ret = H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id);
} H5E_END_TRY;
if(ret >= 0)
TEST_ERROR
/* Close object headers */
if(H5O_close(&oh_loc2) < 0)
FAIL_STACK_ERROR
if(H5O_close(&oh_loc) < 0)
FAIL_STACK_ERROR
/* Open first object header */
HDmemset(&oh_loc, 0, sizeof(oh_loc));
if(H5O_create(f, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
FAIL_STACK_ERROR
if(1 != H5O_link(&oh_loc, 1, H5AC_ind_read_dxpl_id))
FAIL_STACK_ERROR
/* Create second object header, to guarantee that first object header uses multiple chunks */
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
if(H5O_create(f, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
FAIL_STACK_ERROR
if(1 != H5O_link(&oh_loc2, 1, H5AC_ind_read_dxpl_id))
FAIL_STACK_ERROR
/* Add message to move to object header */
time_new = 11111111;
if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Verify chunk index for message */
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
FAIL_STACK_ERROR
if(chunkno != 0)
TEST_ERROR
/* Lock the message into the chunk */
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Fill object header with messages, creating multiple chunks */
/* (would normally move locked message to new chunk) */
for(i = 0; i < 10; i++) {
time_new = (i + 1) * 1000 + 10;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
} /* end for */
/* Get # of object header chunks */
if(H5O_get_hdr_info(&oh_loc, H5AC_ind_read_dxpl_id, &hdr_info) < 0)
FAIL_STACK_ERROR
if(hdr_info.nchunks != 2)
TEST_ERROR
/* Verify chunk index for message */
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
FAIL_STACK_ERROR
if(chunkno != 0)
TEST_ERROR
/* Unlock the message */
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
FAIL_STACK_ERROR
/* Close object headers */
if(H5O_close(&oh_loc2) < 0)
FAIL_STACK_ERROR
if(H5O_close(&oh_loc) < 0)
FAIL_STACK_ERROR
PASSED();
/* Close the file we created */
if(H5Fclose(file) < 0)
TEST_ERROR