From cad9846d77ea4926bb0f13cf5151c1a7ac05ec87 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 28 Jun 2007 22:12:45 -0500 Subject: [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) --- MANIFEST | 2 + src/H5Adense.c | 50 ++-- src/H5B2cache.c | 69 ++++-- src/H5Dfill.c | 69 ++++-- src/H5FScache.c | 67 ++++-- src/H5Gdense.c | 24 +- src/H5Gnode.c | 145 +++++++----- src/H5HFcache.c | 116 +++++---- src/H5Oshared.c | 77 ++++-- src/H5SM.c | 3 +- src/H5SMcache.c | 652 ++++++++++++++++++++++++++++----------------------- src/H5SMpkg.h | 75 +++--- src/H5Sselect.c | 36 +-- src/H5Tconv.c | 17 +- src/H5Tprivate.h | 3 + src/H5WB.c | 291 +++++++++++++++++++++++ src/H5WBprivate.h | 64 +++++ src/Makefile.am | 2 +- src/Makefile.in | 5 +- tools/misc/h5debug.c | 4 +- 20 files changed, 1182 insertions(+), 589 deletions(-) create mode 100644 src/H5WB.c create mode 100644 src/H5WBprivate.h 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; xnum_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; xnum_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; xheader->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 + * + * 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 + * + * 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. */ -- cgit v0.12