diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-06-29 03:12:45 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-06-29 03:12:45 (GMT) |
commit | cad9846d77ea4926bb0f13cf5151c1a7ac05ec87 (patch) | |
tree | c88b30412b25b6fc5df9534a6ff2cf1742393a36 /src/H5WB.c | |
parent | 58467956ba56fc52dd03e3540f14b062f9a6c5bb (diff) | |
download | hdf5-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.c | 291 |
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() */ + |