summaryrefslogtreecommitdiffstats
path: root/src/H5WB.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-06-29 03:12:45 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-06-29 03:12:45 (GMT)
commitcad9846d77ea4926bb0f13cf5151c1a7ac05ec87 (patch)
treec88b30412b25b6fc5df9534a6ff2cf1742393a36 /src/H5WB.c
parent58467956ba56fc52dd03e3540f14b062f9a6c5bb (diff)
downloadhdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.zip
hdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.tar.gz
hdf5-cad9846d77ea4926bb0f13cf5151c1a7ac05ec87.tar.bz2
[svn-r13926] Description:
Add small interface to "wrap" a static buffer (usually on the stack), but still allow for buffers larger than the static buffer to be allocated. This can eliminate _many_ short-lived buffer allocations in situations where the buffer is a predictable size (or at least a "very likely" size). Also, some minor code cleanups, particularly in the SOHM caching code. Tested on: Mac OS X/32 10.4.10 (amazon)
Diffstat (limited to 'src/H5WB.c')
-rw-r--r--src/H5WB.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/H5WB.c b/src/H5WB.c
new file mode 100644
index 0000000..e53c70c
--- /dev/null
+++ b/src/H5WB.c
@@ -0,0 +1,291 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5WB.c
+ * Jun 26 2007
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implements the "wrapped buffer" code for wrapping
+ * an existing [staticly sized] buffer, in order to
+ * avoid lots of memory allocation calls.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/* Typedef for buffer wrapper */
+struct H5WB_t {
+ void *wrapped_buf; /* Pointer to wrapped buffer */
+ size_t wrapped_size; /* Size of wrapped buffer */
+ void *actual_buf; /* Pointer to actual buffer */
+ size_t actual_size; /* Size of actual buffer used */
+ size_t alloc_size; /* Size of actual buffer allocated */
+};
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5WB_t struct */
+H5FL_DEFINE_STATIC(H5WB_t);
+
+/* Declare a free list to manage the extra buffer information */
+H5FL_BLK_DEFINE_STATIC(extra_buf);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_wrap
+ *
+ * Purpose: Wraps an existing [possibly static] buffer
+ *
+ * Return: Pointer to buffer wrapper info on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+H5WB_t *
+H5WB_wrap(void *buf, size_t buf_size)
+{
+ H5WB_t *wb = NULL; /* Wrapped buffer info */
+ H5WB_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_wrap, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(buf);
+ HDassert(buf_size);
+
+ /* Create wrapped buffer info */
+ if(NULL == (wb = H5FL_MALLOC(H5WB_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for wrapped buffer info")
+
+ /* Wrap buffer given */
+ wb->wrapped_buf = buf;
+ wb->wrapped_size = buf_size;
+
+ /* No actual buffer yet */
+ wb->actual_buf = NULL;
+ wb->actual_size = 0;
+ wb->alloc_size = 0;
+
+ /* Set the return value */
+ ret_value = wb;
+
+done:
+ /* Release resources on error */
+ if(!ret_value && wb)
+ (void)H5FL_FREE(H5WB_t, wb);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_wrap() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_actual
+ *
+ * Purpose: Get the pointer to an "actual" buffer, of at least a certain
+ * size.
+ *
+ * Return: Pointer to buffer pointer on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5WB_actual(H5WB_t *wb, size_t need)
+{
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_actual, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Check for previously allocated buffer */
+ if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
+ /* Sanity check */
+ HDassert(wb->actual_size > wb->wrapped_size);
+
+ /* Check if we can re-use existing buffer */
+ if(need <= wb->alloc_size)
+ HGOTO_DONE(wb->actual_buf)
+ /* Can't re-use existing buffer, free it and proceed */
+ else
+ wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
+ } /* end if */
+
+ /* Check if size needed can be fulfilled with wrapped buffer */
+ if(need > wb->wrapped_size) {
+ /* Need to allocate new buffer */
+ if(NULL == (wb->actual_buf = H5FL_BLK_MALLOC(extra_buf, need)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Remember size of buffer allocated */
+ wb->alloc_size = need;
+ } /* end if */
+ else {
+ /* Don't have to allocate a new buffer, use the wrapped one */
+ wb->actual_buf = wb->wrapped_buf;
+ wb->alloc_size = 0;
+ } /* end else */
+
+ /* Set the return value */
+ ret_value = wb->actual_buf;
+
+done:
+ /* Remember size of buffer used, if we were successful */
+ if(ret_value)
+ wb->actual_size = need;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_actual() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_actual_clear
+ *
+ * Purpose: Get the pointer to an "actual" buffer, of at least a certain
+ * size. Also, clear actual buffer to zeros.
+ *
+ * Return: Pointer to buffer pointer on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5WB_actual_clear(H5WB_t *wb, size_t need)
+{
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5WB_actual_clear, NULL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Get a pointer to an actual buffer */
+ if(NULL == (ret_value = H5WB_actual(wb, need)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Clear the buffer */
+ HDmemset(ret_value, 0, need);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5WB_actual_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5WB_unwrap
+ *
+ * Purpose: "unwrap" a wrapped buffer, releasing all resources used
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 26 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5WB_unwrap(H5WB_t *wb)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5WB_unwrap)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(wb);
+ HDassert(wb->wrapped_buf);
+
+ /* Release any extra buffers allocated */
+ if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
+ /* Sanity check */
+ HDassert(wb->actual_size > wb->wrapped_size);
+
+ wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
+ } /* end if */
+
+ /* Release the buffer wrapper info */
+ H5FL_FREE(H5WB_t, wb);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5WB_unwrap() */
+