diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2005-05-17 19:01:07 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2005-05-17 19:01:07 (GMT) |
commit | 9b4c1ce9f6e79cf3194b3777813365a623688c47 (patch) | |
tree | c28c7fcf1c9fb58011a46602ab48b54179375c18 /src | |
parent | 2afe0fcda114dd398e518d9f1242307f06b72fbc (diff) | |
download | hdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.zip hdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.tar.gz hdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.tar.bz2 |
[svn-r10750] Purpose:
New feature.
Description:
Add "memory pool" internal data structure. This set of routines is
designed to add a way to allocate small pieces of information for a particular
purpose and then free all the pieces at once (i.e. without having to free each
piece individually). Memory pools are also good for localizing lots of small
allocations that logically belong together.
For example, if you were constructing a temporary linked list, you could
create a new memory pool, allocate all the nodes for the list from the memory
pool and when you were done with the list, just destroy the pool instead of
tracking through the list and freeing each block independently.
Platforms tested:
FreeBSD 4.11 (sleipnir)
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5MP.c | 468 | ||||
-rw-r--r-- | src/H5MPpkg.h | 105 | ||||
-rw-r--r-- | src/H5MPprivate.h | 45 | ||||
-rw-r--r-- | src/H5MPtest.c | 236 | ||||
-rwxr-xr-x | src/Makefile.am | 17 | ||||
-rw-r--r-- | src/Makefile.in | 47 |
6 files changed, 873 insertions, 45 deletions
diff --git a/src/H5MP.c b/src/H5MP.c new file mode 100644 index 0000000..490b38a --- /dev/null +++ b/src/H5MP.c @@ -0,0 +1,468 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5MP.c + * May 2 2005 + * Quincey Koziol <koziol@ncsa.uiuc.edu> + * + * Purpose: Implements memory pools. (Similar to Apache's APR + * memory pools) + * + * Please see the documentation in: + * doc/html/TechNotes/MemoryPools.html for a full description + * of how they work, etc. + * + *------------------------------------------------------------------------- + */ + +#define H5MP_PACKAGE /*suppress error about including H5MPpkg */ + +/* Private headers */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5MPpkg.h" /* Memory Pools */ + +/****************/ +/* Local Macros */ +/****************/ + +/* Minimum sized block */ +#define H5MP_MIN_BLOCK (H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGNMENT) + +/* First block in page */ +#define H5MP_PAGE_FIRST_BLOCK(p) \ + (H5MP_page_blk_t *)((unsigned char *)(p) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))) + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/********************************/ +/* Package Variable Definitions */ +/********************************/ + + +/********************/ +/* Static Variables */ +/********************/ + +/* Declare a free list to manage the H5MP_pool_t struct */ +H5FL_DEFINE(H5MP_pool_t); + + + +/*------------------------------------------------------------------------- + * Function: H5MP_create + * + * Purpose: Create a new memory pool + * + * Return: Pointer to the memory pool "header" on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 2 2005 + * + *------------------------------------------------------------------------- + */ +H5MP_pool_t * +H5MP_create (size_t page_size, unsigned flags) +{ + H5MP_pool_t *mp; /* New memory pool header */ + H5MP_pool_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MP_create, NULL) + + /* Allocate space for the pool header */ + if (NULL==(mp = H5FL_MALLOC(H5MP_pool_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for memory pool header") + + /* Assign information */ + mp->page_size = H5MP_BLOCK_ALIGN(page_size); + mp->flags = flags; + + /* Initialize information */ + mp->free_size = 0; + mp->first = NULL; + mp->max_size = mp->page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)); + + /* Create factory for pool pages */ + if((mp->page_fac=H5FL_fac_init(page_size))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't create page factory") + + /* Set return value */ + ret_value = mp; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MP_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_new_page + * + * Purpose: Allocate new page for a memory pool + * + * Return: Pointer to the page allocated on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 4 2005 + * + *------------------------------------------------------------------------- + */ +static H5MP_page_t * +H5MP_new_page(H5MP_pool_t *mp, size_t page_size) +{ + H5MP_page_t *new_page; /* New page created */ + H5MP_page_blk_t *first_blk; /* Pointer to first block in page */ + H5MP_page_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5MP_new_page) + + /* Sanity check */ + HDassert(mp); + HDassert(page_size >= mp->page_size); + + /* Allocate page */ + if(page_size > mp->page_size) { + if(NULL == (new_page = H5MM_malloc(page_size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page") + new_page->free_size = page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)); + new_page->fac_alloc = FALSE; + } /* end if */ + else { + if((new_page = H5FL_FAC_MALLOC(mp->page_fac)) == NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page") + new_page->free_size = mp->max_size; + new_page->fac_alloc = TRUE; + } /* end else */ +#ifdef QAK +HDfprintf(stderr,"%s: Allocating new page = %p\n", FUNC, new_page); +#endif /* QAK */ + + /* Initialize page information */ + first_blk = H5MP_PAGE_FIRST_BLOCK(new_page); + first_blk->size = new_page->free_size; + first_blk->page = new_page; + first_blk->is_free = TRUE; + first_blk->prev = NULL; + first_blk->next = NULL; + + /* Insert into page list */ + new_page->prev = NULL; + new_page->next = mp->first; + if(mp->first) + mp->first->prev = new_page; + mp->first = new_page; + + /* Account for new free space */ + new_page->free_blk = first_blk; + mp->free_size += new_page->free_size; + + /* Assign return value */ + ret_value = new_page; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MP_new_page() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_malloc + * + * Purpose: Allocate space in a memory pool + * + * Return: Pointer to the space allocated on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 2 2005 + * + *------------------------------------------------------------------------- + */ +void * +H5MP_malloc (H5MP_pool_t *mp, size_t request) +{ + H5MP_page_t *alloc_page = NULL; /* Page to allocate space from */ + H5MP_page_blk_t *alloc_free; /* Pointer to free space in page */ + size_t needed; /* Size requested, plus block header and alignment */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MP_malloc, NULL) + + /* Sanity check */ + HDassert(mp); + HDassert(request > 0); + + /* Compute actual size needed */ + needed = H5MP_BLOCK_ALIGN(request) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)); +#ifdef QAK +HDfprintf(stderr,"%s: sizeof(H5MP_page_blk_t) = %Zu\n", FUNC, sizeof(H5MP_page_blk_t)); +HDfprintf(stderr,"%s: request = %Zu, needed = %Zu\n", FUNC, request, needed); +#endif /* QAK */ + + /* See if the request can be handled by existing free space */ + if(needed <= mp->free_size) { + size_t pool_free_avail; /* Amount of free space possibly available in pool */ + + /* Locate page with enough free space */ + alloc_page = mp->first; + pool_free_avail = mp->free_size; + while(alloc_page && pool_free_avail >= needed) { + /* If we found a page with enough free space, search for large + * enough free block on that page */ + if(alloc_page->free_size >= needed) { + size_t page_free_avail; /* Amount of free space possibly available */ + + /* Locate large enough block */ + alloc_free = alloc_page->free_blk; + page_free_avail = alloc_page->free_size; + while(alloc_free && page_free_avail >= needed) { + if(alloc_free->is_free) { + /* If we found a large enough block, leave now */ + if(alloc_free->size >= needed) + goto found; /* Needed to escape double "while" loop */ + + /* Decrement amount of potential space left */ + page_free_avail -= alloc_free->size; + } /* end if */ + + /* Go to next block */ + alloc_free = alloc_free->next; + } /* end while */ + } /* end if */ + + /* Decrement amount of potential space left */ + pool_free_avail -= alloc_page->free_size; + + /* Go to next page */ + alloc_page = alloc_page->next; + } /* end while */ + } /* end if */ + + { + size_t page_size; /* Size of page needed */ + + /* Check if the request is too large for a standard page */ + page_size = (needed > mp->max_size) ? + (needed + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))) : mp->page_size; + + /* Allocate new page */ + if(NULL == (alloc_page = H5MP_new_page(mp, page_size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page") + + /* Set the block to allocate from */ + alloc_free = alloc_page->free_blk; + } /* end block */ + + /* Allocate space in page */ +found: + + /* Sanity check */ + HDassert(alloc_page); + HDassert(alloc_free); + + /* Check if we can subdivide the free space */ + if(alloc_free->size > (needed + H5MP_MIN_BLOCK)) { + H5MP_page_blk_t *new_free; /* New free block created */ + + /* Carve out new free block after block to allocate */ + new_free = (H5MP_page_blk_t *)(((unsigned char *)alloc_free) + needed); + + /* Link into existing lists */ + new_free->next = alloc_free->next; + if(alloc_free->next) + alloc_free->next->prev = new_free; + new_free->prev = alloc_free; + alloc_free->next = new_free; + + /* Set blocks' information */ + new_free->size = alloc_free->size - needed; + new_free->is_free = TRUE; + new_free->page = alloc_free->page; + alloc_free->size = needed; + alloc_free->is_free = FALSE; + } /* end if */ + else { + /* Use whole free space block for new block */ + alloc_free->is_free = FALSE; + } /* end else */ + + /* Update page & pool's free size information */ + alloc_page->free_size -= alloc_free->size; + if(alloc_page->free_blk == alloc_free) + alloc_page->free_blk = alloc_free->next; + mp->free_size -= alloc_free->size; + + /* Set new space pointer for the return value */ + ret_value = ((unsigned char *)alloc_free) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)); +#ifdef QAK +HDfprintf(stderr,"%s: Allocating space from page, ret_value = %p\n", FUNC, ret_value); +#endif /* QAK */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MP_malloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_free + * + * Purpose: Release space in a memory pool + * + * Return: NULL on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 3 2005 + * + * Note: Should we release pages that have no used blocks? + * + *------------------------------------------------------------------------- + */ +void * +H5MP_free (H5MP_pool_t *mp, void *spc) +{ + H5MP_page_blk_t *spc_blk; /* Block for space to free */ + H5MP_page_t *spc_page; /* Page containing block to free */ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOFUNC(H5MP_free) + + /* Sanity check */ + HDassert(mp); + HDassert(spc); + + /* Get block header for space to free */ + spc_blk = (H5MP_page_blk_t *)(((unsigned char *)spc) - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))); + + /* Mark block as free */ + HDassert(spc_blk->is_free == FALSE); + spc_blk->is_free = TRUE; + + /* Add it's space to the amount of free space in the page & pool */ + spc_page = spc_blk->page; +#ifdef QAK +HDfprintf(stderr,"%s: Freeing from page = %p\n", "H5MP_free", spc_page); +#endif /* QAK */ + spc_page->free_size += spc_blk->size; + mp->free_size += spc_blk->size; + + /* Move page with newly freed space to front of list of pages in pool */ + if(spc_page != mp->first) { + /* Remove page from list */ + spc_page->prev->next = spc_page->next; + if(spc_page->next) + spc_page->next->prev = spc_page->prev; + + /* Insert page at beginning of list */ + spc_page->prev = NULL; + spc_page->next = mp->first; + mp->first->prev = spc_page; + mp->first = spc_page; + } /* end if */ + + /* Check if block can be merged with free space after it on page */ + if(spc_blk->next != NULL) { + H5MP_page_blk_t *next_blk; /* Block following space to free */ + + next_blk = spc_blk->next; + HDassert(next_blk->prev == spc_blk); + if(next_blk->is_free) { + spc_blk->size += next_blk->size; + spc_blk->next = next_blk->next; + } /* end if */ + } /* end if */ + + /* Check if block can be merged with free space before it on page */ + if(spc_blk->prev != NULL) { + H5MP_page_blk_t *prev_blk; /* Block before space to free */ + + prev_blk = spc_blk->prev; + HDassert(prev_blk->next == spc_blk); + if(prev_blk->is_free) { + prev_blk->size += spc_blk->size; + prev_blk->next = spc_blk->next; + } /* end if */ + } /* end if */ + + /* Check if the block freed becomes the first free block on the page */ + if(spc_page->free_blk == NULL || spc_blk < spc_page->free_blk) + spc_page->free_blk = spc_blk; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MP_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_close + * + * Purpose: Release all memory for a pool and destroy pool + * + * Return: Non-negative on success/negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 3 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5MP_close (H5MP_pool_t *mp) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5MP_close, FAIL) + + /* Release memory for pool pages */ + if(mp->first != NULL) { + H5MP_page_t *page, *next_page; /* Pointer to pages in pool */ + + /* Iterate through pages, releasing them */ + page = mp->first; + while(page) { + next_page = page->next; + + /* Free the page appropriately */ + if(page->fac_alloc) + H5FL_FAC_FREE(mp->page_fac,page); + else + H5MM_xfree(page); + + page = next_page; + } /* end while */ + } /* end if */ + + /* Release page factory */ + if(mp->page_fac) + if(H5FL_fac_term(mp->page_fac)<0) + HGOTO_ERROR (H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory") + + /* Free the memory pool itself */ + H5FL_FREE(H5MP_pool_t, mp); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MP_close() */ + diff --git a/src/H5MPpkg.h b/src/H5MPpkg.h new file mode 100644 index 0000000..3dc4bab --- /dev/null +++ b/src/H5MPpkg.h @@ -0,0 +1,105 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Monday, May 2, 2005 + * + * Purpose: This file contains declarations which are visible only within + * the H5MP package. Source files outside the H5MP package should + * include H5MPprivate.h instead. + */ +#ifndef H5MP_PACKAGE +#error "Do not include this file outside the H5MP package!" +#endif + +#ifndef _H5MPpkg_H +#define _H5MPpkg_H + +/* Get package's private header */ +#include "H5MPprivate.h" /* Memory Pools */ + +/* Other private headers needed by this file */ +#include "H5FLprivate.h" /* Free Lists */ + +/**************************/ +/* Package Private Macros */ +/**************************/ + +/* Alignment macros */ +/* (Ideas from Apache APR :-) */ + +/* Default alignment necessary */ +#define H5MP_BLOCK_ALIGNMENT 8 + +/* General alignment macro */ +/* (this only works for aligning to power of 2 boundary) */ +#define H5MP_ALIGN(x, a) \ + (((x) + ((size_t)(a)) - 1) & ~(((size_t)(a)) - 1)) + +/* Default alignment */ +#define H5MP_BLOCK_ALIGN(x) H5MP_ALIGN(x, H5MP_BLOCK_ALIGNMENT) + + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + +/* Free block in pool */ +typedef struct H5MP_page_blk_t { + size_t size; /* Size of block (includes this H5MP_page_blk_t info) */ + unsigned is_free:1; /* Flag to indicate the block is free */ + struct H5MP_page_t *page; /* Pointer to page block is located in */ + struct H5MP_page_blk_t *prev; /* Pointer to previous block in page */ + struct H5MP_page_blk_t *next; /* Pointer to next block in page */ +} H5MP_page_blk_t; + +/* Memory pool page */ +typedef struct H5MP_page_t { + size_t free_size; /* Total amount of free space in page */ + unsigned fac_alloc:1; /* Flag to indicate the page was allocated by the pool's factory */ + H5MP_page_blk_t *free_blk; /* Pointer to first free block in page */ + struct H5MP_page_t *next; /* Pointer to next page in pool */ + struct H5MP_page_t *prev; /* Pointer to previous page in pool */ +} H5MP_page_t; + +/* Memory pool header */ +struct H5MP_pool_t { + H5FL_fac_head_t *page_fac; /* Free-list factory for pages */ + size_t page_size; /* Page size for pool */ + size_t free_size; /* Total amount of free space in pool */ + size_t max_size; /* Maximum block that will fit in a standard page */ + H5MP_page_t *first; /* Pointer to first page in pool */ + unsigned flags; /* Bit flags for pool settings */ +}; + + +/*****************************************/ +/* Package Private Variable Declarations */ +/*****************************************/ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ +#ifdef H5MP_TESTING +H5_DLL herr_t H5MP_get_pool_free_size (const H5MP_pool_t *mp, size_t *free_size); +H5_DLL htri_t H5MP_pool_is_free_size_correct(const H5MP_pool_t *mp); +H5_DLL herr_t H5MP_get_pool_first_page(const H5MP_pool_t *mp, H5MP_page_t **page); +H5_DLL herr_t H5MP_get_page_free_size(const H5MP_page_t *mp, size_t *page); +H5_DLL herr_t H5MP_get_page_next_page(const H5MP_page_t *page, H5MP_page_t **next_page); +#endif /* H5MP_TESTING */ + +#endif /* _H5MPpkg_H */ + diff --git a/src/H5MPprivate.h b/src/H5MPprivate.h index fbe4df1..92249aa 100644 --- a/src/H5MPprivate.h +++ b/src/H5MPprivate.h @@ -12,11 +12,50 @@ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* - * Header file for private definitions of the MPE instrumentation. +/*------------------------------------------------------------------------- + * + * Created: H5MPprivate.h + * May 2 2005 + * Quincey Koziol <koziol@ncsa.uiuc.edu> + * + * Purpose: Private header for memory pool routines. + * + *------------------------------------------------------------------------- */ + #ifndef _H5MPprivate_H #define _H5MPprivate_H +/* Include package's public header (not yet) */ +/* #include "H5MPpublic.h" */ + +/* Private headers needed by this file */ + + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/* Pool creation flags */ +/* Default settings */ +#define H5MP_FLG_DEFAULT 0 +#define H5MP_PAGE_SIZE_DEFAULT 4096 /* (bytes) */ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* Memory pool header (defined in H5MPpkg.c) */ +typedef struct H5MP_pool_t H5MP_pool_t; + + +/***************************************/ +/* Library-private Function Prototypes */ +/***************************************/ +H5_DLL H5MP_pool_t *H5MP_create (size_t page_size, unsigned flags); +H5_DLL void * H5MP_malloc (H5MP_pool_t *mp, size_t request); +H5_DLL void * H5MP_free (H5MP_pool_t *mp, void *spc); +H5_DLL herr_t H5MP_close (H5MP_pool_t *mp); -#endif +#endif /* _H5MPprivate_H */ diff --git a/src/H5MPtest.c b/src/H5MPtest.c new file mode 100644 index 0000000..7962457 --- /dev/null +++ b/src/H5MPtest.c @@ -0,0 +1,236 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Tuesday, May 3, 2005 + * + * Purpose: Memory pool testing functions. + */ + +#define H5MP_PACKAGE /*suppress error about including H5MPpkg */ +#define H5MP_TESTING /*include H5MP testing funcs*/ + +/* Private headers */ +#include "H5private.h" /* Generic Functions */ +#include "H5MPpkg.h" /* Memory Pools */ +#include "H5Eprivate.h" /* Error handling */ + +/* Static Prototypes */ + +/* Package variables */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_get_pool_free_size + * + * Purpose: Retrieve the total amount of free space in entire pool + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, May 3, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5MP_get_pool_free_size(const H5MP_pool_t *mp, size_t *free_size) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MP_get_pool_free_size) + + /* Check arguments. */ + HDassert(mp); + HDassert(free_size); + + /* Get memory pool's free space */ + *free_size = mp->free_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5MP_get_pool_free_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_get_pool_first_page + * + * Purpose: Retrieve the first page in a memory pool + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, May 3, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5MP_get_pool_first_page(const H5MP_pool_t *mp, H5MP_page_t **page) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MP_get_pool_first_page) + + /* Check arguments. */ + HDassert(mp); + HDassert(page); + + /* Get memory pool's first page */ + *page = mp->first; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5MP_get_pool_first_page() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_pool_is_free_size_correct + * + * Purpose: Check that the free space reported in each page corresponds + * to the free size in each page and that the free space in the + * free blocks for a page corresponds with the free space for + * the page. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Wednesday, May 3, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5MP_pool_is_free_size_correct(const H5MP_pool_t *mp) +{ + H5MP_page_t *page; /* Pointer to current page */ + size_t pool_free; /* Size of pages' free space */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MP_pool_is_free_size_correct) + + /* Check arguments. */ + HDassert(mp); + + /* Iterate through pages, checking the free size & accumulating the + * free space for all the pages */ + page = mp->first; + pool_free = 0; + while(page != NULL) { + H5MP_page_blk_t *blk; /* Pointer to current free block */ + size_t page_free; /* Size of blocks on free list */ + + /* Iterate through the blocks in page, accumulating free space */ + blk = (H5MP_page_blk_t *)((unsigned char *)page + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))); + page_free = 0; + while(blk != NULL) { + if(blk->is_free) + page_free += blk->size; + blk = blk->next; + } /* end while */ + + /* Check that the free space from the blocks on the free list + * corresponds to space in page */ +#ifdef QAK +HDfprintf(stderr,"%s: page_free = %Zu, page->free_size = %Zu\n", "H5MP_pool_is_free_size_correct", page_free, page->free_size); +#endif /* QAK */ + if(page_free != page->free_size) + HGOTO_DONE (FALSE) + + /* Increment the amount of free space in pool */ + pool_free += page->free_size; + + /* Advance to next page */ + page = page->next; + } /* end while */ + + /* Check that the free space from the pages + * corresponds to free space in pool */ +#ifdef QAK +HDfprintf(stderr,"%s: pool_free = %Zu, mp->free_size = %Zu\n", "H5MP_pool_is_free_size_correct", pool_free, mp->free_size); +#endif /* QAK */ + if(pool_free != mp->free_size) + HGOTO_DONE (FALSE) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5MP_pool_is_free_size_correct() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_get_page_free_size + * + * Purpose: Retrieve the amount of free space in given page + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, May 3, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5MP_get_page_free_size(const H5MP_page_t *page, size_t *free_size) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MP_get_page_free_size) + + /* Check arguments. */ + HDassert(page); + HDassert(free_size); + + /* Get memory page's free space */ + *free_size = page->free_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5MP_get_page_free_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5MP_get_page_next_page + * + * Purpose: Retrieve the next page in the pool + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, May 3, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5MP_get_page_next_page(const H5MP_page_t *page, H5MP_page_t **next_page) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MP_get_page_next_page) + + /* Check arguments. */ + HDassert(page); + HDassert(next_page); + + /* Get next memory page */ + *next_page = page->next; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5MP_get_page_next_page() */ + diff --git a/src/Makefile.am b/src/Makefile.am index 50128e2..ec21d50 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,7 +52,9 @@ libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5B2.c H5B2cache.c H5B2dbg.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c \ H5G.c H5Gent.c H5Gnode.c H5Gstab.c \ - H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c H5O.c \ + H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ + H5MP.c H5MPtest.c \ + H5O.c \ H5Oattr.c H5Obogus.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ @@ -78,19 +80,6 @@ include_HEADERS =H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5B2public.h \ H5SHpublic.h \ H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h H5api_adpt.h -# Private headers -#noinst_HEADERS =H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ -# H5B2private.h \ -# H5BTprivate.h \ -# H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \ -# H5FOprivate.h H5FSprivate.h H5Gprivate.h H5Gpkg.h \ -# H5HGprivate.h H5HLprivate.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \ -# H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \ -# H5Rprivate.h H5RCprivate.h H5RSprivate.h H5Sprivate.h H5SHprivate.h \ -# H5STprivate.h \ -# H5Tprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \ -# H5Zprivate.h H5Zpkg.h H5config.h - # install libhdf5.settings in lib directory settingsdir=$(libdir) settings_DATA=libhdf5.settings diff --git a/src/Makefile.in b/src/Makefile.in index f9fc0c9..050139d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -92,20 +92,20 @@ am_libhdf5_la_OBJECTS = H5.lo H5A.lo H5AC.lo H5B.lo H5B2.lo \ H5FDstdio.lo H5FDstream.lo H5FL.lo H5FO.lo H5FP.lo \ H5FPclient.lo H5FPserver.lo H5FS.lo H5G.lo H5Gent.lo \ H5Gnode.lo H5Gstab.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo \ - H5HP.lo H5I.lo H5MF.lo H5MM.lo H5O.lo H5Oattr.lo H5Obogus.lo \ - H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Olayout.lo \ - H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo H5Osdspace.lo \ - H5Oshared.lo H5Ostab.lo H5P.lo H5Pdcpl.lo H5Pdxpl.lo \ - H5Pfapl.lo H5Pfcpl.lo H5Ptest.lo H5R.lo H5RC.lo H5RS.lo H5S.lo \ - H5Sall.lo H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo \ - H5Sselect.lo H5Stest.lo H5SH.lo H5SHcache.lo H5SHdbg.lo \ - H5SL.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \ - H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tenum.lo H5Tfields.lo \ - H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo \ - H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ - H5Tvlen.lo H5TS.lo H5V.lo H5Z.lo H5Zdeflate.lo \ - H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo H5Zszip.lo \ - H5Zscaleoffset.lo H5Ztrans.lo + H5HP.lo H5I.lo H5MF.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ + H5Oattr.lo H5Obogus.lo H5Ocont.lo H5Odtype.lo H5Oefl.lo \ + H5Ofill.lo H5Olayout.lo H5Omtime.lo H5Oname.lo H5Onull.lo \ + H5Opline.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo H5P.lo \ + H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo H5Ptest.lo H5R.lo \ + H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Shyper.lo H5Smpio.lo \ + H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo H5SH.lo \ + H5SHcache.lo H5SHdbg.lo H5SL.lo H5ST.lo H5T.lo H5Tarray.lo \ + H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ + H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \ + H5Tnative.lo H5Toffset.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ + H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo H5Z.lo \ + H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ + H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) H5detect_SOURCES = H5detect.c @@ -369,7 +369,9 @@ libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5B2.c H5B2cache.c H5B2dbg.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c \ H5G.c H5Gent.c H5Gnode.c H5Gstab.c \ - H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c H5O.c \ + H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ + H5MP.c H5MPtest.c \ + H5O.c \ H5Oattr.c H5Obogus.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ @@ -396,19 +398,6 @@ include_HEADERS = H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5B2public.h \ H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h H5api_adpt.h -# Private headers -#noinst_HEADERS =H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ -# H5B2private.h \ -# H5BTprivate.h \ -# H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \ -# H5FOprivate.h H5FSprivate.h H5Gprivate.h H5Gpkg.h \ -# H5HGprivate.h H5HLprivate.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \ -# H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \ -# H5Rprivate.h H5RCprivate.h H5RSprivate.h H5Sprivate.h H5SHprivate.h \ -# H5STprivate.h \ -# H5Tprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \ -# H5Zprivate.h H5Zpkg.h H5config.h - # install libhdf5.settings in lib directory settingsdir = $(libdir) settings_DATA = libhdf5.settings @@ -580,6 +569,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MM.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MP.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MPtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5O.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oattr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Obogus.Plo@am__quote@ |