summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-06-29 03:12:45 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-06-29 03:12:45 (GMT)
commitcad9846d77ea4926bb0f13cf5151c1a7ac05ec87 (patch)
treec88b30412b25b6fc5df9534a6ff2cf1742393a36
parent58467956ba56fc52dd03e3540f14b062f9a6c5bb (diff)
downloadhdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.zip
hdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.tar.gz
hdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.tar.bz2
[svn-r13926] Description:
Add small interface to "wrap" a static buffer (usually on the stack), but still allow for buffers larger than the static buffer to be allocated. This can eliminate _many_ short-lived buffer allocations in situations where the buffer is a predictable size (or at least a "very likely" size). Also, some minor code cleanups, particularly in the SOHM caching code. Tested on: Mac OS X/32 10.4.10 (amazon)
-rw-r--r--MANIFEST2
-rw-r--r--src/H5Adense.c50
-rw-r--r--src/H5B2cache.c69
-rw-r--r--src/H5Dfill.c69
-rw-r--r--src/H5FScache.c67
-rw-r--r--src/H5Gdense.c24
-rw-r--r--src/H5Gnode.c145
-rw-r--r--src/H5HFcache.c116
-rw-r--r--src/H5Oshared.c77
-rwxr-xr-xsrc/H5SM.c3
-rw-r--r--src/H5SMcache.c652
-rwxr-xr-xsrc/H5SMpkg.h75
-rw-r--r--src/H5Sselect.c36
-rw-r--r--src/H5Tconv.c17
-rw-r--r--src/H5Tprivate.h3
-rw-r--r--src/H5WB.c291
-rw-r--r--src/H5WBprivate.h64
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in5
-rw-r--r--tools/misc/h5debug.c4
20 files changed, 1182 insertions, 589 deletions
diff --git a/MANIFEST b/MANIFEST
index b5e559c..0715883 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -696,6 +696,8 @@
./src/H5TSprivate.h
./src/H5V.c
./src/H5Vprivate.h
+./src/H5WB.c
+./src/H5WBprivate.h
./src/H5Z.c
./src/H5Zdeflate.c
./src/H5Zfletcher32.c
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 892a334..e35366a 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -42,6 +42,7 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@@ -166,9 +167,6 @@ typedef struct H5A_bt2_ud_rmbi_t {
/* Local Variables */
/*******************/
-/* Declare a free list to manage the serialized attribute information */
-H5FL_BLK_DEFINE(ser_attr);
-
/*-------------------------------------------------------------------------
@@ -410,8 +408,8 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */
- void *attr_ptr = NULL; /* Pointer to serialized message */
unsigned mesg_flags = 0; /* Flags for storing message */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -474,19 +472,20 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
udata.id = attr->sh_loc.u.heap_id;
} /* end if */
else {
- size_t attr_size; /* Size of serialized attribute in the heap */
+ void *attr_ptr; /* Pointer to serialized message */
+ size_t attr_size; /* Size of serialized attribute in the heap */
/* Find out the size of buffer needed for serialized message */
if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, FALSE, attr)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get message size")
- /* Allocate space for serialized message, if necessary */
- if(attr_size > sizeof(attr_buf)) {
- if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
- else
- attr_ptr = attr_buf;
+ /* Wrap the local buffer for serialized attributes */
+ if(NULL == (wb = H5WB_wrap(attr_buf, sizeof(attr_buf))))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for attribute */
+ if(NULL == (attr_ptr = H5WB_actual(wb, attr_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of attribute or shared message */
if(H5O_msg_encode(f, H5O_ATTR_ID, FALSE, (unsigned char *)attr_ptr, attr) < 0)
@@ -529,8 +528,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
- if(attr_ptr && attr_ptr != attr_buf)
- (void)H5FL_BLK_FREE(ser_attr, attr_ptr);
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_insert() */
@@ -592,8 +591,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
{
H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */
+ H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
- void *attr_ptr = NULL; /* Pointer to serialized attribute */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_write_bt2_cb)
@@ -638,19 +637,20 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
*changed = TRUE;
} /* end if */
else {
- size_t attr_size; /* Size of serialized attribute in the heap */
+ void *attr_ptr; /* Pointer to serialized message */
+ size_t attr_size; /* Size of serialized attribute in the heap */
/* Find out the size of buffer needed for serialized attribute */
if((attr_size = H5O_msg_raw_size(op_data->f, H5O_ATTR_ID, FALSE, op_data->attr)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
- /* Allocate space for serialized attribute, if necessary */
- if(attr_size > sizeof(attr_buf)) {
- if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
- else
- attr_ptr = attr_buf;
+ /* Wrap the local buffer for serialized attributes */
+ if(NULL == (wb = H5WB_wrap(attr_buf, sizeof(attr_buf))))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for attribute */
+ if(NULL == (attr_ptr = H5WB_actual(wb, attr_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of attribute */
if(H5O_msg_encode(op_data->f, H5O_ATTR_ID, FALSE, (unsigned char *)attr_ptr, op_data->attr) < 0)
@@ -674,8 +674,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
done:
/* Release resources */
- if(attr_ptr && attr_ptr != attr_buf)
- (void)H5FL_BLK_FREE(ser_attr, attr_ptr);
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_write_bt2_cb() */
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index f081ae8..86592c5 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -36,6 +36,8 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
/****************/
/* Local Macros */
@@ -46,6 +48,9 @@
#define H5B2_INT_VERSION 0 /* Internal node */
#define H5B2_LEAF_VERSION 0 /* Leaf node */
+/* Size of stack buffer for serialized headers */
+#define H5B2_HDR_BUF_SIZE 128
+
/******************/
/* Local Typedefs */
@@ -118,9 +123,6 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
/* Local Variables */
/*******************/
-/* Declare a free list to manage B-tree header data to/from disk */
-H5FL_BLK_DEFINE_STATIC(header_block);
-
/*-------------------------------------------------------------------------
@@ -149,7 +151,9 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
size_t size; /* Header size */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
- uint8_t *buf = NULL; /* Temporary buffer */
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
+ uint8_t *hdr; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
H5B2_t *ret_value; /* Return value */
@@ -165,18 +169,23 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));
- /* Compute the size of the B-tree header on disk */
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Compute the size of the serialized B-tree header on disk */
size = H5B2_HEADER_SIZE(f);
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for header */
+ if(NULL == (hdr = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
- p = buf;
+ /* Get temporary pointer to serialized header */
+ p = hdr;
/* Magic number */
if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC))
@@ -213,10 +222,10 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
UINT32DECODE(p, stored_chksum);
/* Sanity check */
- HDassert((size_t)(p - buf) == size);
+ HDassert((size_t)(p - hdr) == size);
/* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
+ computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -230,8 +239,9 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
ret_value = bt2;
done:
- if(buf)
- (void)H5FL_BLK_FREE(header_block, buf);
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && bt2)
(void)H5B2_cache_hdr_dest(f, bt2);
@@ -260,6 +270,8 @@ done:
static herr_t
H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *bt2, unsigned UNUSED * flags_ptr)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_cache_hdr_flush, FAIL)
@@ -271,7 +283,7 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
if (bt2->cache_info.is_dirty) {
H5B2_shared_t *shared; /* Shared B-tree information */
- uint8_t *buf; /* Temporary raw data buffer */
+ uint8_t *hdr; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t metadata_chksum; /* Computed metadata checksum value */
@@ -280,14 +292,19 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
HDassert(shared);
- /* Compute the size of the B-tree header on disk */
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Compute the size of the serialized B-tree header on disk */
size = H5B2_HEADER_SIZE(f);
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for header */
+ if(NULL == (hdr = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer")
- p = buf;
+ /* Get temporary pointer to serialized header */
+ p = hdr;
/* Magic number */
HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC);
@@ -318,18 +335,16 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec);
/* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
+ metadata_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the B-tree header. */
- HDassert((size_t)(p - buf) == size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
+ HDassert((size_t)(p - hdr) == size);
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk")
- (void)H5FL_BLK_FREE(header_block, buf);
-
bt2->cache_info.is_dirty = FALSE;
} /* end if */
@@ -338,6 +353,10 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_cache_hdr_flush() */
diff --git a/src/H5Dfill.c b/src/H5Dfill.c
index 89e3a6b..b2e8e9d 100644
--- a/src/H5Dfill.c
+++ b/src/H5Dfill.c
@@ -39,6 +39,7 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5Vprivate.h" /* Vector and array functions */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@@ -65,9 +66,6 @@
/* Package Variables */
/*********************/
-/* Declare a free list to manage blocks of single datatype element data */
-H5FL_BLK_DEFINE(type_elem);
-
/* Declare extern the free list to manage blocks of type conversion data */
H5FL_BLK_EXTERN(type_conv);
@@ -174,7 +172,10 @@ herr_t
H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id)
{
- uint8_t *tconv_buf = NULL; /* Data type conv buffer */
+ H5WB_t *elem_wb = NULL; /* Wrapped buffer for element data */
+ uint8_t elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for element data */
+ H5WB_t *bkg_elem_wb = NULL; /* Wrapped buffer for background data */
+ uint8_t bkg_elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for background data */
uint8_t *bkg_buf = NULL; /* Background conversion buffer */
uint8_t *tmp_buf = NULL; /* Temp conversion buffer */
hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */
@@ -198,12 +199,18 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
/* If there's no fill value, just use zeros */
if(fill == NULL) {
- /* Allocate space & initialize conversion buffer to zeros */
- if(NULL == (tconv_buf = H5FL_BLK_CALLOC(type_elem, dst_type_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ void *elem_ptr; /* Pointer to element to use for fill value */
+
+ /* Wrap the local buffer for elements */
+ if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for element */
+ if(NULL == (elem_ptr = H5WB_actual_clear(elem_wb, dst_type_size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Fill the selection in the memory buffer */
- if(H5S_select_fill(tconv_buf, dst_type_size, space, buf) < 0)
+ if(H5S_select_fill(elem_ptr, dst_type_size, space, buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed")
} /* end if */
else {
@@ -283,24 +290,38 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
/* Convert disk buffer into memory buffer */
if(!H5T_path_noop(tpath)) {
- /* Allocate space for conversion buffer */
- if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_elem, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ void *elem_ptr; /* Pointer to element to use for fill value */
+ void *bkg_ptr; /* Pointer to background element to use for fill value */
+
+ /* Wrap the local buffer for elements */
+ if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for element */
+ if(NULL == (elem_ptr = H5WB_actual(elem_wb, buf_size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Copy the user's data into the buffer for conversion */
- HDmemcpy(tconv_buf, fill, src_type_size);
+ HDmemcpy(elem_ptr, fill, src_type_size);
/* If there's no VL type of data, do conversion first then fill the data into
* the memory buffer. */
- if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_elem, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(H5T_path_bkg(tpath)) {
+ /* Wrap the local buffer for background elements */
+ if(NULL == (bkg_elem_wb = H5WB_wrap(bkg_elem_buf, sizeof(bkg_elem_buf))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for element */
+ if(NULL == (bkg_ptr = H5WB_actual_clear(bkg_elem_wb, buf_size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
+ } /* end if */
/* Perform datatype conversion */
- if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
+ if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, elem_ptr, bkg_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed")
- /* Point at temporary buffer */
- fill_buf = tconv_buf;
+ /* Point at element buffer */
+ fill_buf = elem_ptr;
} /* end if */
else
fill_buf = fill;
@@ -318,14 +339,12 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tmp_buf)
H5FL_BLK_FREE(type_conv, tmp_buf);
- if(tconv_buf)
- H5FL_BLK_FREE(type_elem, tconv_buf);
- if(bkg_buf) {
- if(TRUE == H5T_detect_class(fill_type, H5T_VLEN))
- H5FL_BLK_FREE(type_conv, bkg_buf);
- else
- H5FL_BLK_FREE(type_elem, bkg_buf);
- } /* end if */
+ if(elem_wb && H5WB_unwrap(elem_wb) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+ if(bkg_elem_wb && H5WB_unwrap(bkg_elem_wb) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_fill() */
diff --git a/src/H5FScache.c b/src/H5FScache.c
index 001916e..700f026 100644
--- a/src/H5FScache.c
+++ b/src/H5FScache.c
@@ -37,6 +37,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FSpkg.h" /* File free space */
#include "H5Vprivate.h" /* Vectors and arrays */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
@@ -46,6 +47,9 @@
#define H5FS_HDR_VERSION 0 /* Header */
#define H5FS_SINFO_VERSION 0 /* Serialized sections */
+/* Size of stack buffer for serialized headers */
+#define H5FS_HDR_BUF_SIZE 256
+
/******************/
/* Local Typedefs */
@@ -118,9 +122,6 @@ const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{
/* Local Variables */
/*******************/
-/* Declare a free list to manage free space header data to/from disk */
-H5FL_BLK_DEFINE_STATIC(header_block);
-
/* Declare a free list to manage free space section data to/from disk */
H5FL_BLK_DEFINE_STATIC(sect_block);
@@ -146,7 +147,9 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
H5FS_t *fspace = NULL; /* Free space header info */
const H5FS_prot_t *fs_prot = (const H5FS_prot_t *)_fs_prot; /* User data for protecting */
size_t size; /* Header size */
- uint8_t *buf = NULL; /* Temporary buffer */
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5FS_HDR_BUF_SIZE]; /* Buffer for header */
+ uint8_t *hdr; /* Pointer to header buffer */
const uint8_t *p; /* Pointer into raw data buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
@@ -170,18 +173,22 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
/* Set free space manager's internal information */
fspace->addr = addr;
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't wrap buffer")
+
/* Compute the size of the free space header on disk */
size = H5FS_HEADER_SIZE(f);
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for header */
+ if(NULL == (hdr = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, buf) < 0)
+ if(H5F_block_read(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_READERROR, NULL, "can't read free space header")
- p = buf;
+ p = hdr;
/* Magic number */
if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
@@ -237,12 +244,12 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
H5F_DECODE_LENGTH(f, p, fspace->alloc_sect_size);
/* Compute checksum on indirect block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+ computed_chksum = H5_checksum_metadata(hdr, (size_t)(p - hdr), 0);
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
- HDassert((size_t)(p - buf) == size);
+ HDassert((size_t)(p - hdr) == size);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -252,8 +259,9 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
ret_value = fspace;
done:
- if(buf)
- H5FL_BLK_FREE(header_block, buf);
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && fspace)
(void)H5FS_cache_hdr_dest(f, fspace);
@@ -284,6 +292,8 @@ done:
static herr_t
H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_t *fspace, unsigned UNUSED * flags_ptr)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5FS_HDR_BUF_SIZE]; /* Buffer for header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_hdr_flush)
@@ -297,19 +307,24 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
HDassert(fspace);
if(fspace->cache_info.is_dirty) {
- uint8_t *buf = NULL; /* Temporary raw data buffer */
- uint8_t *p; /* Pointer into raw data buffer */
+ uint8_t *hdr; /* Pointer to header buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
uint32_t metadata_chksum; /* Computed metadata checksum value */
- size_t size; /* Header size on disk */
+ size_t size; /* Header size on disk */
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Compute the size of the free space header on disk */
size = H5FS_HEADER_SIZE(f);
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for header */
+ if(NULL == (hdr = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't get actual buffer")
- p = buf;
+ /* Get temporary pointer to header */
+ p = hdr;
/* Magic number */
HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
@@ -358,18 +373,16 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
H5F_ENCODE_LENGTH(f, p, fspace->alloc_sect_size);
/* Compute checksum */
- metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+ metadata_chksum = H5_checksum_metadata(hdr, (size_t)(p - hdr), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the free space header. */
- HDassert((size_t)(p - buf) == size);
- if(H5F_block_write(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, buf) < 0)
+ HDassert((size_t)(p - hdr) == size);
+ if(H5F_block_write(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space header to disk")
- H5FL_BLK_FREE(header_block, buf);
-
fspace->cache_info.is_dirty = FALSE;
} /* end if */
@@ -378,6 +391,10 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space header")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_cache_hdr_flush() */
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index a8a54b5..070d551 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -36,9 +36,9 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free lists */
#include "H5Gpkg.h" /* Groups */
#include "H5MMprivate.h" /* Memory management */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@@ -252,9 +252,6 @@ typedef struct {
/* Local Variables */
/*******************/
-/* Declare a free list to manage the serialized link information */
-H5FL_BLK_DEFINE(ser_link);
-
/*-------------------------------------------------------------------------
@@ -373,6 +370,7 @@ H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5G_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle */
size_t link_size; /* Size of serialized link in the heap */
+ H5WB_t *wb = NULL; /* Wrapped buffer for link data */
uint8_t link_buf[H5G_LINK_BUF_SIZE]; /* Buffer for serializing link */
void *link_ptr = NULL; /* Pointer to serialized link */
herr_t ret_value = SUCCEED; /* Return value */
@@ -397,13 +395,13 @@ HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr)
HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDstrlen(lnk->name), link_size);
#endif /* QAK */
- /* Allocate space for serialized link, if necessary */
- if(link_size > sizeof(link_buf)) {
- if(NULL == (link_ptr = H5FL_BLK_MALLOC(ser_link, link_size)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
- else
- link_ptr = link_buf;
+ /* Wrap the local buffer for serialized link */
+ if(NULL == (wb = H5WB_wrap(link_buf, sizeof(link_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for link */
+ if(NULL == (link_ptr = H5WB_actual(wb, link_size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of link */
if(H5O_msg_encode(f, H5O_LINK_ID, FALSE, link_ptr, lnk) < 0)
@@ -444,8 +442,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
- if(link_ptr && link_ptr != link_buf)
- H5FL_BLK_FREE(ser_link, link_ptr);
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_insert() */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 6baf175..fb3c999 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -39,6 +39,7 @@
#include "H5HLprivate.h" /* Local Heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/* Private typedefs */
@@ -67,6 +68,9 @@ typedef struct H5G_node_t {
#define H5G_NODE_VERS 1 /*symbol table node version number */
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
+/* Size of stack buffer for serialized nodes */
+#define H5G_NODE_BUF_SIZE 512
+
/* PRIVATE PROTOTYPES */
static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf);
static size_t H5G_node_size(const H5F_t *f);
@@ -142,9 +146,6 @@ H5FL_DEFINE_STATIC(H5G_node_t);
/* Declare a free list to manage sequences of H5G_entry_t's */
H5FL_SEQ_DEFINE_STATIC(H5G_entry_t);
-/* Declare a free list to manage blocks of symbol node data */
-H5FL_BLK_DEFINE_STATIC(symbol_node);
-
/* Declare a free list to manage the native key offset sequence information */
H5FL_SEQ_DEFINE_STATIC(size_t);
@@ -346,65 +347,83 @@ H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_udata1
void UNUSED * _udata2)
{
H5G_node_t *sym = NULL;
- size_t size = 0;
- uint8_t *buf = NULL;
- const uint8_t *p = NULL;
+ size_t size;
+ H5WB_t *wb = NULL; /* Wrapped buffer for node data */
+ uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
+ uint8_t *node; /* Pointer to node buffer */
+ const uint8_t *p;
H5G_node_t *ret_value; /*for error handling */
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_load);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_load)
/*
* Check arguments.
*/
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(!_udata1);
- assert(NULL == _udata2);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!_udata1);
+ HDassert(NULL == _udata2);
/*
* Initialize variables.
*/
+
+ /* Wrap the local buffer for serialized node info */
+ if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Compute the size of the serialized symbol table node on disk */
size = H5G_node_size(f);
- if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for symbol table node");
- p=buf;
- if(NULL == (sym = H5FL_CALLOC(H5G_node_t)) ||
- NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node");
+
+ /* Get a pointer to a buffer that's large enough for node */
+ if(NULL == (node = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ /* Read the serialized symbol table node. */
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node")
+
+ /* Get temporary pointer to serialized node */
+ p = node;
+
/* magic */
if(HDmemcmp(p, H5G_NODE_MAGIC, (size_t)H5G_NODE_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature")
p += 4;
/* version */
if(H5G_NODE_VERS != *p++)
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version")
+
/* reserved */
p++;
+ /* Allocate symbol table data structures */
+ if(NULL == (sym = H5FL_CALLOC(H5G_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
/* number of symbols */
UINT16DECODE(p, sym->nsyms);
/* entries */
if(H5G_ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries")
/* Set return value */
ret_value = sym;
done:
- if(buf)
- H5FL_BLK_FREE(symbol_node,buf);
- if(!ret_value) {
- if (sym)
- if(H5G_node_dest(f, sym)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node");
- }
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
+ if(!ret_value)
+ if(sym && H5G_node_dest(f, sym) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_load() */
/*-------------------------------------------------------------------------
@@ -443,65 +462,77 @@ done:
static herr_t
H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym, unsigned UNUSED * flags_ptr)
{
- uint8_t *buf = NULL;
- size_t size;
+ H5WB_t *wb = NULL; /* Wrapped buffer for node data */
+ uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush)
/*
* Check arguments.
*/
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(sym);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(sym);
/*
* Look for dirty entries and set the node dirty flag.
*/
- for (u = 0; u < sym->nsyms; u++)
- if (sym->entry[u].dirty) {
+ for(u = 0; u < sym->nsyms; u++)
+ if(sym->entry[u].dirty) {
/* Set the node's dirty flag */
sym->cache_info.is_dirty = TRUE;
/* Reset the entry's dirty flag */
- sym->entry[u].dirty=FALSE;
+ sym->entry[u].dirty = FALSE;
} /* end if */
/*
* Write the symbol node to disk.
*/
- if (sym->cache_info.is_dirty) {
+ if(sym->cache_info.is_dirty) {
+ uint8_t *node; /* Pointer to node buffer */
+ size_t size;
+
+ /* Wrap the local buffer for serialized node info */
+ if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Compute the size of the serialized symbol table node on disk */
size = H5G_node_size(f);
- /* Allocate temporary buffer */
- if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Get a pointer to a buffer that's large enough for node */
+ if(NULL == (node = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
- if (H5G_node_serialize(f, sym, size, buf) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed");
+ /* Serialize symbol table node into buffer */
+ if(H5G_node_serialize(f, sym, size, node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed")
- if (H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file");
- H5FL_BLK_FREE(symbol_node,buf);
+ /* Write the serialized symbol table node. */
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file")
/* Reset the node's dirty flag */
sym->cache_info.is_dirty = FALSE;
- }
+ } /* end if */
/*
* Destroy the symbol node? This might happen if the node is being
* preempted from the cache.
*/
- if (destroy) {
- if(H5G_node_dest(f, sym)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node");
- }
+ if(destroy)
+ if(H5G_node_dest(f, sym) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_flush() */
/*-------------------------------------------------------------------------
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 5dbfd2e..7e1130b 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -39,6 +39,7 @@
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
@@ -49,6 +50,12 @@
#define H5HF_DBLOCK_VERSION 0 /* Direct block */
#define H5HF_IBLOCK_VERSION 0 /* Indirect block */
+/* Size of stack buffer for serialized headers */
+#define H5HF_HDR_BUF_SIZE 512
+
+/* Size of stack buffer for serialized indirect blocks */
+#define H5HF_IBLOCK_BUF_SIZE 4096
+
/******************/
/* Local Typedefs */
@@ -126,15 +133,9 @@ const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{
/* Local Variables */
/*******************/
-/* Declare a free list to manage heap header data to/from disk */
-H5FL_BLK_DEFINE_STATIC(header_block);
-
/* Declare a free list to manage heap direct block data to/from disk */
H5FL_BLK_DEFINE(direct_block);
-/* Declare a free list to manage heap indirect block data to/from disk */
-H5FL_BLK_DEFINE_STATIC(indirect_block);
-
/*-------------------------------------------------------------------------
@@ -257,7 +258,9 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap info */
size_t size; /* Header size */
- uint8_t *buf = NULL; /* Temporary buffer */
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
+ uint8_t *buf; /* Pointer to header buffer */
const uint8_t *p; /* Pointer into raw data buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
@@ -280,17 +283,22 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
/* Set the heap header's address */
hdr->heap_addr = addr;
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
+
/* Compute the 'base' size of the fractal heap header on disk */
size = H5HF_HEADER_SIZE(hdr);
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header")
+ /* Get temporary pointer to serialized header */
p = buf;
/* Magic number */
@@ -300,7 +308,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
/* Version */
if(*p++ != H5HF_HDR_VERSION)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap header version")
+ HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap header version")
/* General heap information */
UINT16DECODE(p, hdr->id_len); /* Heap ID length */
@@ -358,8 +366,8 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
hdr->heap_size = size + filter_info_size;
/* Re-size current buffer */
- if((buf = H5FL_BLK_REALLOC(header_block, buf, hdr->heap_size)) == NULL)
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't allocate space to decode I/O pipeline filters")
+ if(NULL == (buf = H5WB_actual(wb, hdr->heap_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read in I/O filter information */
/* (and the checksum) */
@@ -416,8 +424,9 @@ HDfprintf(stderr, "%s: hdr->fspace = %p\n", FUNC, hdr->fspace);
ret_value = hdr;
done:
- if(buf)
- buf = H5FL_BLK_FREE(header_block, buf);
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
(void)H5HF_cache_hdr_dest(f, hdr);
@@ -446,6 +455,8 @@ done:
static herr_t
H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr, unsigned UNUSED * flags_ptr)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_flush)
@@ -471,13 +482,18 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
/* Set the shared heap header's file context for this operation */
hdr->f = f;
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
/* Compute the size of the heap header on disk */
size = hdr->heap_size;
- /* Allocate temporary buffer */
- if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
+ /* Get temporary pointer to serialized header */
p = buf;
/* Magic number */
@@ -547,8 +563,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap header to disk")
- buf = H5FL_BLK_FREE(header_block, buf);
-
hdr->dirty = FALSE;
hdr->cache_info.is_dirty = FALSE;
} /* end if */
@@ -558,6 +572,10 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap header")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_cache_hdr_flush() */
@@ -692,7 +710,9 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */
H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Shared parent information */
H5HF_indirect_t *iblock = NULL; /* Indirect block info */
- uint8_t *buf = NULL; /* Temporary buffer */
+ H5WB_t *wb = NULL; /* Wrapped buffer for indirect block data */
+ uint8_t iblock_buf[H5HF_IBLOCK_BUF_SIZE]; /* Buffer for indirect block */
+ uint8_t *buf; /* Temporary buffer */
const uint8_t *p; /* Pointer into raw data buffer */
haddr_t heap_addr; /* Address of heap header in the file */
uint32_t stored_chksum; /* Stored metadata checksum value */
@@ -732,18 +752,22 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr);
iblock->addr = addr;
iblock->nchildren = 0;
+ /* Wrap the local buffer for serialized indirect block */
+ if(NULL == (wb = H5WB_wrap(iblock_buf, sizeof(iblock_buf))))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
+
/* Compute size of indirect block */
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
- /* Allocate buffer to decode block */
-/* XXX: Use free list factories? */
- if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for serialized indirect block */
+ if(NULL == (buf = H5WB_actual(wb, iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read indirect block from disk */
if(H5F_block_read(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap indirect block")
+ /* Get temporary pointer to serialized indirect block */
p = buf;
/* Magic number */
@@ -753,7 +777,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr);
/* Version */
if(*p++ != H5HF_IBLOCK_VERSION)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version")
+ HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap direct block version")
/* Address of heap that owns this block */
H5F_addr_decode(f, &p, &heap_addr);
@@ -865,10 +889,9 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add
ret_value = iblock;
done:
- /* Free buffer */
-/* XXX: Keep buffer around? */
- buf = H5FL_BLK_FREE(indirect_block, buf);
-
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && iblock)
(void)H5HF_cache_iblock_dest(f, iblock);
@@ -898,6 +921,8 @@ done:
static herr_t
H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_indirect_t *iblock, unsigned UNUSED * flags_ptr)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for indirect block data */
+ uint8_t iblock_buf[H5HF_IBLOCK_BUF_SIZE]; /* Buffer for indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_flush)
@@ -912,7 +937,7 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
if(iblock->cache_info.is_dirty) {
H5HF_hdr_t *hdr; /* Shared fractal heap information */
- uint8_t *buf = NULL; /* Temporary buffer */
+ uint8_t *buf; /* Temporary buffer */
uint8_t *p; /* Pointer into raw data buffer */
#ifndef NDEBUG
unsigned nchildren = 0; /* Track # of children */
@@ -923,21 +948,25 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
/* Get the pointer to the shared heap header */
hdr = iblock->hdr;
-
- /* Set the shared heap header's file context for this operation */
- hdr->f = f;
-
- /* Allocate buffer to encode block */
-/* XXX: Use free list factories? */
#ifdef QAK
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtable.cparam.width);
#endif /* QAK */
- if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Set the shared heap header's file context for this operation */
+ hdr->f = f;
+
+ /* Wrap the local buffer for serialized indirect block */
+ if(NULL == (wb = H5WB_wrap(iblock_buf, sizeof(iblock_buf))))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for serialized indirect block */
+ if(NULL == (buf = H5WB_actual(wb, iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Get temporary pointer to buffer for serialized indirect block */
p = buf;
/* Magic number */
@@ -1013,9 +1042,6 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f
if(H5F_block_write(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap indirect block to disk")
- /* Free buffer */
- buf = H5FL_BLK_FREE(indirect_block, buf);
-
/* Reset dirty flags */
iblock->cache_info.is_dirty = FALSE;
} /* end if */
@@ -1025,6 +1051,10 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap indirect block")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_cache_iblock_flush() */
@@ -1292,7 +1322,7 @@ HDfprintf(stderr, "%s: nbytes = %Zu, read_size = %Zu, read_buf = %p\n", FUNC, nb
/* Version */
if(*p++ != H5HF_DBLOCK_VERSION)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version")
+ HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap direct block version")
/* Address of heap that owns this block (just for file integrity checks) */
H5F_addr_decode(f, &p, &heap_addr);
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index e78a1d3..9d4fd73 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -26,19 +26,29 @@
* the global heap.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5FLprivate.h" /* Free lists */
#include "H5Gprivate.h" /* Groups */
#include "H5HFprivate.h" /* Fractal heap */
-#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+/****************/
+/* Local Macros */
+/****************/
/* First version, with full symbol table entry as link for object header sharing */
#define H5O_SHARED_VERSION_1 1
@@ -53,8 +63,31 @@
/* Size of stack buffer for serialized messages */
#define H5O_MESG_BUF_SIZE 128
-/* Declare a free list to manage the serialized message information */
-H5FL_BLK_DEFINE(ser_mesg);
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
/*-------------------------------------------------------------------------
@@ -63,10 +96,7 @@ H5FL_BLK_DEFINE(ser_mesg);
* Purpose: Reads a message referred to by a shared message.
*
* Return: Success: Ptr to message in native format. The message
- * should be freed by calling H5O_msg_reset(). If
- * MESG is a null pointer then the caller should
- * also call H5MM_xfree() on the return value
- * after calling H5O_msg_reset().
+ * should be freed by calling H5O_msg_reset().
*
* Failure: NULL
*
@@ -81,8 +111,8 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
const H5O_msg_class_t *type)
{
H5HF_t *fheap = NULL;
+ H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t mesg_buf[H5O_MESG_BUF_SIZE]; /* Buffer for deserializing messages */
- uint8_t *buf = NULL; /* Pointer to raw message in heap */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_shared_read)
@@ -100,8 +130,9 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
/* Check for implicit shared object header message */
if(shared->type == H5O_SHARE_TYPE_SOHM) {
- haddr_t fheap_addr;
- size_t buf_size;
+ haddr_t fheap_addr; /* Address of SOHM heap */
+ uint8_t *mesg_ptr; /* Pointer to raw message in heap */
+ size_t mesg_size; /* Size of message */
/* Retrieve the fractal heap address for shared messages */
if(H5SM_get_fheap_addr(f, dxpl_id, type->id, &fheap_addr) < 0)
@@ -112,23 +143,23 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap")
/* Get the size of the message in the heap */
- if(H5HF_get_obj_len(fheap, dxpl_id, &(shared->u.heap_id), &buf_size) < 0)
+ if(H5HF_get_obj_len(fheap, dxpl_id, &(shared->u.heap_id), &mesg_size) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "can't get message size from fractal heap.")
- /* Allocate space for serialized message, if necessary */
- if(buf_size > sizeof(mesg_buf)) {
- if(NULL == (buf = H5FL_BLK_MALLOC(ser_mesg, buf_size)))
- HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "memory allocation failed")
- } /* end if */
- else
- buf = mesg_buf;
+ /* Wrap the local buffer for serialized message */
+ if(NULL == (wb = H5WB_wrap(mesg_buf, sizeof(mesg_buf))))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for message */
+ if(NULL == (mesg_ptr = H5WB_actual(wb, mesg_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Retrieve the message from the heap */
- if(H5HF_read(fheap, dxpl_id, &(shared->u.heap_id), buf) < 0)
+ if(H5HF_read(fheap, dxpl_id, &(shared->u.heap_id), mesg_ptr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "can't read message from fractal heap.")
/* Decode the message */
- if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, buf)))
+ if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, mesg_ptr)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.")
} /* end if */
else {
@@ -150,10 +181,10 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
done:
/* Release resources */
- if(buf && buf != mesg_buf)
- buf = H5FL_BLK_FREE(ser_mesg, buf);
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "can't close fractal heap")
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_read() */
diff --git a/src/H5SM.c b/src/H5SM.c
index b435c9d..88b4b10 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -69,13 +69,13 @@ static herr_t H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_index_header_t *header, unsigned type_id, void *mesg,
unsigned *cache_flags_ptr);
static herr_t H5SM_decr_ref(void *record, void *op_data, hbool_t *changed);
-static herr_t H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata);
static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_index_header_t *header, const H5O_shared_t * mesg,
unsigned *cache_flags, void ** /*out*/ encoded_mesg);
static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag);
static herr_t H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
hbool_t *oh_modified, void *_udata);
+static herr_t H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata);
static herr_t H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
H5O_t * open_oh, hid_t dxpl_id, size_t *encoding_size /*out*/,
void ** encoded_mesg /*out*/);
@@ -101,6 +101,7 @@ H5FL_ARR_DEFINE(H5SM_sohm_t, H5O_SHMESG_MAX_LIST_SIZE);
/*******************/
+
/*-------------------------------------------------------------------------
* Function: H5SM_init
*
diff --git a/src/H5SMcache.c b/src/H5SMcache.c
index 3b85bcf..371344a 100644
--- a/src/H5SMcache.c
+++ b/src/H5SMcache.c
@@ -17,8 +17,9 @@
/* Module Setup */
/****************/
-#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
+
/***********/
/* Headers */
@@ -28,157 +29,78 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5MMprivate.h" /* Memory management */
#include "H5SMpkg.h" /* Shared object header messages */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
/****************/
/* Local Macros */
/****************/
+/* Size of stack buffer for serialized tables */
+#define H5SM_TBL_BUF_SIZE 1024
+
+/* Size of stack buffer for serialized list indices */
+#define H5SM_LST_BUF_SIZE 1024
+
+
/******************/
/* Local Typedefs */
/******************/
+
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table);
-static H5SM_master_table_t *H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *table);
-static herr_t H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy);
-static herr_t H5SM_dest_table(H5F_t *f, H5SM_master_table_t* table);
-static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr);
-static herr_t H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list);
-static H5SM_list_t *H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
-static herr_t H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy);
-static herr_t H5SM_dest_list(H5F_t *f, H5SM_list_t* list);
+/* Metadata cache (H5AC) callbacks */
+static H5SM_master_table_t *H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *table);
+static herr_t H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table);
+static herr_t H5SM_table_dest(H5F_t *f, H5SM_master_table_t* table);
+static herr_t H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy);
+static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr);
+static H5SM_list_t *H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
+static herr_t H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list);
+static herr_t H5SM_list_dest(H5F_t *f, H5SM_list_t* list);
+static herr_t H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy);
static herr_t H5SM_list_size(const H5F_t *f, const H5SM_list_t UNUSED *list, size_t *size_ptr);
+
/*********************/
/* Package Variables */
/*********************/
/* H5SM inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_SOHM_TABLE[1] = {{
H5AC_SOHM_TABLE_ID,
- (H5AC_load_func_t) H5SM_load_table,
- (H5AC_flush_func_t) H5SM_flush_table,
- (H5AC_dest_func_t) H5SM_dest_table,
- (H5AC_clear_func_t)H5SM_clear_table,
- (H5AC_size_func_t) H5SM_table_size,
+ (H5AC_load_func_t)H5SM_table_load,
+ (H5AC_flush_func_t)H5SM_table_flush,
+ (H5AC_dest_func_t)H5SM_table_dest,
+ (H5AC_clear_func_t)H5SM_table_clear,
+ (H5AC_size_func_t)H5SM_table_size,
}};
const H5AC_class_t H5AC_SOHM_LIST[1] = {{
- H5AC_SOHM_LIST_ID,
- (H5AC_load_func_t) H5SM_load_list,
- (H5AC_flush_func_t) H5SM_flush_list,
- (H5AC_dest_func_t) H5SM_dest_list,
- (H5AC_clear_func_t)H5SM_clear_list,
- (H5AC_size_func_t) H5SM_list_size,
+ H5AC_SOHM_LIST_ID,
+ (H5AC_load_func_t)H5SM_list_load,
+ (H5AC_flush_func_t)H5SM_list_flush,
+ (H5AC_dest_func_t)H5SM_list_dest,
+ (H5AC_clear_func_t)H5SM_list_clear,
+ (H5AC_size_func_t)H5SM_list_size,
}};
-/* Declare a free list to manage data to/from disk */
-H5FL_BLK_DEFINE_STATIC(shared_mesg_cache);
/*****************************/
/* Library Private Variables */
/*****************************/
+
/*******************/
/* Local Variables */
/*******************/
-/*-------------------------------------------------------------------------
- * Function: H5SM_flush_table
- *
- * Purpose: Flushes (and destroys) the table of Shared Object Header
- * Message indexes.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: James Laird
- * November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
-{
- uint8_t *buf=NULL; /* Temporary buffer */
- herr_t ret_value=SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5SM_flush_table)
-
- /* check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(table);
-
- if(table->cache_info.is_dirty) {
- uint8_t *p; /* Pointer into raw data buffer */
- size_t size; /* Header size on disk */
- uint32_t computed_chksum; /* Computed metadata checksum value */
- int x; /* Counter variable */
-
- /* Verify that we're writing version 0 of the table; this is the only
- * version defined so far.
- */
- HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
-
- /* Encode the master table and all of the index headers as one big blob */
- size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
-
- /* Allocate the buffer */
- if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Encode the master table */
- p = buf;
-
- /* Encode magic number */
- HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC);
- p += H5SM_TABLE_SIZEOF_MAGIC;
-
- /* Encode each index header */
- for(x=0; x<table->num_indexes; ++x) {
- *p++ = H5SM_LIST_VERSION; /* Encode version for this list. */
- *p++ = table->indexes[x].index_type; /* Is message index a list or a B-tree? */
-
- UINT16ENCODE(p, table->indexes[x].mesg_types); /* Type of messages in the index */
- UINT32ENCODE(p, table->indexes[x].min_mesg_size); /* Minimum size of message to share */
- UINT16ENCODE(p, table->indexes[x].list_max); /* List cutoff; fewer than this number and index becomes a list */
- UINT16ENCODE(p, table->indexes[x].btree_min); /* B-tree cutoff; more than this number and index becomes a B-tree */
- UINT16ENCODE(p, table->indexes[x].num_messages); /* Number of messages shared */
- H5F_addr_encode(f, &p, table->indexes[x].index_addr); /* Address of the actual index */
- H5F_addr_encode(f, &p, table->indexes[x].heap_addr); /* Address of the index's heap */
- }
-
- /* Compute checksum on buffer */
- computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
- UINT32ENCODE(p, computed_chksum);
-
- /* Write the table to disk */
- HDassert((size_t)(p - buf) == size);
- if(H5F_block_write(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
-
- table->cache_info.is_dirty = FALSE;
-
- } /* end if */
-
- if(destroy)
- if(H5SM_dest_table(f, table) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
-
-done:
- /* Free buffer if allocated */
- if(buf)
- buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_flush_table */
-
/*-------------------------------------------------------------------------
- * Function: H5SM_load_table
+ * Function: H5SM_table_load
*
* Purpose: Loads the master table of Shared Object Header Message
* indexes.
@@ -191,22 +113,24 @@ done:
*-------------------------------------------------------------------------
*/
static H5SM_master_table_t *
-H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
+H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
{
H5SM_master_table_t *table = NULL;
- size_t table_size; /* Size of SOHM master table on disk */
- uint8_t *buf=NULL; /* Reading buffer */
- const uint8_t *p; /* Pointer into input buffer */
- uint32_t stored_chksum; /* Stored metadata checksum value */
- uint32_t computed_chksum; /* Computed metadata checksum value */
- uint8_t x; /* Counter variable for index headers */
+ size_t size; /* Size of SOHM master table on disk */
+ H5WB_t *wb = NULL; /* Wrapped buffer for table data */
+ uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */
+ uint8_t *buf; /* Reading buffer */
+ const uint8_t *p; /* Pointer into input buffer */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ size_t x; /* Counter variable for index headers */
H5SM_master_table_t *ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5SM_load_table)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_table_load)
/* Verify that we're reading version 0 of the table; this is the only
- * version defined so far.
- */
+ * version defined so far.
+ */
HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
/* Allocate space for the master table in memory */
@@ -220,25 +144,30 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
HDassert(addr != HADDR_UNDEF);
HDassert(table->num_indexes > 0);
+ /* Wrap the local buffer for serialized table info */
+ if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf))))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer")
+
/* Compute the size of the SOHM table header on disk. This is the "table" itself
* plus each index within the table
*/
- table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
+ size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
- /* Allocate temporary buffer */
- if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, table_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for serialized table */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_SOHM_TABLE, addr, table_size, dxpl_id, buf) < 0)
+ if(H5F_block_read(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM table")
+ /* Get temporary pointer to serialized table */
p = buf;
/* Check magic number */
- if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature");
- p += H5SM_TABLE_SIZEOF_MAGIC;
+ if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature")
+ p += H5SM_SIZEOF_MAGIC;
/* Don't count the checksum in the table size yet, since it comes after
* all of the index headers
@@ -250,49 +179,68 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes")
/* Read in the index headers */
- for(x=0; x<table->num_indexes; ++x) {
- if (H5SM_LIST_VERSION != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad shared message list version number")
+ for(x = 0; x < table->num_indexes; ++x) {
+ /* Verify correct version of index list */
+ if(H5SM_LIST_VERSION != *p++)
+ HGOTO_ERROR(H5E_FILE, H5E_VERSION, NULL, "bad shared message list version number")
- table->indexes[x].index_type= *p++; /* type of the index (list or B-tree) */
+ /* Type of the index (list or B-tree) */
+ table->indexes[x].index_type= *p++;
+
+ /* Type of messages in the index */
UINT16DECODE(p, table->indexes[x].mesg_types);
+
+ /* Minimum size of message to share */
UINT32DECODE(p, table->indexes[x].min_mesg_size);
+
+ /* List cutoff; fewer than this number and index becomes a list */
UINT16DECODE(p, table->indexes[x].list_max);
+
+ /* B-tree cutoff; more than this number and index becomes a B-tree */
UINT16DECODE(p, table->indexes[x].btree_min);
+
+ /* Number of messages shared */
UINT16DECODE(p, table->indexes[x].num_messages);
+
+ /* Address of the actual index */
H5F_addr_decode(f, &p, &(table->indexes[x].index_addr));
+
+ /* Address of the index's heap */
H5F_addr_decode(f, &p, &(table->indexes[x].heap_addr));
- }
+ } /* end for */
/* Read in checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
- HDassert((size_t)(p - buf) == table_size);
+ HDassert((size_t)(p - buf) == size);
/* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, (table_size - H5SM_SIZEOF_CHECKSUM), 0);
+ computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
- HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table");
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table")
+ /* Set return value */
ret_value = table;
done:
- /* Free buffer if allocated */
- if(buf)
- buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
+ if(!ret_value && table)
+ (void)H5SM_table_dest(f, table);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_load_table */
+} /* end H5SM_table_load() */
-
/*-------------------------------------------------------------------------
- * Function: H5SM_clear_table
+ * Function: H5SM_table_flush
*
- * Purpose: Mark this table as no longer being dirty.
+ * Purpose: Flushes (and destroys) the table of Shared Object Header
+ * Message indexes.
*
* Return: Non-negative on success/Negative on failure
*
@@ -302,32 +250,106 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy)
+H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for table data */
+ uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_table)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_table_flush)
- /*
- * Check arguments.
- */
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
HDassert(table);
- /* Reset the dirty flag. */
- table->cache_info.is_dirty = FALSE;
+ if(table->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ size_t x; /* Counter variable */
+
+ /* Verify that we're writing version 0 of the table; this is the only
+ * version defined so far.
+ */
+ HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf))))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Encode the master table and all of the index headers as one big blob */
+ size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
+
+ /* Get a pointer to a buffer that's large enough for serialized table */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Get temporary pointer to buffer for serialized table */
+ p = buf;
+
+ /* Encode magic number */
+ HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
+ p += H5SM_SIZEOF_MAGIC;
+
+ /* Encode each index header */
+ for(x = 0; x < table->num_indexes; ++x) {
+ /* Version for this list. */
+ *p++ = H5SM_LIST_VERSION;
+
+ /* Is message index a list or a B-tree? */
+ *p++ = table->indexes[x].index_type;
+
+ /* Type of messages in the index */
+ UINT16ENCODE(p, table->indexes[x].mesg_types);
+
+ /* Minimum size of message to share */
+ UINT32ENCODE(p, table->indexes[x].min_mesg_size);
+
+ /* List cutoff; fewer than this number and index becomes a list */
+ UINT16ENCODE(p, table->indexes[x].list_max);
+
+ /* B-tree cutoff; more than this number and index becomes a B-tree */
+ UINT16ENCODE(p, table->indexes[x].btree_min);
+
+ /* Number of messages shared */
+ UINT16ENCODE(p, table->indexes[x].num_messages);
+
+ /* Address of the actual index */
+ H5F_addr_encode(f, &p, table->indexes[x].index_addr);
+
+ /* Address of the index's heap */
+ H5F_addr_encode(f, &p, table->indexes[x].heap_addr);
+ } /* end for */
+
+ /* Compute checksum on buffer */
+ computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
+ UINT32ENCODE(p, computed_chksum);
+
+ /* Write the table to disk */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
+
+ table->cache_info.is_dirty = FALSE;
+ } /* end if */
if(destroy)
- if(H5SM_dest_table(f, table) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table")
+ if(H5SM_table_dest(f, table) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_clear_table */
+} /* end H5SM_table_flush() */
-
/*-------------------------------------------------------------------------
- * Function: H5SM_dest_table
+ * Function: H5SM_table_dest
*
* Purpose: Frees memory used by the SOHM table.
*
@@ -339,10 +361,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_dest_table(H5F_t UNUSED *f, H5SM_master_table_t* table)
+H5SM_table_dest(H5F_t UNUSED *f, H5SM_master_table_t* table)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_dest_table)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_dest)
+ /* Sanity check */
HDassert(table);
HDassert(table->indexes);
@@ -351,13 +374,13 @@ H5SM_dest_table(H5F_t UNUSED *f, H5SM_master_table_t* table)
H5FL_FREE(H5SM_master_table_t, table);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_dest_table */
+} /* end H5SM_table_dest() */
/*-------------------------------------------------------------------------
- * Function: H5SM_table_size
+ * Function: H5SM_table_clear
*
- * Purpose: Returns the size of the table encoded on disk.
+ * Purpose: Mark this table as no longer being dirty.
*
* Return: Non-negative on success/Negative on failure
*
@@ -367,27 +390,33 @@ H5SM_dest_table(H5F_t UNUSED *f, H5SM_master_table_t* table)
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr)
+H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_size)
+ herr_t ret_value = SUCCEED; /* Return value */
- /* check arguments */
- HDassert(f);
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_table_clear)
+
+ /*
+ * Check arguments.
+ */
HDassert(table);
- HDassert(size_ptr);
- /* Set size value */
- *size_ptr = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
+ /* Reset the dirty flag. */
+ table->cache_info.is_dirty = FALSE;
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_table_size */
+ if(destroy)
+ if(H5SM_table_dest(f, table) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_table_clear() */
/*-------------------------------------------------------------------------
- * Function: H5SM_flush_list
+ * Function: H5SM_table_size
*
- * Purpose: Flush this list index.
+ * Purpose: Returns the size of the table encoded on disk.
*
* Return: Non-negative on success/Negative on failure
*
@@ -397,81 +426,24 @@ H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_p
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
+H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr)
{
- uint8_t *buf=NULL; /* Temporary buffer */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5SM_flush_list)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_size)
/* check arguments */
HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(list);
- HDassert(list->header);
-
- if (list->cache_info.is_dirty) {
- uint8_t *p; /* Pointer into raw data buffer */
- size_t size; /* Header size on disk */
- uint32_t computed_chksum; /* Computed metadata checksum value */
- hsize_t x;
- hsize_t mesgs_written;
-
- size = H5SM_LIST_SIZE(f, list->header->num_messages);
-
- /* Allocate temporary buffer */
- if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Encode the list */
- p = buf;
-
- /* Encode magic number */
- HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC);
- p += H5SM_LIST_SIZEOF_MAGIC;
-
- /* Write messages from the messages array to disk */
- mesgs_written = 0;
- for(x=0; x<list->header->list_max && mesgs_written < list->header->num_messages; x++) {
- if(list->messages[x].location != H5SM_NO_LOC) {
- if(H5SM_message_encode(f, p, &(list->messages[x]))< 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
-
- p+=H5SM_SOHM_ENTRY_SIZE(f);
- ++mesgs_written;
- }
- }
-
- HDassert(mesgs_written == list->header->num_messages);
-
- /* Compute checksum on buffer */
- computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
- UINT32ENCODE(p, computed_chksum);
-
- /* Write the list to disk */
- HDassert((size_t)(p - buf) == size);
- if(H5F_block_write(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
-
- list->cache_info.is_dirty = FALSE;
- }
-
- if(destroy)
- if(H5SM_dest_list(f, list) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
+ HDassert(table);
+ HDassert(size_ptr);
-done:
- /* Free buffer if allocated */
- if(buf)
- buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
+ /* Set size value */
+ *size_ptr = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_flush_list */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_table_size() */
-
/*-------------------------------------------------------------------------
- * Function: H5SM_load_list
+ * Function: H5SM_list_load
*
* Purpose: Loads a list of SOHM messages.
*
@@ -483,20 +455,23 @@ done:
*-------------------------------------------------------------------------
*/
static H5SM_list_t *
-H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *udata2)
+H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *udata2)
{
- H5SM_list_t *list; /* The SOHM list being read in */
+ H5SM_list_t *list; /* The SOHM list being read in */
H5SM_index_header_t *header = (H5SM_index_header_t *) udata2; /* Index header for this list */
- size_t size; /* Size of SOHM list on disk */
- uint8_t *buf = NULL; /* Reading buffer */
- uint8_t *p; /* Pointer into input buffer */
- uint32_t stored_chksum; /* Stored metadata checksum value */
- uint32_t computed_chksum; /* Computed metadata checksum value */
- hsize_t x; /* Counter variable for messages in list */
- H5SM_list_t *ret_value=NULL;
-
- FUNC_ENTER_NOAPI_NOINIT(H5SM_load_list)
+ size_t size; /* Size of SOHM list on disk */
+ H5WB_t *wb = NULL; /* Wrapped buffer for list index data */
+ uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */
+ uint8_t *buf; /* Reading buffer */
+ uint8_t *p; /* Pointer into input buffer */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ size_t x; /* Counter variable for messages in list */
+ H5SM_list_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_list_load)
+ /* Sanity check */
HDassert(header);
/* Allocate space for the SOHM list data structure */
@@ -510,28 +485,33 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
list->header = header;
+ /* Wrap the local buffer for serialized list index info */
+ if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf))))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer")
+
/* Compute the size of the SOHM list on disk */
size = H5SM_LIST_SIZE(f, header->num_messages);
- /* Allocate temporary buffer */
- if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Get a pointer to a buffer that's large enough for serialized list index */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read list from disk */
if(H5F_block_read(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM list")
+
+ /* Get temporary pointer to serialized list index */
p = buf;
/* Check magic number */
- if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
- p += H5SM_LIST_SIZEOF_MAGIC;
+ if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature")
+ p += H5SM_SIZEOF_MAGIC;
/* Read messages into the list array */
- for(x = 0; x < header->num_messages; x++)
- {
+ for(x = 0; x < header->num_messages; x++) {
if(H5SM_message_decode(f, p, &(list->messages[x])) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message");
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message")
p += H5SM_SOHM_ENTRY_SIZE(f);
} /* end for */
@@ -541,42 +521,38 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
/* Sanity check */
HDassert((size_t)(p - buf) == size);
-
/* Compute checksum on entire header */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
- HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list");
-
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list")
/* Initialize the rest of the array */
for(x = header->num_messages; x < header->list_max; x++)
list->messages[x].location = H5SM_NO_LOC;
+ /* Set return value */
ret_value = list;
done:
- /* Free buffer if allocated */
- if(buf)
- buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
-
- if(ret_value == NULL) {
- if(list) {
- if(list->messages)
- H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
- H5FL_FREE(H5SM_list_t, list);
- } /* end if */
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
+ if(!ret_value && list) {
+ if(list->messages)
+ H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
+ H5FL_FREE(H5SM_list_t, list);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_load_list */
+} /* end H5SM_list_load() */
/*-------------------------------------------------------------------------
- * Function: H5SM_clear_list
+ * Function: H5SM_list_flush
*
- * Purpose: Marks a list as not dirty.
+ * Purpose: Flush this list index.
*
* Return: Non-negative on success/Negative on failure
*
@@ -586,31 +562,85 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy)
+H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
{
+ H5WB_t *wb = NULL; /* Wrapped buffer for list index data */
+ uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_list)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_list_flush)
- /*
- * Check arguments.
- */
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
HDassert(list);
+ HDassert(list->header);
- /* Reset the dirty flag. */
- list->cache_info.is_dirty = FALSE;
+ if(list->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ size_t mesgs_written; /* Number of messages written to list */
+ size_t x; /* Local index variable */
+
+ /* Wrap the local buffer for serialized list index info */
+ if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf))))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ size = H5SM_LIST_SIZE(f, list->header->num_messages);
+
+ /* Get a pointer to a buffer that's large enough for serialized list index */
+ if(NULL == (buf = H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Get temporary pointer to buffer for serialized list index */
+ p = buf;
+
+ /* Encode magic number */
+ HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
+ p += H5SM_SIZEOF_MAGIC;
+
+ /* Write messages from the messages array to disk */
+ mesgs_written = 0;
+ for(x = 0; x < list->header->list_max && mesgs_written < list->header->num_messages; x++) {
+ if(list->messages[x].location != H5SM_NO_LOC) {
+ if(H5SM_message_encode(f, p, &(list->messages[x])) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
+
+ p+=H5SM_SOHM_ENTRY_SIZE(f);
+ ++mesgs_written;
+ } /* end if */
+ } /* end for */
+ HDassert(mesgs_written == list->header->num_messages);
+
+ /* Compute checksum on buffer */
+ computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
+ UINT32ENCODE(p, computed_chksum);
+
+ /* Write the list to disk */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
+
+ list->cache_info.is_dirty = FALSE;
+ } /* end if */
if(destroy)
- if(H5SM_dest_list(f, list) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list")
+ if(H5SM_list_dest(f, list) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end of H5SM_clear_list */
+} /* end H5SM_list_flush() */
/*-------------------------------------------------------------------------
- * Function: H5SM_dest_list
+ * Function: H5SM_list_dest
*
* Purpose: Frees all memory used by the list.
*
@@ -622,9 +652,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_dest_list(H5F_t UNUSED *f, H5SM_list_t* list)
+H5SM_list_dest(H5F_t UNUSED *f, H5SM_list_t* list)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_dest_list)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_list_dest)
HDassert(list);
HDassert(list->messages);
@@ -634,7 +664,43 @@ H5SM_dest_list(H5F_t UNUSED *f, H5SM_list_t* list)
H5FL_FREE(H5SM_list_t, list);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_dest_list */
+} /* end H5SM_list_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_list_clear
+ *
+ * Purpose: Marks a list as not dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_list_clear)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(list);
+
+ /* Reset the dirty flag. */
+ list->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5SM_list_dest(f, list) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end of H5SM_list_clear() */
/*-------------------------------------------------------------------------
@@ -664,7 +730,5 @@ H5SM_list_size(const H5F_t UNUSED *f, const H5SM_list_t *list, size_t *size_ptr)
*size_ptr = H5SM_LIST_SIZE(f, list->header->list_max);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_list_size */
+} /* end H5SM_list_size() */
-
-
diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h
index 72be9f7..8d987a9 100755
--- a/src/H5SMpkg.h
+++ b/src/H5SMpkg.h
@@ -39,38 +39,55 @@
/****************************/
/* Package Macros */
/****************************/
-#define H5SM_LIST_MAGIC "SMLI"
-#define H5SM_LIST_SIZEOF_MAGIC 4
-#define H5SM_TABLE_MAGIC "SMTB"
-#define H5SM_TABLE_SIZEOF_MAGIC 4
-#define H5SM_SIZEOF_CHECKSUM 4
-
-#define H5SM_HEAP_LOC_SIZE (4 /* Reference count */ \
- + sizeof(H5O_fheap_id_t)) /* size of heap ID on disk */
-#define H5SM_OH_LOC_SIZE(f) (1 /* reserved (possible flags?) */ \
- + 1 /* message type ID */ \
- + 2 /* creation index of message in OH */ \
- + H5F_SIZEOF_ADDR(f)) /* address of OH */
+/* Size of signature information (on disk) */
+#define H5SM_SIZEOF_MAGIC 4
-#define H5SM_SOHM_ENTRY_SIZE(f) (1 /* Message location */ \
- + 4 /* Hash value */ \
- + MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)))
+/* Shared Message signatures */
+#define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */
+#define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */
-#define H5SM_TABLE_SIZE(f) ( H5SM_TABLE_SIZEOF_MAGIC \
- + H5SM_SIZEOF_CHECKSUM) /* Checksum */
-
-#define H5SM_INDEX_HEADER_SIZE(f) (1 /* Whether index is a list or B-tree */ \
- + 1 /* Version of index format */ \
- + 2 /* Type of messages stored in the index */ \
- + 4 /* Minimum size of messages to share */ \
- + (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
- + H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \
- + H5F_SIZEOF_ADDR(f)) /* Address of heap */
+/* Size of checksum information (on disk) */
+#define H5SM_SIZEOF_CHECKSUM 4
-#define H5SM_LIST_SIZE(f, num_mesg) H5SM_LIST_SIZEOF_MAGIC \
- + (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) \
- + H5SM_SIZEOF_CHECKSUM /* Checksum */
+#define H5SM_HEAP_LOC_SIZE ( \
+ 4 /* Reference count */ \
+ + sizeof(H5O_fheap_id_t) /* size of heap ID on disk */ \
+ )
+
+#define H5SM_OH_LOC_SIZE(f) ( \
+ 1 /* reserved (possible flags?) */ \
+ + 1 /* message type ID */ \
+ + 2 /* creation index of message in OH */ \
+ + H5F_SIZEOF_ADDR(f) /* address of OH */ \
+ )
+
+#define H5SM_SOHM_ENTRY_SIZE(f) ( \
+ 1 /* Message location */ \
+ + 4 /* Hash value */ \
+ + MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)) /* Entry */ \
+ )
+
+#define H5SM_TABLE_SIZE(f) ( \
+ H5SM_SIZEOF_MAGIC /* Signature */ \
+ + H5SM_SIZEOF_CHECKSUM /* Checksum */ \
+ )
+
+#define H5SM_INDEX_HEADER_SIZE(f) ( \
+ 1 /* Whether index is a list or B-tree */ \
+ + 1 /* Version of index format */ \
+ + 2 /* Type of messages stored in the index */ \
+ + 4 /* Minimum size of messages to share */ \
+ + (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
+ + H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \
+ + H5F_SIZEOF_ADDR(f) /* Address of heap */ \
+ )
+
+#define H5SM_LIST_SIZE(f, num_mesg) ( \
+ H5SM_SIZEOF_MAGIC /* Signature */ \
+ + (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) /* Message entries */ \
+ + H5SM_SIZEOF_CHECKSUM /* Checksum */ \
+ )
#define H5SM_B2_NODE_SIZE 512
#define H5SM_B2_SPLIT_PERCENT 100
@@ -168,7 +185,7 @@ struct H5SM_master_table_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
- uint8_t num_indexes; /* Number of indexes */
+ unsigned num_indexes; /* Number of indexes */
H5SM_index_header_t *indexes; /* Array of num_indexes indexes */
};
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 666c8da..844317b 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -29,6 +29,7 @@
#include "H5Iprivate.h" /* IDs */
#include "H5Spkg.h" /* Dataspaces */
#include "H5Vprivate.h" /* Vector and array functions */
+#include "H5WBprivate.h" /* Wrapped Buffers */
/* Local functions */
#ifdef LATER
@@ -37,8 +38,6 @@ static htri_t H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter);
static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
#endif /* LATER */
-/* Declare a free list to manage blocks of single datatype element data */
-H5FL_BLK_EXTERN(type_elem);
/*--------------------------------------------------------------------------
@@ -1437,9 +1436,11 @@ herr_t
H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
{
H5S_sel_iter_t iter; /* Selection iteration info */
- hbool_t iter_init=0; /* Selection iteration info has been initialized */
+ hbool_t iter_init = 0; /* Selection iteration info has been initialized */
+ H5WB_t *elem_wb = NULL; /* Wrapped buffer for element data */
+ uint8_t elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for element data */
uint8_t *buf; /* Current location in buffer */
- const void *fill=_fill; /* Alias for fill-value buffer */
+ const void *fill; /* Alias for fill-value buffer */
hssize_t nelmts; /* Number of elements in selection */
hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
@@ -1457,10 +1458,17 @@ H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_
assert(_buf);
/* Check if we need a temporary fill value buffer */
- if(fill==NULL) {
- if (NULL==(fill = H5FL_BLK_CALLOC(type_elem,fill_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "fill value buffer allocation failed");
+ if(_fill == NULL) {
+ /* Wrap the local buffer for elements */
+ if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Get a pointer to a buffer that's large enough for element */
+ if(NULL == (fill = H5WB_actual_clear(elem_wb, fill_size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
} /* end if */
+ else
+ fill = _fill;
/* Initialize iterator */
if (H5S_select_iter_init(&iter, space, fill_size)<0)
@@ -1495,15 +1503,11 @@ H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_
} /* end while */
done:
- /* Release selection iterator */
- if(iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
-
- /* Release fill value, if allocated */
- if(_fill==NULL && fill)
- H5FL_BLK_FREE(type_elem, (void *)fill); /* casting away const OK - QAK */
+ /* Release resouces */
+ if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
+ if(elem_wb && H5WB_unwrap(elem_wb) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_select_fill() */
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index b5cc696..e0d878a 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -3163,8 +3163,7 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
int direction; /*direction of traversal */
size_t elmtno; /*element number counter */
unsigned u; /* local index variable */
- void *bkg_buf=NULL; /*temporary background buffer */
- size_t bkg_buf_size=0; /*size of background buffer in bytes */
+ void *bkg_buf = NULL; /*temporary background buffer */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5T_conv_array, FAIL)
@@ -3239,10 +3238,12 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Check if we need a background buffer for this conversion */
if(tpath->cdata.need_bkg) {
+ size_t bkg_buf_size; /*size of background buffer in bytes */
+
/* Allocate background buffer */
bkg_buf_size = src->shared->u.array.nelem * MAX(src->shared->size, dst->shared->size);
- if((bkg_buf = H5FL_BLK_CALLOC(array_seq, bkg_buf_size)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(array_seq, bkg_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
/* Perform the actual conversion */
@@ -3259,10 +3260,6 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
dp += dst_delta;
} /* end for */
- /* Release the background buffer, if we have one */
- if(bkg_buf != NULL)
- H5FL_BLK_FREE(array_seq, bkg_buf);
-
/* Release the temporary datatype IDs used */
if(tsrc_id >= 0)
H5I_dec_ref(tsrc_id);
@@ -3275,6 +3272,10 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
} /* end switch */
done:
+ /* Release the background buffer, if we have one */
+ if(bkg_buf)
+ H5FL_BLK_FREE(array_seq, bkg_buf);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_conv_array() */
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 608284e..842eced 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -30,6 +30,9 @@
#include "H5Gprivate.h" /* Groups */
#include "H5Rprivate.h" /* References */
+/* Macro for size of temporary buffers to contain a single element */
+#define H5T_ELEM_BUF_SIZE 256
+
/* Forward references of package typedefs */
typedef struct H5T_t H5T_t;
typedef struct H5T_stats_t H5T_stats_t;
diff --git a/src/H5WB.c b/src/H5WB.c
new file mode 100644
index 0000000..e53c70c
--- /dev/null
+++ b/src/H5WB.c
@@ -0,0 +1,291 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5WB.c
+ * Jun 26 2007
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implements the "wrapped buffer" code for wrapping
+ * an existing [staticly sized] buffer, in order to
+ * avoid lots of memory allocation calls.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/* Typedef for buffer wrapper */
+struct H5WB_t {
+ void *wrapped_buf; /* Pointer to wrapped buffer */
+ size_t wrapped_size; /* Size of wrapped buffer */
+ void *actual_buf; /* Pointer to actual buffer */
+ size_t actual_size; /* Size of actual buffer used */
+ size_t alloc_size; /* Size of actual buffer allocated */
+};
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5WB_t struct */
+H5FL_DEFINE_STATIC(H5WB_t);
+
+/* Declare a free list to manage the extra buffer information */
+H5FL_BLK_DEFINE_STATIC(extra_buf);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_wrap
+ *
+ * Purpose: Wraps an existing [possibly static] buffer
+ *
+ * Return: Pointer to buffer wrapper info on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+H5WB_t *
+H5WB_wrap(void *buf, size_t buf_size)
+{
+ H5WB_t *wb = NULL; /* Wrapped buffer info */
+ H5WB_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_wrap, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(buf);
+ HDassert(buf_size);
+
+ /* Create wrapped buffer info */
+ if(NULL == (wb = H5FL_MALLOC(H5WB_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for wrapped buffer info")
+
+ /* Wrap buffer given */
+ wb->wrapped_buf = buf;
+ wb->wrapped_size = buf_size;
+
+ /* No actual buffer yet */
+ wb->actual_buf = NULL;
+ wb->actual_size = 0;
+ wb->alloc_size = 0;
+
+ /* Set the return value */
+ ret_value = wb;
+
+done:
+ /* Release resources on error */
+ if(!ret_value && wb)
+ (void)H5FL_FREE(H5WB_t, wb);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_wrap() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_actual
+ *
+ * Purpose: Get the pointer to an "actual" buffer, of at least a certain
+ * size.
+ *
+ * Return: Pointer to buffer pointer on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5WB_actual(H5WB_t *wb, size_t need)
+{
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_actual, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Check for previously allocated buffer */
+ if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
+ /* Sanity check */
+ HDassert(wb->actual_size > wb->wrapped_size);
+
+ /* Check if we can re-use existing buffer */
+ if(need <= wb->alloc_size)
+ HGOTO_DONE(wb->actual_buf)
+ /* Can't re-use existing buffer, free it and proceed */
+ else
+ wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
+ } /* end if */
+
+ /* Check if size needed can be fulfilled with wrapped buffer */
+ if(need > wb->wrapped_size) {
+ /* Need to allocate new buffer */
+ if(NULL == (wb->actual_buf = H5FL_BLK_MALLOC(extra_buf, need)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Remember size of buffer allocated */
+ wb->alloc_size = need;
+ } /* end if */
+ else {
+ /* Don't have to allocate a new buffer, use the wrapped one */
+ wb->actual_buf = wb->wrapped_buf;
+ wb->alloc_size = 0;
+ } /* end else */
+
+ /* Set the return value */
+ ret_value = wb->actual_buf;
+
+done:
+ /* Remember size of buffer used, if we were successful */
+ if(ret_value)
+ wb->actual_size = need;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_actual() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_actual_clear
+ *
+ * Purpose: Get the pointer to an "actual" buffer, of at least a certain
+ * size. Also, clear actual buffer to zeros.
+ *
+ * Return: Pointer to buffer pointer on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5WB_actual_clear(H5WB_t *wb, size_t need)
+{
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_actual_clear, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Get a pointer to an actual buffer */
+ if(NULL == (ret_value = H5WB_actual(wb, need)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Clear the buffer */
+ HDmemset(ret_value, 0, need);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_actual_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_unwrap
+ *
+ * Purpose: "unwrap" a wrapped buffer, releasing all resources used
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5WB_unwrap(H5WB_t *wb)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5WB_unwrap)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Release any extra buffers allocated */
+ if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
+ /* Sanity check */
+ HDassert(wb->actual_size > wb->wrapped_size);
+
+ wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
+ } /* end if */
+
+ /* Release the buffer wrapper info */
+ H5FL_FREE(H5WB_t, wb);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5WB_unwrap() */
+
diff --git a/src/H5WBprivate.h b/src/H5WBprivate.h
new file mode 100644
index 0000000..cfa3fcb
--- /dev/null
+++ b/src/H5WBprivate.h
@@ -0,0 +1,64 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5WBprivate.h
+ * Jun 26 2007
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Private header for library accessible wrapped buffer routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef _H5WBprivate_H
+#define _H5WBprivate_H
+
+/* Include package's public header */
+/* #include "H5WBpublic.h" */
+
+/* Private headers needed by this file */
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Wrapped buffer info (forward decl - defined in H5WB.c) */
+typedef struct H5WB_t H5WB_t;
+
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+
+/* General routines for wrapped buffer operations */
+H5_DLL H5WB_t *H5WB_wrap(void *buf, size_t buf_size);
+H5_DLL void *H5WB_actual(H5WB_t *wb, size_t need);
+H5_DLL void *H5WB_actual_clear(H5WB_t *wb, size_t need);
+H5_DLL herr_t H5WB_unwrap(H5WB_t *wb);
+
+#endif /* _H5WBprivate_H */
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 7f4fae2..1e593d2 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,7 +83,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Tfixed.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
H5Torder.c \
- H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \
+ H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c
diff --git a/src/Makefile.in b/src/Makefile.in
index 5aea1fb..4851429 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -114,7 +114,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdeprec.lo \
H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \
H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \
- H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo \
+ H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo \
H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \
H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS)
@@ -436,7 +436,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Tfixed.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
H5Torder.c \
- H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \
+ H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c
@@ -758,6 +758,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tstrpad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tvlen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5V.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5WB.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Z.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zdeflate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zfletcher32.Plo@am__quote@
diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c
index 13bbe86..0af179a 100644
--- a/tools/misc/h5debug.c
+++ b/tools/misc/h5debug.c
@@ -445,14 +445,14 @@ main(int argc, char *argv[])
status = H5FS_sects_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, extra, extra2);
- } else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC)) {
+ } else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC)) {
/*
* Debug shared message master table.
*/
status = H5SM_table_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, (unsigned) UFAIL, (unsigned) UFAIL);
- } else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC)) {
+ } else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC)) {
/*
* Debug shared message list index.
*/