summaryrefslogtreecommitdiffstats
path: root/src/H5HL.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HL.c')
-rw-r--r--src/H5HL.c429
1 files changed, 218 insertions, 211 deletions
diff --git a/src/H5HL.c b/src/H5HL.c
index 9de9f5b..e86be3d 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -153,8 +153,7 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/)
if (NULL==(heap = H5FL_CALLOC(H5HL_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
heap->addr = *addr_p + (hsize_t)sizeof_hdr;
- heap->disk_alloc = size_hint;
- heap->mem_alloc = size_hint;
+ heap->heap_alloc = size_hint;
if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + size_hint))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
@@ -254,25 +253,24 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* heap data size */
- H5F_DECODE_LENGTH(f, p, heap->disk_alloc);
- heap->mem_alloc = heap->disk_alloc;
+ H5F_DECODE_LENGTH(f, p, heap->heap_alloc);
/* free list head */
H5F_DECODE_LENGTH(f, p, free_block);
- if (free_block != H5HL_FREE_NULL && free_block >= heap->disk_alloc)
+ if (free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
/* data */
H5F_addr_decode(f, &p, &(heap->addr));
- if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->mem_alloc))))
+ if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->heap_alloc))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (heap->disk_alloc &&
- H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
+ if (heap->heap_alloc &&
+ H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data");
/* Build free list */
while (H5HL_FREE_NULL != free_block) {
- if (free_block >= heap->disk_alloc)
+ if (free_block >= heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@@ -287,7 +285,7 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
H5F_DECODE_LENGTH(f, p, free_block);
H5F_DECODE_LENGTH(f, p, fl->size);
- if (fl->offset + fl->size > heap->disk_alloc)
+ if (fl->offset + fl->size > heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
}
@@ -324,7 +322,7 @@ done:
*
* It used to be called during cache eviction, where it
* attempted to size the disk space allocation for the
- * actuall size of the heap. However, this causes problems
+ * actual size of the heap. However, this causes problems
* in the parallel case, as the reuslting disk allocations
* may not be synchronized.
*
@@ -338,15 +336,15 @@ done:
static herr_t
H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
{
- herr_t ret_value = SUCCEED;
- size_t sizeof_hdr;
+ size_t new_heap_size = heap->heap_alloc; /* New size of heap */
+ size_t sizeof_hdr;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5HL_minimize_heap_space, FAIL)
/* check args */
HDassert( f );
HDassert( heap );
- HDassert( heap->disk_alloc == heap->mem_alloc );
sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */
@@ -355,14 +353,14 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
* eliminating free blocks at the tail of the buffer before flushing the
* buffer out.
*/
- if (heap->freelist) {
+ if(heap->freelist) {
H5HL_free_t *tmp_fl;
H5HL_free_t *last_fl = NULL;
/* Search for a free block at the end of the buffer */
for (tmp_fl = heap->freelist; tmp_fl; tmp_fl = tmp_fl->next)
/* Check if the end of this free block is at the end of the buffer */
- if (tmp_fl->offset + tmp_fl->size == heap->mem_alloc) {
+ if (tmp_fl->offset + tmp_fl->size == heap->heap_alloc) {
last_fl = tmp_fl;
break;
}
@@ -371,98 +369,90 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
* Found free block at the end of the buffer, decide what to do
* about it
*/
- if (last_fl) {
- size_t new_mem_size = heap->mem_alloc; /* New size of memory buffer */
-
+ if(last_fl) {
/*
* If the last free block's size is more than half the memory
* buffer size (and the memory buffer is larger than the
* minimum size), reduce or eliminate it.
*/
- if (last_fl->size >= (heap->mem_alloc / 2) && heap->mem_alloc > H5HL_MIN_HEAP) {
+ if(last_fl->size >= (heap->heap_alloc / 2) && heap->heap_alloc > H5HL_MIN_HEAP) {
/*
* Reduce size of buffer until it's too small or would
* eliminate the free block
*/
- while (new_mem_size > H5HL_MIN_HEAP &&
- new_mem_size >= (last_fl->offset + H5HL_SIZEOF_FREE(f)))
- new_mem_size /= 2;
+ while(new_heap_size > H5HL_MIN_HEAP &&
+ new_heap_size >= (last_fl->offset + H5HL_SIZEOF_FREE(f)))
+ new_heap_size /= 2;
/*
* Check if reducing the memory buffer size would
- * eliminate the free list
+ * eliminate the free block
*/
- if (new_mem_size < (last_fl->offset + H5HL_SIZEOF_FREE(f))) {
+ if(new_heap_size < (last_fl->offset + H5HL_SIZEOF_FREE(f))) {
/* Check if this is the only block on the free list */
- if (last_fl->prev == NULL && last_fl->next == NULL) {
+ if(last_fl->prev == NULL && last_fl->next == NULL) {
/* Double the new memory size */
- new_mem_size *= 2;
+ new_heap_size *= 2;
/* Truncate the free block */
- last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset);
- new_mem_size = last_fl->offset + last_fl->size;
+ last_fl->size = H5HL_ALIGN(new_heap_size - last_fl->offset);
+ new_heap_size = last_fl->offset + last_fl->size;
assert(last_fl->size >= H5HL_SIZEOF_FREE(f));
} else {
/*
* Set the size of the memory buffer to the start
* of the free list
*/
- new_mem_size = last_fl->offset;
+ new_heap_size = last_fl->offset;
/* Eliminate the free block from the list */
last_fl = H5HL_remove_free(heap, last_fl);
- }
+ } /* end else */
} else {
/* Truncate the free block */
- last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset);
- new_mem_size = last_fl->offset + last_fl->size;
+ last_fl->size = H5HL_ALIGN(new_heap_size - last_fl->offset);
+ new_heap_size = last_fl->offset + last_fl->size;
assert(last_fl->size >= H5HL_SIZEOF_FREE(f));
assert(last_fl->size == H5HL_ALIGN(last_fl->size));
- }
-
- /* Resize the memory buffer and reserved space in file */
- if (new_mem_size != heap->mem_alloc) {
-
- heap->mem_alloc = new_mem_size;
- heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_mem_size));
-
- if (!heap->chunk)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- }
- }
- }
- }
+ } /* end else */
+ } /* end if */
+ } /* end if */
+ } /* end if */
/*
* If the heap grew smaller than disk storage then move the
* data segment of the heap to another contiguous block of disk
* storage.
*/
- if (heap->mem_alloc != heap->disk_alloc) {
- haddr_t old_addr = heap->addr, new_addr;
+ if(new_heap_size != heap->heap_alloc) {
+ haddr_t old_addr = heap->addr,
+ new_addr;
+
+ HDassert(new_heap_size < heap->heap_alloc);
- HDassert( heap->mem_alloc < heap->disk_alloc );
+ /* Resize the memory buffer */
+ heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_heap_size));
+ if(!heap->chunk)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Release old space on disk */
- H5_CHECK_OVERFLOW(heap->disk_alloc, size_t, hsize_t);
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->disk_alloc);
+ /* (Should be safe to free old heap space first, since it's shrinking -QAK) */
+ H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
+ H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->heap_alloc);
H5E_clear_stack(NULL); /* don't really care if the free failed */
/* Allocate new space on disk */
- H5_CHECK_OVERFLOW(heap->mem_alloc, size_t, hsize_t);
-
- if (HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)heap->mem_alloc)))
+ H5_CHECK_OVERFLOW(new_heap_size, size_t, hsize_t);
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space for heap")
+ /* Update heap info*/
heap->addr = new_addr;
-
- /* Set new size of block on disk */
- heap->disk_alloc = heap->mem_alloc;
- }
+ heap->heap_alloc = new_heap_size;
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5HL_minimize_heap_space() */
@@ -506,7 +496,7 @@ H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf)
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
- H5F_ENCODE_LENGTH(f, p, heap->mem_alloc);
+ H5F_ENCODE_LENGTH(f, p, heap->heap_alloc);
H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL);
H5F_addr_encode(f, &p, heap->addr);
@@ -573,7 +563,6 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
HDassert( f );
HDassert( H5F_addr_defined(addr) );
HDassert( heap );
- HDassert( heap->disk_alloc == heap->mem_alloc );
if (heap->cache_info.is_dirty) {
haddr_t hdr_end_addr;
@@ -588,14 +577,14 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
if (H5F_addr_eq(heap->addr, hdr_end_addr)) {
/* The header and data are contiguous */
- if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->disk_alloc),
+ if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->heap_alloc),
dxpl_id, heap->chunk) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file")
} else {
if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, heap->chunk) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file")
- if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc,
+ if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc,
dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file")
}
@@ -717,7 +706,7 @@ H5HL_compute_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr)
HDassert(heap);
HDassert(size_ptr);
- *size_ptr = H5HL_SIZEOF_HDR(f) + heap->disk_alloc;
+ *size_ptr = H5HL_SIZEOF_HDR(f) + heap->heap_alloc;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HL_compute_size() */
@@ -766,8 +755,8 @@ H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, voi
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
- assert(offset < heap->mem_alloc);
- assert(offset + size <= heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
+ assert(offset + size <= heap->heap_alloc);
if (!buf && NULL==(buf = H5MM_malloc(size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@@ -864,7 +853,7 @@ H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_offset_into)
assert(f);
assert(heap);
- assert(offset < heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
FUNC_LEAVE_NOAPI(heap->chunk + H5HL_SIZEOF_HDR(f) + offset)
}
@@ -976,12 +965,9 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
{
H5HL_t *heap = NULL;
unsigned heap_flags = H5AC__NO_FLAGS_SET;
- H5HL_free_t *fl = NULL, *max_fl = NULL;
- htri_t tri_result;
- herr_t result;
+ H5HL_free_t *fl = NULL, *last_fl = NULL;
size_t offset = 0;
- size_t need_size, old_size, need_more;
- size_t new_disk_alloc;
+ size_t need_size;
hbool_t found;
size_t sizeof_hdr; /* Cache H5HL header size for file */
size_t ret_value; /* Return value */
@@ -989,10 +975,10 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
FUNC_ENTER_NOAPI(H5HL_insert, (size_t)(-1));
/* check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(buf_size > 0);
- assert(buf);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(buf_size > 0);
+ HDassert(buf);
if (0==(f->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, (size_t)(-1), "no write intent on file");
@@ -1016,28 +1002,28 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
* 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 >= H5HL_SIZEOF_FREE(f)) {
- /* a bigger free block was found */
+ for(fl = heap->freelist, found = FALSE; fl; fl = fl->next) {
+ if(fl->size > need_size &&
+ fl->size - need_size >= H5HL_SIZEOF_FREE(f)) {
+ /* a big enough free block was found */
offset = fl->offset;
fl->offset += need_size;
fl->size -= need_size;
- assert (fl->offset==H5HL_ALIGN (fl->offset));
- assert (fl->size==H5HL_ALIGN (fl->size));
+ HDassert(fl->offset == H5HL_ALIGN(fl->offset));
+ HDassert(fl->size == H5HL_ALIGN(fl->size));
found = TRUE;
break;
- } else if (fl->size == need_size) {
+ } else if(fl->size == need_size) {
/* free block of exact size found */
offset = fl->offset;
fl = H5HL_remove_free(heap, fl);
found = TRUE;
break;
- } else if (!max_fl || max_fl->offset < fl->offset) {
- /* use worst fit */
- max_fl = fl;
+ } else if(!last_fl || last_fl->offset < fl->offset) {
+ /* track free space that's closest to end of heap */
+ last_fl = fl;
}
- }
+ } /* end for */
/*
* If no free chunk was large enough, then allocate more space and
@@ -1045,34 +1031,41 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
* 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==FALSE) {
- need_more = MAX3(need_size, heap->mem_alloc, H5HL_SIZEOF_FREE(f));
-
- new_disk_alloc = heap->disk_alloc + need_more;
- HDassert( heap->disk_alloc < new_disk_alloc );
- H5_CHECK_OVERFLOW(heap->disk_alloc, size_t, hsize_t);
- H5_CHECK_OVERFLOW(new_disk_alloc, size_t, hsize_t);
-
- /* extend the current heap if we can... */
- tri_result = H5MF_can_extend(f, H5FD_MEM_LHEAP, heap->addr,
- (hsize_t)(heap->disk_alloc),
- (hsize_t)need_more);
- if ( tri_result == TRUE ) {
-
- result = H5MF_extend(f, H5FD_MEM_LHEAP, heap->addr,
- (hsize_t)(heap->disk_alloc),
- (hsize_t)need_more);
- if ( result < 0 ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), \
- "can't extend heap on disk");
- }
+ if(found == FALSE) {
+ size_t need_more; /* How much more space we need */
+ size_t new_heap_alloc; /* Final size of space allocated for heap */
+ htri_t can_extend; /* Whether the local heap's data segment on disk can be extended */
+
+ /* At least double the heap's size, making certain there's enough room
+ * for the new object */
+ need_more = MAX(need_size, heap->heap_alloc);
+
+ /* If there is no last free block or it's not at the end of the heap,
+ * and the amount of space to allocate is not big enough to include at
+ * least the new object and a free-list info, trim down the amount of
+ * space requested to just the amount of space needed. (Generally
+ * speaking, this only occurs when the heap is small -QAK)
+ */
+ if(!(last_fl && last_fl->offset + last_fl->size == heap->heap_alloc)
+ && (need_more < (need_size + H5HL_SIZEOF_FREE(f))))
+ need_more = need_size;
- heap->disk_alloc = new_disk_alloc;
+ new_heap_alloc = heap->heap_alloc + need_more;
+ HDassert(heap->heap_alloc < new_heap_alloc);
+ H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
+ H5_CHECK_OVERFLOW(new_heap_alloc, size_t, hsize_t);
- } else { /* ...if we can't, allocate a new chunk & release the old */
+ /* Check if current heap is extendible */
+ can_extend = H5MF_can_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more);
+ if(can_extend < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "unable to check whether heap can be extended")
- haddr_t old_addr = heap->addr;
+ /* extend the current heap if we can... */
+ if(can_extend == TRUE) {
+ if(H5MF_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "can't extend heap on disk")
+ } /* end if */
+ else { /* ...if we can't, allocate a new chunk & release the old */
haddr_t new_addr;
/* The new allocation may fail -- to avoid the possiblity of
@@ -1081,54 +1074,50 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
*/
/* allocate new disk space for the heap */
- if ( (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id,
- (hsize_t)new_disk_alloc)) == HADDR_UNDEF ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), \
- "unable to allocate file space for heap")
- }
+ if((new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_alloc)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "unable to allocate file space for heap")
/* Release old space on disk */
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr,
- (hsize_t)heap->disk_alloc);
+ H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc);
H5E_clear_stack(NULL); /* don't really care if the free failed */
heap->addr = new_addr;
- heap->disk_alloc = new_disk_alloc;
- }
+ } /* end else */
- if (max_fl && max_fl->offset + max_fl->size == heap->mem_alloc) {
+ /* If the last free list in the heap is at the end of the heap, extend it */
+ if(last_fl && last_fl->offset + last_fl->size == heap->heap_alloc) {
/*
- * Increase the size of the maximum free block.
+ * Increase the size of the last free block.
*/
- offset = max_fl->offset;
- max_fl->offset += need_size;
- max_fl->size += need_more - need_size;
- assert (max_fl->offset==H5HL_ALIGN (max_fl->offset));
- assert (max_fl->size==H5HL_ALIGN (max_fl->size));
+ offset = last_fl->offset;
+ last_fl->offset += need_size;
+ last_fl->size += need_more - need_size;
+ HDassert(last_fl->offset == H5HL_ALIGN(last_fl->offset));
+ HDassert(last_fl->size == H5HL_ALIGN(last_fl->size));
- if (max_fl->size < H5HL_SIZEOF_FREE(f)) {
+ if (last_fl->size < H5HL_SIZEOF_FREE(f)) {
#ifdef H5HL_DEBUG
- if (H5DEBUG(HL) && max_fl->size) {
+ if (H5DEBUG(HL) && last_fl->size) {
fprintf(H5DEBUG(HL), "H5HL: lost %lu bytes at line %d\n",
- (unsigned long)(max_fl->size), __LINE__);
+ (unsigned long)(last_fl->size), __LINE__);
}
#endif
- max_fl = H5HL_remove_free(heap, max_fl);
+ last_fl = H5HL_remove_free(heap, last_fl);
}
- } else {
+ } /* end if */
+ 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 >= H5HL_SIZEOF_FREE(f)) {
- if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
- fl->offset = heap->mem_alloc + need_size;
+ offset = heap->heap_alloc;
+ if(need_more - need_size >= H5HL_SIZEOF_FREE(f)) {
+ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed")
+ fl->offset = heap->heap_alloc + need_size;
fl->size = need_more - need_size;
- assert (fl->offset==H5HL_ALIGN (fl->offset));
- assert (fl->size==H5HL_ALIGN (fl->size));
+ HDassert(fl->offset == H5HL_ALIGN(fl->offset));
+ HDassert(fl->size == H5HL_ALIGN(fl->size));
fl->prev = NULL;
fl->next = heap->freelist;
if (heap->freelist) heap->freelist->prev = fl;
@@ -1140,40 +1129,39 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
(unsigned long)(need_more - need_size), __LINE__);
#endif
}
- }
+ } /* end else */
#ifdef H5HL_DEBUG
if (H5DEBUG(HL)) {
fprintf(H5DEBUG(HL),
"H5HL: resize mem buf from %lu to %lu bytes\n",
- (unsigned long)(heap->mem_alloc),
- (unsigned long)(heap->mem_alloc + need_more));
+ (unsigned long)(heap->heap_alloc),
+ (unsigned long)(heap->heap_alloc + need_more));
}
#endif
- old_size = heap->mem_alloc;
- heap->mem_alloc += need_more;
- heap->chunk = H5FL_BLK_REALLOC(heap_chunk,heap->chunk,
- (sizeof_hdr + heap->mem_alloc));
- if (NULL==heap->chunk)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
-
- /* clear new section so junk doesn't appear in the file */
- HDmemset(heap->chunk + sizeof_hdr + old_size, 0, need_more);
- }
+ heap->heap_alloc = new_heap_alloc;
+ heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + heap->heap_alloc));
+ if(NULL == heap->chunk)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed")
+
+ /* Clear new section so junk doesn't appear in the file */
+ /* (Avoid clearing section which will be overwritten with newly inserted data) */
+ HDmemset(heap->chunk + sizeof_hdr + offset + buf_size, 0, (new_heap_alloc - (offset + buf_size)));
+ } /* end if */
+
/*
* Copy the data into the heap
*/
HDmemcpy(heap->chunk + sizeof_hdr + offset, buf, buf_size);
/* Set return value */
- ret_value=offset;
+ ret_value = offset;
done:
- if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header");
-
- FUNC_LEAVE_NOAPI(ret_value);
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED)
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header")
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HL_insert() */
#ifdef NOT_YET
@@ -1227,8 +1215,8 @@ H5HL_write(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, co
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap");
- assert(offset < heap->mem_alloc);
- assert(offset + size <= heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
+ assert(offset + size <= heap->heap_alloc);
heap_flags |= H5AC__DIRTIED_FLAG;
HDmemcpy(heap->chunk + H5HL_SIZEOF_HDR(f) + offset, buf, size);
@@ -1305,9 +1293,8 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap");
- HDassert( offset < heap->mem_alloc );
- HDassert( offset + size <= heap->mem_alloc );
- HDassert( heap->disk_alloc == heap->mem_alloc );
+ HDassert( offset < heap->heap_alloc );
+ HDassert( offset + size <= heap->heap_alloc );
fl = heap->freelist;
heap_flags |= H5AC__DIRTIED_FLAG;
@@ -1331,28 +1318,19 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
assert (fl->offset==H5HL_ALIGN (fl->offset));
assert (fl->size==H5HL_ALIGN (fl->size));
fl2 = H5HL_remove_free(heap, fl2);
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) !=
- SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
fl2 = fl2->next;
}
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0 )
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
@@ -1365,28 +1343,19 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
fl->size += fl2->size;
assert (fl->size==H5HL_ALIGN (fl->size));
fl2 = H5HL_remove_free(heap, fl2);
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) !=
- SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
fl2 = fl2->next;
}
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
@@ -1407,6 +1376,7 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
#endif
HGOTO_DONE(SUCCEED);
}
+
/*
* Add an entry to the free list.
*/
@@ -1422,14 +1392,10 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
heap->freelist->prev = fl;
heap->freelist = fl;
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
done:
@@ -1488,8 +1454,8 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
assert(!H5F_addr_overflow(addr,sizeof_hdr));
if(H5F_addr_eq(heap->addr,addr+sizeof_hdr)) {
/* Free the contiguous local heap in one call */
- H5_CHECK_OVERFLOW(sizeof_hdr+heap->disk_alloc,size_t,hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)(sizeof_hdr+heap->disk_alloc))<0)
+ H5_CHECK_OVERFLOW(sizeof_hdr+heap->heap_alloc,size_t,hsize_t);
+ if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)(sizeof_hdr+heap->heap_alloc))<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free contiguous local heap");
} /* end if */
else {
@@ -1499,8 +1465,8 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap header");
/* Free the local heap's data */
- H5_CHECK_OVERFLOW(heap->disk_alloc,size_t,hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->disk_alloc)<0)
+ H5_CHECK_OVERFLOW(heap->heap_alloc,size_t,hsize_t);
+ if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap data");
} /* end else */
@@ -1518,3 +1484,44 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HL_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_get_size
+ *
+ * Purpose: Retrieves the current size of a heap
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Nov 7 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size)
+{
+ H5HL_t *heap = NULL; /* Heap to query */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5HL_get_size, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(size);
+
+ /* Get heap pointer */
+ if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+
+ /* Set the size to return */
+ *size = heap->heap_alloc;
+
+done:
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release local heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_get_size() */
+