diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 1998-01-16 22:23:43 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 1998-01-16 22:23:43 (GMT) |
commit | c2c94c31878dc42926661c9cb7e71be620196fc1 (patch) | |
tree | ee9ce2ae309882348dc1eafc1d105b5e6646605e /src/H5H.c | |
parent | 903e677366a86ea385d5cfe1241f3f53132941de (diff) | |
download | hdf5-c2c94c31878dc42926661c9cb7e71be620196fc1.zip hdf5-c2c94c31878dc42926661c9cb7e71be620196fc1.tar.gz hdf5-c2c94c31878dc42926661c9cb7e71be620196fc1.tar.bz2 |
[svn-r157] Reformatted code with indent...
Diffstat (limited to 'src/H5H.c')
-rw-r--r-- | src/H5H.c | 1587 |
1 files changed, 790 insertions, 797 deletions
@@ -1,1000 +1,993 @@ /*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. + * Copyright (C) 1997 National Center for Supercomputing Applications. * All rights reserved. * *------------------------------------------------------------------------- * - * Created: H5H.c - * Jul 16 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: H5H.c + * Jul 16 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Heap functions for the global small object heap - * and for local symbol table name heaps. + * Purpose: Heap functions for the global small object heap + * and for local symbol table name heaps. * * Modifications: * - * Robb Matzke, 5 Aug 1997 - * Added calls to H5E. + * Robb Matzke, 5 Aug 1997 + * Added calls to H5E. * *------------------------------------------------------------------------- */ -#include <H5private.h> /*library */ -#include <H5ACprivate.h> /*cache */ -#include <H5Eprivate.h> /*error handling */ -#include <H5Hprivate.h> /*self */ -#include <H5MFprivate.h> /*file memory management */ -#include <H5MMprivate.h> /*core memory management */ +#include <H5private.h> /*library */ +#include <H5ACprivate.h> /*cache */ +#include <H5Eprivate.h> /*error handling */ +#include <H5Hprivate.h> /*self */ +#include <H5MFprivate.h> /*file memory management */ +#include <H5MMprivate.h> /*core memory management */ -#define H5H_FREE_NULL 1 /*end of free list on disk */ -#define PABLO_MASK H5H_mask -#define H5H_ALIGN(X) (((X)+7)&~0x03) /*align on 8-byte boundary */ +#define H5H_FREE_NULL 1 /*end of free list on disk */ +#define PABLO_MASK H5H_mask +#define H5H_ALIGN(X) (((X)+7)&~0x03) /*align on 8-byte boundary */ typedef struct H5H_free_t { - size_t offset; /*offset of free block */ - size_t size; /*size of free block */ - struct H5H_free_t *prev; /*previous entry in free list */ - struct H5H_free_t *next; /*next entry in free list */ + size_t offset; /*offset of free block */ + size_t size; /*size of free block */ + struct H5H_free_t *prev; /*previous entry in free list */ + struct H5H_free_t *next; /*next entry in free list */ } H5H_free_t; typedef struct H5H_t { - intn dirty; - haddr_t addr; /*address of data */ - size_t disk_alloc; /*data bytes allocated on disk */ - size_t mem_alloc; /*data bytes allocated in mem */ - uint8 *chunk; /*the chunk, including header */ - H5H_free_t *freelist; /*the free list */ + intn dirty; + haddr_t addr; /*address of data */ + size_t disk_alloc; /*data bytes allocated on disk */ + size_t mem_alloc; /*data bytes allocated in mem */ + uint8 *chunk; /*the chunk, including header */ + H5H_free_t *freelist; /*the free list */ } H5H_t; /* PRIVATE PROTOTYPES */ -static H5H_t *H5H_load (H5F_t *f, const haddr_t *addr, const void *udata1, - void *udata2); -static herr_t H5H_flush (H5F_t *f, hbool_t dest, const haddr_t *addr, - H5H_t *heap); +static H5H_t *H5H_load(H5F_t *f, const haddr_t *addr, const void *udata1, + void *udata2); +static herr_t H5H_flush(H5F_t *f, hbool_t dest, const haddr_t *addr, + H5H_t *heap); /* * H5H inherits cache-like properties from H5AC */ -static const H5AC_class_t H5AC_HEAP[1] = {{ - H5AC_HEAP_ID, - (void*(*)(H5F_t*,const haddr_t*,const void*,void*))H5H_load, - (herr_t(*)(H5F_t*,hbool_t,const haddr_t*,void*))H5H_flush, -}}; +static const H5AC_class_t H5AC_HEAP[1] = +{ + { + H5AC_HEAP_ID, + (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5H_load, + (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5H_flush, + }}; /* Interface initialization */ -static intn interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL - +static intn interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL /*------------------------------------------------------------------------- - * Function: H5H_create + * Function: H5H_create * - * Purpose: Creates a new heap data structure on disk and caches it - * in memory. SIZE_HINT is a hint for the initial size of the - * data area of the heap. If size hint is invalid then a - * reasonable (but probably not optimal) size will be chosen. - * If the heap ever has to grow, then REALLOC_HINT is the - * minimum amount by which the heap will grow. + * Purpose: Creates a new heap data structure on disk and caches it + * in memory. SIZE_HINT is a hint for the initial size of the + * data area of the heap. If size hint is invalid then a + * reasonable (but probably not optimal) size will be chosen. + * If the heap ever has to grow, then REALLOC_HINT is the + * minimum amount by which the heap will grow. * - * Return: Success: SUCCEED. The file address of new heap is - * returned through the ADDR argument. + * Return: Success: SUCCEED. The file address of new heap is + * returned through the ADDR argument. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 16 1997 * * Modifications: * - * Robb Matzke, 5 Aug 1997 - * Takes a flag that determines the type of heap that is - * created. + * Robb Matzke, 5 Aug 1997 + * Takes a flag that determines the type of heap that is + * created. * *------------------------------------------------------------------------- */ herr_t -H5H_create (H5F_t *f, H5H_type_t heap_type, size_t size_hint, - haddr_t *addr/*out*/) +H5H_create(H5F_t *f, H5H_type_t heap_type, size_t size_hint, + haddr_t *addr /*out */ ) { - H5H_t *heap = NULL; - size_t total_size; /*total heap size on disk */ + H5H_t *heap = NULL; + size_t total_size; /*total heap size on disk */ - FUNC_ENTER (H5H_create, FAIL); + FUNC_ENTER(H5H_create, FAIL); - /* check arguments */ - assert (f); - assert (addr); - if (H5H_GLOBAL==heap_type) { + /* check arguments */ + assert(f); + assert(addr); + if (H5H_GLOBAL == heap_type) { #ifndef NDEBUG - fprintf (stderr, "H5H_create: a local heap is used as the global " - "heap\n"); + fprintf(stderr, "H5H_create: a local heap is used as the global " + "heap\n"); #endif - } - - size_hint = MAX (0, size_hint); - if (size_hint && size_hint<H5H_SIZEOF_FREE(f)) { - size_hint = H5H_SIZEOF_FREE(f); - } - size_hint = H5H_ALIGN (size_hint); - - /* allocate file version */ - total_size = H5H_SIZEOF_HDR(f) + size_hint; - if (H5MF_alloc (f, H5MF_META, total_size, addr/*out*/)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate file memory"); - } - - /* allocate memory version */ - heap = H5MM_xcalloc (1, sizeof(H5H_t)); - heap->addr = *addr; - H5F_addr_inc (&(heap->addr), H5H_SIZEOF_HDR (f)); - heap->disk_alloc = size_hint; - heap->mem_alloc = size_hint; - heap->chunk = H5MM_xcalloc (1, H5H_SIZEOF_HDR(f)+size_hint); - - /* free list */ - if (size_hint) { - heap->freelist = H5MM_xmalloc (sizeof(H5H_free_t)); - heap->freelist->offset = 0; - heap->freelist->size = size_hint; - heap->freelist->prev = heap->freelist->next = NULL; - } else { - heap->freelist = NULL; - } - - /* add to cache */ - heap->dirty = 1; - if (H5AC_set (f, H5AC_HEAP, addr, heap)<0) { - heap->chunk = H5MM_xfree (heap->chunk); - heap->freelist = H5MM_xfree (heap->freelist); - HRETURN_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, - "unable to cache heap"); - } - - FUNC_LEAVE (SUCCEED); + } + size_hint = MAX(0, size_hint); + if (size_hint && size_hint < H5H_SIZEOF_FREE(f)) { + size_hint = H5H_SIZEOF_FREE(f); + } + size_hint = H5H_ALIGN(size_hint); + + /* allocate file version */ + total_size = H5H_SIZEOF_HDR(f) + size_hint; + if (H5MF_alloc(f, H5MF_META, total_size, addr /*out */ ) < 0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate file memory"); + } + /* allocate memory version */ + heap = H5MM_xcalloc(1, sizeof(H5H_t)); + heap->addr = *addr; + H5F_addr_inc(&(heap->addr), H5H_SIZEOF_HDR(f)); + heap->disk_alloc = size_hint; + heap->mem_alloc = size_hint; + heap->chunk = H5MM_xcalloc(1, H5H_SIZEOF_HDR(f) + size_hint); + + /* free list */ + if (size_hint) { + heap->freelist = H5MM_xmalloc(sizeof(H5H_free_t)); + heap->freelist->offset = 0; + heap->freelist->size = size_hint; + heap->freelist->prev = heap->freelist->next = NULL; + } else { + heap->freelist = NULL; + } + + /* add to cache */ + heap->dirty = 1; + if (H5AC_set(f, H5AC_HEAP, addr, heap) < 0) { + heap->chunk = H5MM_xfree(heap->chunk); + heap->freelist = H5MM_xfree(heap->freelist); + HRETURN_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, + "unable to cache heap"); + } + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * Function: H5H_load + * Function: H5H_load * - * Purpose: Loads a heap from disk. + * Purpose: Loads a heap from disk. * - * Return: Success: Ptr to heap memory data structure. + * Return: Success: Ptr to heap memory data structure. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 17 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5H_t * -H5H_load (H5F_t *f, const haddr_t *addr, const void *udata1, void *udata2) +static H5H_t * +H5H_load(H5F_t *f, const haddr_t *addr, const void *udata1, void *udata2) { - uint8 hdr[20]; - const uint8 *p=NULL; - H5H_t *heap=NULL; - H5H_free_t *fl=NULL, *tail=NULL; - size_t free_block=H5H_FREE_NULL; - H5H_t *ret_value=NULL; - - FUNC_ENTER (H5H_load, NULL); - - /* check arguments */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - assert (H5H_SIZEOF_HDR(f) <= sizeof hdr); - assert (!udata1); - assert (!udata2); - - if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) { - HRETURN_ERROR (H5E_HEAP, H5E_READERROR, NULL, - "unable to read heap header"); - } - p = hdr; - heap = H5MM_xcalloc (1, sizeof(H5H_t)); - - /* magic number */ - if (HDmemcmp (hdr, H5H_MAGIC, H5H_SIZEOF_MAGIC)) { - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "bad heap signature"); - } - p += H5H_SIZEOF_MAGIC; - - /* heap data size */ - H5F_decode_length (f, p, heap->disk_alloc); - heap->mem_alloc = heap->disk_alloc; - - /* free list head */ - H5F_decode_length (f, p, free_block); - if (free_block!=H5H_FREE_NULL && free_block>=heap->disk_alloc) { - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "bad heap free list"); - } - - /* data */ - H5F_addr_decode (f, &p, &(heap->addr)); - heap->chunk = H5MM_xcalloc (1, H5H_SIZEOF_HDR(f) + heap->mem_alloc); - if (heap->disk_alloc && - H5F_block_read (f, &(heap->addr), heap->disk_alloc, - heap->chunk + H5H_SIZEOF_HDR(f))<0) { - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "unable to read heap data"); - } - - /* free list */ - while (H5H_FREE_NULL!=free_block) { - if (free_block>=heap->disk_alloc) { - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "bad heap free list"); - } - fl = H5MM_xmalloc (sizeof (H5H_free_t)); - fl->offset = free_block; - fl->prev = tail; - fl->next = NULL; - if (tail) tail->next = fl; - tail = fl; - if (!heap->freelist) heap->freelist = fl; - - p = heap->chunk + H5H_SIZEOF_HDR(f) + free_block; - H5F_decode_length (f, p, free_block); - H5F_decode_length (f, p, fl->size); - - if (fl->offset + fl->size > heap->disk_alloc) { - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "bad heap free list"); - } - } - - ret_value = heap; - - done: - if (!ret_value && heap) { - heap->chunk = H5MM_xfree (heap->chunk); - H5MM_xfree (heap); - for (fl=heap->freelist; fl; fl=tail) { - tail = fl->next; - H5MM_xfree (fl); - } - } - - FUNC_LEAVE (ret_value); + uint8 hdr[20]; + const uint8 *p = NULL; + H5H_t *heap = NULL; + H5H_free_t *fl = NULL, *tail = NULL; + size_t free_block = H5H_FREE_NULL; + H5H_t *ret_value = NULL; + + FUNC_ENTER(H5H_load, NULL); + + /* check arguments */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + assert(H5H_SIZEOF_HDR(f) <= sizeof hdr); + assert(!udata1); + assert(!udata2); + + if (H5F_block_read(f, addr, H5H_SIZEOF_HDR(f), hdr) < 0) { + HRETURN_ERROR(H5E_HEAP, H5E_READERROR, NULL, + "unable to read heap header"); + } + p = hdr; + heap = H5MM_xcalloc(1, sizeof(H5H_t)); + + /* magic number */ + if (HDmemcmp(hdr, H5H_MAGIC, H5H_SIZEOF_MAGIC)) { + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "bad heap signature"); + } + p += H5H_SIZEOF_MAGIC; + + /* heap data size */ + H5F_decode_length(f, p, heap->disk_alloc); + heap->mem_alloc = heap->disk_alloc; + + /* free list head */ + H5F_decode_length(f, p, free_block); + if (free_block != H5H_FREE_NULL && free_block >= heap->disk_alloc) { + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "bad heap free list"); + } + /* data */ + H5F_addr_decode(f, &p, &(heap->addr)); + heap->chunk = H5MM_xcalloc(1, H5H_SIZEOF_HDR(f) + heap->mem_alloc); + if (heap->disk_alloc && + H5F_block_read(f, &(heap->addr), heap->disk_alloc, + heap->chunk + H5H_SIZEOF_HDR(f)) < 0) { + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "unable to read heap data"); + } + /* free list */ + while (H5H_FREE_NULL != free_block) { + if (free_block >= heap->disk_alloc) { + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "bad heap free list"); + } + fl = H5MM_xmalloc(sizeof(H5H_free_t)); + fl->offset = free_block; + fl->prev = tail; + fl->next = NULL; + if (tail) + tail->next = fl; + tail = fl; + if (!heap->freelist) + heap->freelist = fl; + + p = heap->chunk + H5H_SIZEOF_HDR(f) + free_block; + H5F_decode_length(f, p, free_block); + H5F_decode_length(f, p, fl->size); + + if (fl->offset + fl->size > heap->disk_alloc) { + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "bad heap free list"); + } + } + + ret_value = heap; + + done: + if (!ret_value && heap) { + heap->chunk = H5MM_xfree(heap->chunk); + H5MM_xfree(heap); + for (fl = heap->freelist; fl; fl = tail) { + tail = fl->next; + H5MM_xfree(fl); + } + } + FUNC_LEAVE(ret_value); } - /*------------------------------------------------------------------------- - * Function: H5H_flush + * Function: H5H_flush * - * Purpose: Flushes a heap from memory to disk if it's dirty. Optionally - * deletes the heap from memory. + * Purpose: Flushes a heap from memory to disk if it's dirty. Optionally + * deletes the heap from memory. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 17 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5H_flush (H5F_t *f, hbool_t destroy, const haddr_t *addr, H5H_t *heap) +H5H_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5H_t *heap) { - uint8 *p = heap->chunk; - H5H_free_t *fl = heap->freelist; - haddr_t hdr_end_addr; - - FUNC_ENTER (H5H_flush, FAIL); - - /* check arguments */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - assert (heap); - - if (heap->dirty) { - - /* - * If the heap grew larger than disk storage then move the - * data segment of the heap to a larger contiguous block of - * disk storage. - */ - if (heap->mem_alloc > heap->disk_alloc) { - haddr_t old_addr = heap->addr, new_addr; - if (H5MF_alloc (f, H5MF_META, heap->mem_alloc, &new_addr/*out*/)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate file space for heap"); - } - heap->addr = new_addr; - H5MF_free (f, &old_addr, heap->disk_alloc); - H5ECLEAR;/*don't really care if the free failed*/ - heap->disk_alloc = heap->mem_alloc; - } - - /* - * Write the header. - */ - HDmemcpy (p, H5H_MAGIC, H5H_SIZEOF_MAGIC); p += H5H_SIZEOF_MAGIC; - H5F_encode_length (f, p, heap->mem_alloc); - H5F_encode_length (f, p, fl?fl->offset:H5H_FREE_NULL); - H5F_addr_encode (f, &p, &(heap->addr)); - - /* - * Write the free list. - */ - while (fl) { - p = heap->chunk + H5H_SIZEOF_HDR(f) + fl->offset; - if (fl->next) { - H5F_encode_length (f, p, fl->next->offset); - } else { - H5F_encode_length (f, p, H5H_FREE_NULL); - } - H5F_encode_length (f, p, fl->size); - fl = fl->next; - } - - /* - * Copy buffer to disk. - */ - hdr_end_addr = *addr; - H5F_addr_inc (&hdr_end_addr, H5H_SIZEOF_HDR (f)); - if (H5F_addr_eq (&(heap->addr), &hdr_end_addr)) { - /* The header and data are contiguous */ - if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f)+heap->disk_alloc, - heap->chunk)<0) { - HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, - "unable to write heap header and data to disk"); - } - } else { - if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f), heap->chunk)<0) { - HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, - "unable to write heap header to disk"); - } - if (H5F_block_write (f, &(heap->addr), heap->disk_alloc, - heap->chunk + H5H_SIZEOF_HDR(f))<0) { - HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, - "unable to write heap data to disk"); - } - } - - heap->dirty = 0; - } - - /* - * Should we destroy the memory version? - */ - if (destroy) { - heap->chunk = H5MM_xfree (heap->chunk); - while (heap->freelist) { - fl = heap->freelist; - heap->freelist = fl->next; - H5MM_xfree (fl); - } - H5MM_xfree (heap); - } - - FUNC_LEAVE (SUCCEED); + uint8 *p = heap->chunk; + H5H_free_t *fl = heap->freelist; + haddr_t hdr_end_addr; + + FUNC_ENTER(H5H_flush, FAIL); + + /* check arguments */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + assert(heap); + + if (heap->dirty) { + + /* + * If the heap grew larger than disk storage then move the + * data segment of the heap to a larger contiguous block of + * disk storage. + */ + if (heap->mem_alloc > heap->disk_alloc) { + haddr_t old_addr = heap->addr, new_addr; + if (H5MF_alloc(f, H5MF_META, heap->mem_alloc, &new_addr /*out */ ) < 0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate file space for heap"); + } + heap->addr = new_addr; + H5MF_free(f, &old_addr, heap->disk_alloc); + H5ECLEAR; /*don't really care if the free failed */ + heap->disk_alloc = heap->mem_alloc; + } + /* + * Write the header. + */ + HDmemcpy(p, H5H_MAGIC, H5H_SIZEOF_MAGIC); + p += H5H_SIZEOF_MAGIC; + H5F_encode_length(f, p, heap->mem_alloc); + H5F_encode_length(f, p, fl ? fl->offset : H5H_FREE_NULL); + H5F_addr_encode(f, &p, &(heap->addr)); + + /* + * Write the free list. + */ + while (fl) { + p = heap->chunk + H5H_SIZEOF_HDR(f) + fl->offset; + if (fl->next) { + H5F_encode_length(f, p, fl->next->offset); + } else { + H5F_encode_length(f, p, H5H_FREE_NULL); + } + H5F_encode_length(f, p, fl->size); + fl = fl->next; + } + + /* + * Copy buffer to disk. + */ + hdr_end_addr = *addr; + H5F_addr_inc(&hdr_end_addr, H5H_SIZEOF_HDR(f)); + if (H5F_addr_eq(&(heap->addr), &hdr_end_addr)) { + /* The header and data are contiguous */ + if (H5F_block_write(f, addr, H5H_SIZEOF_HDR(f) + heap->disk_alloc, + heap->chunk) < 0) { + HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, + "unable to write heap header and data to disk"); + } + } else { + if (H5F_block_write(f, addr, H5H_SIZEOF_HDR(f), heap->chunk) < 0) { + HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, + "unable to write heap header to disk"); + } + if (H5F_block_write(f, &(heap->addr), heap->disk_alloc, + heap->chunk + H5H_SIZEOF_HDR(f)) < 0) { + HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, + "unable to write heap data to disk"); + } + } + + heap->dirty = 0; + } + /* + * Should we destroy the memory version? + */ + if (destroy) { + heap->chunk = H5MM_xfree(heap->chunk); + while (heap->freelist) { + fl = heap->freelist; + heap->freelist = fl->next; + H5MM_xfree(fl); + } + H5MM_xfree(heap); + } + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * Function: H5H_read + * Function: H5H_read * - * Purpose: Reads some object (or part of an object) from the heap - * whose address is ADDR in file F. OFFSET is the byte offset - * from the beginning of the heap at which to begin reading - * and SIZE is the number of bytes to read. + * Purpose: Reads some object (or part of an object) from the heap + * whose address is ADDR in file F. OFFSET is the byte offset + * from the beginning of the heap at which to begin reading + * and SIZE is the number of bytes to read. * - * If BUF is the null pointer then a buffer is allocated by - * this function. + * If BUF is the null pointer then a buffer is allocated by + * this function. * - * Attempting to read past the end of an object may cause this - * function to fail. + * Attempting to read past the end of an object may cause this + * function to fail. * - * If the heap address ADDR is the the null pointer then the - * address comes from the H5F_t global heap field. + * If the heap address ADDR is the the null pointer then the + * address comes from the H5F_t global heap field. * - * Return: Success: BUF (or the allocated buffer) + * Return: Success: BUF (or the allocated buffer) * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 16 1997 * * Modifications: * *------------------------------------------------------------------------- */ -void * -H5H_read (H5F_t *f, const haddr_t *addr, size_t offset, size_t size, void *buf) +void * +H5H_read(H5F_t *f, const haddr_t *addr, size_t offset, size_t size, void *buf) { - H5H_t *heap = NULL; + H5H_t *heap = NULL; - FUNC_ENTER (H5H_read, NULL); + FUNC_ENTER(H5H_read, NULL); - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (offset>=0); + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(offset >= 0); - if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "unable to load heap"); - } - assert (offset<heap->mem_alloc); - assert (offset+size<=heap->mem_alloc); + if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "unable to load heap"); + } + assert(offset < heap->mem_alloc); + assert(offset + size <= heap->mem_alloc); - if (!buf) buf = H5MM_xmalloc (size); - HDmemcpy (buf, heap->chunk+H5H_SIZEOF_HDR(f)+offset, size); + if (!buf) + buf = H5MM_xmalloc(size); + HDmemcpy(buf, heap->chunk + H5H_SIZEOF_HDR(f) + offset, size); - FUNC_LEAVE (buf); + FUNC_LEAVE(buf); } - /*------------------------------------------------------------------------- - * Function: H5H_peek + * Function: H5H_peek * - * Purpose: This function is a more efficient version of H5H_read. - * Instead of copying a heap object into a caller-supplied - * buffer, this function returns a pointer directly into the - * cache where the heap is being held. Thus, the return pointer - * is valid only until the next call to the cache. + * Purpose: This function is a more efficient version of H5H_read. + * Instead of copying a heap object into a caller-supplied + * buffer, this function returns a pointer directly into the + * cache where the heap is being held. Thus, the return pointer + * is valid only until the next call to the cache. * - * The address of the heap is ADDR in file F. OFFSET is the - * byte offset of the object from the beginning of the heap and - * may include an offset into the interior of the object. + * The address of the heap is ADDR in file F. OFFSET is the + * byte offset of the object from the beginning of the heap and + * may include an offset into the interior of the object. * - * If the heap address ADDR is the null pointer then - * the address comes from the H5F_t global heap field. + * If the heap address ADDR is the null pointer then + * the address comes from the H5F_t global heap field. * - * Return: Success: Ptr to the object. The pointer points to - * a chunk of memory large enough to hold the - * object from the specified offset (usually - * the beginning of the object) to the end - * of the object. Do not attempt to read past - * the end of the object. + * Return: Success: Ptr to the object. The pointer points to + * a chunk of memory large enough to hold the + * object from the specified offset (usually + * the beginning of the object) to the end + * of the object. Do not attempt to read past + * the end of the object. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 16 1997 * * Modifications: * *------------------------------------------------------------------------- */ -const void * -H5H_peek (H5F_t *f, const haddr_t *addr, size_t offset) +const void * +H5H_peek(H5F_t *f, const haddr_t *addr, size_t offset) { - H5H_t *heap = NULL; - const void *retval = NULL; - - FUNC_ENTER (H5H_peek, NULL); - - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (offset>=0); - - if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, - "unable to load heap"); - } - assert (offset<heap->mem_alloc); - - retval = heap->chunk+H5H_SIZEOF_HDR(f)+offset; - FUNC_LEAVE (retval); + H5H_t *heap = NULL; + const void *retval = NULL; + + FUNC_ENTER(H5H_peek, NULL); + + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(offset >= 0); + + if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, + "unable to load heap"); + } + assert(offset < heap->mem_alloc); + + retval = heap->chunk + H5H_SIZEOF_HDR(f) + offset; + FUNC_LEAVE(retval); } - /*------------------------------------------------------------------------- - * Function: H5H_remove_free + * Function: H5H_remove_free * - * Purpose: Removes free list element FL from the specified heap and - * frees it. + * Purpose: Removes free list element FL from the specified heap and + * frees it. * - * Return: NULL + * Return: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 17 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5H_free_t * -H5H_remove_free (H5H_t *heap, H5H_free_t *fl) +static H5H_free_t * +H5H_remove_free(H5H_t *heap, H5H_free_t *fl) { - if (fl->prev) fl->prev->next = fl->next; - if (fl->next) fl->next->prev = fl->prev; - - if (!fl->prev) heap->freelist = fl->next; - return H5MM_xfree (fl); + if (fl->prev) + fl->prev->next = fl->next; + if (fl->next) + fl->next->prev = fl->prev; + + if (!fl->prev) + heap->freelist = fl->next; + return H5MM_xfree(fl); } - /*------------------------------------------------------------------------- - * Function: H5H_insert + * Function: H5H_insert * - * Purpose: Inserts a new item into the heap. + * Purpose: Inserts a new item into the heap. * - * If the heap address ADDR is the null pointer then - * the address comes from the H5F_t global heap field. + * If the heap address ADDR is the null pointer then + * the address comes from the H5F_t global heap field. * - * Return: Success: Offset of new item within heap. + * Return: Success: Offset of new item within heap. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 17 1997 * * Modifications: * *------------------------------------------------------------------------- */ size_t -H5H_insert (H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf) +H5H_insert(H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf) { - H5H_t *heap=NULL; - H5H_free_t *fl=NULL, *max_fl=NULL; - size_t offset = 0; - size_t need_size, old_size, need_more; - hbool_t found; + H5H_t *heap = NULL; + H5H_free_t *fl = NULL, *max_fl = NULL; + size_t offset = 0; + size_t need_size, old_size, need_more; + hbool_t found; #ifndef NDEBUG - static nmessages = 0; + static nmessages = 0; #endif - FUNC_ENTER (H5H_insert, FAIL); - - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (buf_size>0); - assert (buf); - - if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, - "unable to load heap"); - } - heap->dirty += 1; - - /* - * In order to keep the free list descriptors aligned on word boundaries, - * whatever that might mean, we round the size up to the next multiple of - * a word. - */ - need_size = H5H_ALIGN (buf_size); - - /* - * Look for a free slot large enough for this object and which would - * leave zero or at least H5G_SIZEOF_FREE bytes left over. - */ - for (fl=heap->freelist,found=FALSE; fl; fl=fl->next) { - if (fl->size>need_size && fl->size-need_size>=H5H_SIZEOF_FREE(f)) { - /* a bigger free block was found */ - offset = fl->offset; - fl->offset += need_size; - fl->size -= need_size; - found = TRUE; - break; - } else if (fl->size==need_size) { - /* free block of exact size found */ - offset = fl->offset; - fl = H5H_remove_free (heap, fl); - found = TRUE; - break; - } else if (!max_fl || max_fl->offset < fl->offset) { - /* use worst fit */ - max_fl = fl; - } - } - - - /* - * If no free chunk was large enough, then allocate more space and - * add it to the free list. If the heap ends with a free chunk, we - * can extend that free chunk. Otherwise we'll have to make another - * free chunk. If the heap must expand, we double its size. - */ - if (!found) { - - need_more = MAX3 (need_size, heap->mem_alloc, H5H_SIZEOF_FREE(f)); - - if (max_fl && max_fl->offset+max_fl->size==heap->mem_alloc) { - /* - * Increase the size of the maximum free block. - */ - offset = max_fl->offset; - max_fl->offset += need_size; - max_fl->size += need_more - need_size; - - if (max_fl->size < H5H_SIZEOF_FREE(f)) { + FUNC_ENTER(H5H_insert, FAIL); + + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(buf_size > 0); + assert(buf); + + if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, + "unable to load heap"); + } + heap->dirty += 1; + + /* + * In order to keep the free list descriptors aligned on word boundaries, + * whatever that might mean, we round the size up to the next multiple of + * a word. + */ + need_size = H5H_ALIGN(buf_size); + + /* + * Look for a free slot large enough for this object and which would + * leave zero or at least H5G_SIZEOF_FREE bytes left over. + */ + for (fl = heap->freelist, found = FALSE; fl; fl = fl->next) { + if (fl->size > need_size && fl->size - need_size >= H5H_SIZEOF_FREE(f)) { + /* a bigger free block was found */ + offset = fl->offset; + fl->offset += need_size; + fl->size -= need_size; + found = TRUE; + break; + } else if (fl->size == need_size) { + /* free block of exact size found */ + offset = fl->offset; + fl = H5H_remove_free(heap, fl); + found = TRUE; + break; + } else if (!max_fl || max_fl->offset < fl->offset) { + /* use worst fit */ + max_fl = fl; + } + } + + /* + * If no free chunk was large enough, then allocate more space and + * add it to the free list. If the heap ends with a free chunk, we + * can extend that free chunk. Otherwise we'll have to make another + * free chunk. If the heap must expand, we double its size. + */ + if (!found) { + + need_more = MAX3(need_size, heap->mem_alloc, H5H_SIZEOF_FREE(f)); + + if (max_fl && max_fl->offset + max_fl->size == heap->mem_alloc) { + /* + * Increase the size of the maximum free block. + */ + offset = max_fl->offset; + max_fl->offset += need_size; + max_fl->size += need_more - need_size; + + if (max_fl->size < H5H_SIZEOF_FREE(f)) { #ifndef NDEBUG - if (max_fl->size) { - fprintf (stderr, "H5H_insert: lost %lu bytes at line %d\n", - (unsigned long)(max_fl->size), __LINE__); - if (0==nmessages++) { - fprintf (stderr, "Messages from H5H_insert() will go away " - "when assertions are turned off.\n"); - } - } + if (max_fl->size) { + fprintf(stderr, "H5H_insert: lost %lu bytes at line %d\n", + (unsigned long) (max_fl->size), __LINE__); + if (0 == nmessages++) { + fprintf(stderr, "Messages from H5H_insert() will go away " + "when assertions are turned off.\n"); + } + } #endif - max_fl = H5H_remove_free (heap, max_fl); - } - - } else { - /* - * Create a new free list element large enough that we can - * take some space out of it right away. - */ - offset = heap->mem_alloc; - if (need_more-need_size >= H5H_SIZEOF_FREE(f)) { - fl = H5MM_xmalloc (sizeof(H5H_free_t)); - fl->offset = heap->mem_alloc + need_size; - fl->size = need_more - need_size; - fl->prev = NULL; - fl->next = heap->freelist; - if (heap->freelist) heap->freelist->prev = fl; - heap->freelist = fl; + max_fl = H5H_remove_free(heap, max_fl); + } + } else { + /* + * Create a new free list element large enough that we can + * take some space out of it right away. + */ + offset = heap->mem_alloc; + if (need_more - need_size >= H5H_SIZEOF_FREE(f)) { + fl = H5MM_xmalloc(sizeof(H5H_free_t)); + fl->offset = heap->mem_alloc + need_size; + fl->size = need_more - need_size; + fl->prev = NULL; + fl->next = heap->freelist; + if (heap->freelist) + heap->freelist->prev = fl; + heap->freelist = fl; #ifndef NDEBUG - } else if (need_more>need_size) { - fprintf (stderr, "H5H_insert: lost %lu bytes at line %d\n", - (unsigned long)(need_more-need_size), __LINE__); - if (0==nmessages++) { - fprintf (stderr, "Messages from H5H_insert() will go away " - "when assertions are turned off.\n"); - } + } else if (need_more > need_size) { + fprintf(stderr, "H5H_insert: lost %lu bytes at line %d\n", + (unsigned long) (need_more - need_size), __LINE__); + if (0 == nmessages++) { + fprintf(stderr, "Messages from H5H_insert() will go away " + "when assertions are turned off.\n"); + } #endif - } - } + } + } #ifndef NDEBUG - fprintf (stderr, "H5H_insert: resize mem buf from %lu to %lu bytes\n", - (unsigned long)(heap->mem_alloc), - (unsigned long)(heap->mem_alloc + need_more)); - if (0==nmessages++) { - fprintf (stderr, "Messages from H5H_insert() will go away " - "when assertions are turned off.\n"); - } + fprintf(stderr, "H5H_insert: resize mem buf from %lu to %lu bytes\n", + (unsigned long) (heap->mem_alloc), + (unsigned long) (heap->mem_alloc + need_more)); + if (0 == nmessages++) { + fprintf(stderr, "Messages from H5H_insert() will go away " + "when assertions are turned off.\n"); + } #endif - old_size = heap->mem_alloc; - heap->mem_alloc += need_more; - heap->chunk = H5MM_xrealloc (heap->chunk, - H5H_SIZEOF_HDR(f)+heap->mem_alloc); - - /* clear new section so junk doesn't appear in the file */ - HDmemset (heap->chunk+H5H_SIZEOF_HDR(f)+old_size, 0, need_more); - } - - /* - * Copy the data into the heap - */ - HDmemcpy (heap->chunk + H5H_SIZEOF_HDR(f) + offset, buf, buf_size); - FUNC_LEAVE (offset); + old_size = heap->mem_alloc; + heap->mem_alloc += need_more; + heap->chunk = H5MM_xrealloc(heap->chunk, + H5H_SIZEOF_HDR(f) + heap->mem_alloc); + + /* clear new section so junk doesn't appear in the file */ + HDmemset(heap->chunk + H5H_SIZEOF_HDR(f) + old_size, 0, need_more); + } + /* + * Copy the data into the heap + */ + HDmemcpy(heap->chunk + H5H_SIZEOF_HDR(f) + offset, buf, buf_size); + FUNC_LEAVE(offset); } - /*------------------------------------------------------------------------- - * Function: H5H_write + * Function: H5H_write * - * Purpose: Writes (overwrites) the object (or part of object) stored - * in BUF to the heap at file address ADDR in file F. The - * writing begins at byte offset OFFSET from the beginning of - * the heap and continues for SIZE bytes. + * Purpose: Writes (overwrites) the object (or part of object) stored + * in BUF to the heap at file address ADDR in file F. The + * writing begins at byte offset OFFSET from the beginning of + * the heap and continues for SIZE bytes. * - * Do not partially write an object to create it; the first - * write for an object must be for the entire object. + * Do not partially write an object to create it; the first + * write for an object must be for the entire object. * - * If the heap address ADDR is the null pointer then - * the address comes from the H5F_t global heap field. + * If the heap address ADDR is the null pointer then + * the address comes from the H5F_t global heap field. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 16 1997 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5H_write (H5F_t *f, const haddr_t *addr, size_t offset, size_t size, - const void *buf) +H5H_write(H5F_t *f, const haddr_t *addr, size_t offset, size_t size, + const void *buf) { - H5H_t *heap = NULL; + H5H_t *heap = NULL; - FUNC_ENTER (H5H_write, FAIL); + FUNC_ENTER(H5H_write, FAIL); - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (offset>=0); - assert (buf); + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(offset >= 0); + assert(buf); - if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, - "unable to load heap"); - } - assert (offset<heap->mem_alloc); - assert (offset+size<=heap->mem_alloc); + if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, + "unable to load heap"); + } + assert(offset < heap->mem_alloc); + assert(offset + size <= heap->mem_alloc); - heap->dirty += 1; - HDmemcpy (heap->chunk+H5H_SIZEOF_HDR(f)+offset, buf, size); + heap->dirty += 1; + HDmemcpy(heap->chunk + H5H_SIZEOF_HDR(f) + offset, buf, size); - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * Function: H5H_remove + * Function: H5H_remove * - * Purpose: Removes an object or part of an object from the heap at - * address ADDR of file F. The object (or part) to remove - * begins at byte OFFSET from the beginning of the heap and - * continues for SIZE bytes. + * Purpose: Removes an object or part of an object from the heap at + * address ADDR of file F. The object (or part) to remove + * begins at byte OFFSET from the beginning of the heap and + * continues for SIZE bytes. * - * Once part of an object is removed, one must not attempt - * to access that part. Removing the beginning of an object - * results in the object OFFSET increasing by the amount - * truncated. Removing the end of an object results in - * object truncation. Removing the middle of an object results - * in two separate objects, one at the original offset and - * one at the first offset past the removed portion. + * Once part of an object is removed, one must not attempt + * to access that part. Removing the beginning of an object + * results in the object OFFSET increasing by the amount + * truncated. Removing the end of an object results in + * object truncation. Removing the middle of an object results + * in two separate objects, one at the original offset and + * one at the first offset past the removed portion. * - * If the heap address ADDR is the null pointer then - * the address comes from the H5F_t global heap field. + * If the heap address ADDR is the null pointer then + * the address comes from the H5F_t global heap field. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 16 1997 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5H_remove (H5F_t *f, const haddr_t *addr, size_t offset, size_t size) +H5H_remove(H5F_t *f, const haddr_t *addr, size_t offset, size_t size) { - H5H_t *heap = NULL; - H5H_free_t *fl = heap->freelist, *fl2 = NULL; + H5H_t *heap = NULL; + H5H_free_t *fl = heap->freelist, *fl2 = NULL; #ifndef NDEBUG - static int nmessages = 0; + static int nmessages = 0; #endif - FUNC_ENTER (H5H_remove, FAIL); - - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (offset>=0); - assert (size>0); - - if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, - "unable to load heap"); - } - assert (offset<heap->mem_alloc); - assert (offset+size<=heap->mem_alloc); - - heap->dirty += 1; - - /* - * Check if this chunk can be prepended or appended to an already - * free chunk. It might also fall between two chunks in such a way - * that all three chunks can be combined into one. - */ - while (fl) { - if (offset + size == fl->offset) { - fl->offset = offset; - fl->size += size; - fl2 = fl->next; - while (fl2) { - if (fl2->offset + fl2->size == fl->offset) { - fl->offset = fl2->offset; - fl->size += fl2->size; - fl2 = H5H_remove_free (heap, fl2); - HRETURN (SUCCEED); - } - } - HRETURN (SUCCEED); - - } else if (fl->offset + fl->size == offset) { - fl->size += size; - fl2 = fl->next; - while (fl2) { - if (fl->offset + fl->size == fl2->offset) { - fl->size += fl2->size; - fl2 = H5H_remove_free (heap, fl2); - HRETURN (SUCCEED); - } - } - HRETURN (SUCCEED); - } - - fl = fl->next; - } - - - /* - * The amount which is being removed must be large enough to - * hold the free list data. If not, the freed chunk is forever - * lost. - */ - if (size < H5H_SIZEOF_FREE(f)) { + FUNC_ENTER(H5H_remove, FAIL); + + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(offset >= 0); + assert(size > 0); + + if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, + "unable to load heap"); + } + assert(offset < heap->mem_alloc); + assert(offset + size <= heap->mem_alloc); + + heap->dirty += 1; + + /* + * Check if this chunk can be prepended or appended to an already + * free chunk. It might also fall between two chunks in such a way + * that all three chunks can be combined into one. + */ + while (fl) { + if (offset + size == fl->offset) { + fl->offset = offset; + fl->size += size; + fl2 = fl->next; + while (fl2) { + if (fl2->offset + fl2->size == fl->offset) { + fl->offset = fl2->offset; + fl->size += fl2->size; + fl2 = H5H_remove_free(heap, fl2); + HRETURN(SUCCEED); + } + } + HRETURN(SUCCEED); + + } else if (fl->offset + fl->size == offset) { + fl->size += size; + fl2 = fl->next; + while (fl2) { + if (fl->offset + fl->size == fl2->offset) { + fl->size += fl2->size; + fl2 = H5H_remove_free(heap, fl2); + HRETURN(SUCCEED); + } + } + HRETURN(SUCCEED); + } + fl = fl->next; + } + + /* + * The amount which is being removed must be large enough to + * hold the free list data. If not, the freed chunk is forever + * lost. + */ + if (size < H5H_SIZEOF_FREE(f)) { #ifndef NDEBUG - fprintf (stderr, "H5H_remove: lost %lu bytes\n", (unsigned long)size); - if (0==nmessages++) { - fprintf (stderr, "Messages from H5H_remove() will go away " - "when assertions are turned off.\n"); - } + fprintf(stderr, "H5H_remove: lost %lu bytes\n", (unsigned long) size); + if (0 == nmessages++) { + fprintf(stderr, "Messages from H5H_remove() will go away " + "when assertions are turned off.\n"); + } #endif - HRETURN (SUCCEED); - } - - /* - * Add an entry to the free list. - */ - fl = H5MM_xmalloc (sizeof(H5H_free_t)); - fl->offset = offset; - fl->size = size; - fl->prev = NULL; - fl->next = heap->freelist; - if (heap->freelist) heap->freelist->prev = fl; - heap->freelist = fl; - - FUNC_LEAVE (SUCCEED); + HRETURN(SUCCEED); + } + /* + * Add an entry to the free list. + */ + fl = H5MM_xmalloc(sizeof(H5H_free_t)); + fl->offset = offset; + fl->size = size; + fl->prev = NULL; + fl->next = heap->freelist; + if (heap->freelist) + heap->freelist->prev = fl; + heap->freelist = fl; + + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * Function: H5H_debug + * Function: H5H_debug * - * Purpose: Prints debugging information about a heap. + * Purpose: Prints debugging information about a heap. * - * If the heap address ADDR is the null pointer then - * the address comes from the H5F_t global heap field. + * If the heap address ADDR is the null pointer then + * the address comes from the H5F_t global heap field. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 1 1997 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5H_debug (H5F_t *f, const haddr_t *addr, FILE *stream, intn indent, - intn fwidth) +H5H_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, + intn fwidth) { - H5H_t *h = NULL; - int i, j, overlap; - uint8 c; - H5H_free_t *freelist=NULL; - uint8 *marker = NULL; - size_t amount_free = 0; - - FUNC_ENTER (H5H_debug, FAIL); - - /* check arguments */ - assert (f); - if (!addr) addr = &(f->shared->smallobj_addr); - assert (H5F_addr_defined (addr)); - assert (stream); - assert (indent>=0); - assert (fwidth>=0); - - if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, - "unable to load heap"); - } - - fprintf (stream, "%*sHeap...\n", indent, ""); - fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth, - "Dirty:", - (int)(h->dirty)); - fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Data bytes allocated on disk:", - (unsigned long)(h->disk_alloc)); - fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Data bytes allocated in core:", - (unsigned long)(h->mem_alloc)); - - - /* - * Traverse the free list and check that all free blocks fall within - * the heap and that no two free blocks point to the same region of - * the heap. - */ - marker = H5MM_xcalloc (h->mem_alloc, 1); - for (freelist=h->freelist; freelist; freelist=freelist->next) { - fprintf (stream, "%*s%-*s %8lu, %8lu\n", indent, "", fwidth, - "Free Block (offset,size):", - (unsigned long)(freelist->offset), - (unsigned long)(freelist->size)); - if (freelist->offset + freelist->size > h->mem_alloc) { - fprintf (stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n"); - } else { - for (i=overlap=0; i<freelist->size; i++) { - if (marker[freelist->offset+i]) overlap++; - marker[freelist->offset+i] = 1; - } - if (overlap) { - fprintf (stream,"***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n"); - } else { - amount_free += freelist->size; - } - } - } - - if (h->mem_alloc) { - fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Percent of heap used:", - (unsigned long)(100 * (h->mem_alloc - amount_free) / - h->mem_alloc)); - } - - /* - * Print the data in a VMS-style octal dump. - */ - fprintf (stream, "%*sData follows (`__' indicates free region)...\n", - indent, ""); - for (i=0; i<h->disk_alloc; i+=16) { - fprintf (stream, "%*s %8d: ", indent, "", i); - for (j=0; j<16; j++) { - if (i+j<h->disk_alloc) { - if (marker[i+j]) { - fprintf (stream, "__ "); - } else { - c = h->chunk[H5H_SIZEOF_HDR(f)+i+j]; - fprintf (stream, "%02x ", c); - } - } else { - fprintf (stream, " "); - } - if (7==j) HDfputc (' ', stream); - } - - for (j=0; j<16; j++) { - if (i+j<h->disk_alloc) { - if (marker[i+j]) { - HDfputc (' ', stream); - } else { - c = h->chunk[H5H_SIZEOF_HDR(f)+i+j]; - if (c>' ' && c<'~') HDfputc (c, stream); - else HDfputc ('.', stream); - } - } - } - - HDfputc ('\n', stream); - } - - H5MM_xfree (marker); - FUNC_LEAVE (SUCCEED); + H5H_t *h = NULL; + int i, j, overlap; + uint8 c; + H5H_free_t *freelist = NULL; + uint8 *marker = NULL; + size_t amount_free = 0; + + FUNC_ENTER(H5H_debug, FAIL); + + /* check arguments */ + assert(f); + if (!addr) + addr = &(f->shared->smallobj_addr); + assert(H5F_addr_defined(addr)); + assert(stream); + assert(indent >= 0); + assert(fwidth >= 0); + + if (NULL == (h = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, + "unable to load heap"); + } + fprintf(stream, "%*sHeap...\n", indent, ""); + fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, + "Dirty:", + (int) (h->dirty)); + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Data bytes allocated on disk:", + (unsigned long) (h->disk_alloc)); + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Data bytes allocated in core:", + (unsigned long) (h->mem_alloc)); + + /* + * Traverse the free list and check that all free blocks fall within + * the heap and that no two free blocks point to the same region of + * the heap. + */ + marker = H5MM_xcalloc(h->mem_alloc, 1); + for (freelist = h->freelist; freelist; freelist = freelist->next) { + fprintf(stream, "%*s%-*s %8lu, %8lu\n", indent, "", fwidth, + "Free Block (offset,size):", + (unsigned long) (freelist->offset), + (unsigned long) (freelist->size)); + if (freelist->offset + freelist->size > h->mem_alloc) { + fprintf(stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n"); + } else { + for (i = overlap = 0; i < freelist->size; i++) { + if (marker[freelist->offset + i]) + overlap++; + marker[freelist->offset + i] = 1; + } + if (overlap) { + fprintf(stream, "***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n"); + } else { + amount_free += freelist->size; + } + } + } + + if (h->mem_alloc) { + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Percent of heap used:", + (unsigned long) (100 * (h->mem_alloc - amount_free) / + h->mem_alloc)); + } + /* + * Print the data in a VMS-style octal dump. + */ + fprintf(stream, "%*sData follows (`__' indicates free region)...\n", + indent, ""); + for (i = 0; i < h->disk_alloc; i += 16) { + fprintf(stream, "%*s %8d: ", indent, "", i); + for (j = 0; j < 16; j++) { + if (i + j < h->disk_alloc) { + if (marker[i + j]) { + fprintf(stream, "__ "); + } else { + c = h->chunk[H5H_SIZEOF_HDR(f) + i + j]; + fprintf(stream, "%02x ", c); + } + } else { + fprintf(stream, " "); + } + if (7 == j) + HDfputc(' ', stream); + } + + for (j = 0; j < 16; j++) { + if (i + j < h->disk_alloc) { + if (marker[i + j]) { + HDfputc(' ', stream); + } else { + c = h->chunk[H5H_SIZEOF_HDR(f) + i + j]; + if (c > ' ' && c < '~') + HDfputc(c, stream); + else + HDfputc('.', stream); + } + } + } + + HDfputc('\n', stream); + } + + H5MM_xfree(marker); + FUNC_LEAVE(SUCCEED); } |