summaryrefslogtreecommitdiffstats
path: root/src/H5HG.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HG.c')
-rw-r--r--src/H5HG.c150
1 files changed, 97 insertions, 53 deletions
diff --git a/src/H5HG.c b/src/H5HG.c
index e7b21dd..3082618 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -99,7 +99,7 @@ static haddr_t H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size);
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5HG_t struct */
+/* Declare a free list to manage the H5HG_heap_t struct */
H5FL_DEFINE(H5HG_heap_t);
/* Declare a free list to manage sequences of H5HG_obj_t's */
@@ -253,6 +253,45 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HG_protect
+ *
+ * Purpose: Convenience wrapper around H5AC_protect on an indirect block
+ *
+ * Return: Pointer to indirect block on success, NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 5, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+H5HG_heap_t *
+H5HG_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_t rw)
+{
+ H5HG_heap_t *heap; /* Global heap */
+ H5HG_heap_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HG_protect)
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Lock the heap into memory */
+ if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, f, rw)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect global heap")
+
+ /* Set the heap's address */
+ heap->addr = addr;
+
+ /* Set the return value */
+ ret_value = heap;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HG_protect() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HG_alloc
*
* Purpose: Given a heap with enough free space, this function will split
@@ -271,36 +310,36 @@ done:
*-------------------------------------------------------------------------
*/
static size_t
-H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
+H5HG_alloc(H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned *heap_flags_ptr)
{
size_t idx;
- uint8_t *p = NULL;
+ uint8_t *p;
size_t need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size);
- size_t ret_value; /* Return value */
+ size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HG_alloc);
/* Check args */
- assert (heap);
- assert (heap->obj[0].size>=need);
- assert (heap_flags_ptr);
+ HDassert(heap);
+ HDassert(heap->obj[0].size>=need);
+ HDassert(heap_flags_ptr);
/*
* Find an ID for the new object. ID zero is reserved for the free space
* object.
*/
- if(heap->nused<=H5HG_MAXIDX)
- idx=heap->nused++;
+ if(heap->nused <= H5HG_MAXIDX)
+ idx = heap->nused++;
else {
- for (idx=1; idx<heap->nused; idx++)
- if (NULL==heap->obj[idx].begin)
+ for(idx = 1; idx < heap->nused; idx++)
+ if(NULL == heap->obj[idx].begin)
break;
} /* end else */
HDassert(idx < heap->nused);
/* Check if we need more room to store heap objects */
- if(idx>=heap->nalloc) {
+ if(idx >= heap->nalloc) {
size_t new_alloc; /* New allocation number */
H5HG_obj_t *new_obj; /* New array of object descriptions */
@@ -310,16 +349,16 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
HDassert(idx < new_alloc);
/* Reallocate array of objects */
- if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed")
+ if(NULL == (new_obj = H5FL_SEQ_REALLOC(H5HG_obj_t, heap->obj, new_alloc)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, 0, "memory allocation failed")
/* Clear newly allocated space */
HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0]));
/* Update heap information */
- heap->nalloc=new_alloc;
- heap->obj=new_obj;
- HDassert(heap->nalloc>heap->nused);
+ heap->nalloc = new_alloc;
+ heap->obj = new_obj;
+ HDassert(heap->nalloc > heap->nused);
} /* end if */
/* Initialize the new object */
@@ -333,14 +372,14 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
H5F_ENCODE_LENGTH (f, p, size);
/* Fix the free space object */
- if (need==heap->obj[0].size) {
+ if(need == heap->obj[0].size) {
/*
* All free space has been exhausted from this collection.
*/
heap->obj[0].size = 0;
heap->obj[0].begin = NULL;
-
- } else if (heap->obj[0].size-need >= H5HG_SIZEOF_OBJHDR (f)) {
+ } /* end if */
+ else if(heap->obj[0].size-need >= H5HG_SIZEOF_OBJHDR (f)) {
/*
* Some free space remains and it's larger than a heap object header,
* so write the new free heap object header to the heap.
@@ -353,8 +392,8 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
UINT32ENCODE(p, 0); /*reserved*/
H5F_ENCODE_LENGTH (f, p, heap->obj[0].size);
assert(H5HG_ISALIGNED(heap->obj[0].size));
-
- } else {
+ } /* end else-if */
+ else {
/*
* Some free space remains but it's smaller than a heap object header,
* so we don't write the header.
@@ -368,11 +407,11 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
*heap_flags_ptr |= H5AC__DIRTIED_FLAG;
/* Set the return value */
- ret_value=idx;
+ ret_value = idx;
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5HG_alloc() */
/*-------------------------------------------------------------------------
@@ -403,11 +442,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HG_extend(H5F_t *f, H5HG_heap_t *heap, size_t need, unsigned *heap_flags_ptr)
+H5HG_extend(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t need)
{
+ H5HG_heap_t *heap = NULL; /* Pointer to heap to extend */
+ unsigned heap_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting heap */
size_t old_size; /* Previous size of the heap's chunk */
- uint8_t *new_chunk = NULL; /* Pointer to new chunk information */
- uint8_t *p = NULL; /* Pointer to raw heap info */
+ uint8_t *new_chunk; /* Pointer to new chunk information */
+ uint8_t *p; /* Pointer to raw heap info */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -415,8 +456,11 @@ H5HG_extend(H5F_t *f, H5HG_heap_t *heap, size_t need, unsigned *heap_flags_ptr)
/* Check args */
HDassert(f);
- HDassert(heap);
- HDassert(heap_flags_ptr);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Protect the heap */
+ if(NULL == (heap = H5HG_protect(f, dxpl_id, addr, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap")
/* Re-allocate the heap information in memory */
if(NULL == (new_chunk = H5FL_BLK_REALLOC(gheap_chunk, heap->chunk, (heap->size + need))))
@@ -452,10 +496,17 @@ HDmemset(new_chunk + heap->size, 0, need);
H5F_ENCODE_LENGTH(f, p, heap->obj[0].size);
assert(H5HG_ISALIGNED(heap->obj[0].size));
+ /* Resize the heap in the cache */
+ if(H5AC_resize_entry(heap, heap->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize global heap in cache")
+
/* Mark the heap as dirty */
- *heap_flags_ptr |= H5AC__DIRTIED_FLAG;
+ heap_flags |= H5AC__DIRTIED_FLAG;
done:
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, heap->addr, heap, heap_flags) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to unprotect heap")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HG_extend() */
@@ -521,14 +572,6 @@ H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/
* and protecting and unprotecting all the collections in the global
* heap on a regular basis will skew the replacement policy.
*
- * However, there is a bigger issue -- as best I can tell, we only look
- * for free space in global heap chunks that are in cache. If we can't
- * find any, we allocate a new chunk. This may be a problem in FP mode,
- * as the metadata cache is disabled. Do we allocate a new heap
- * collection for every entry in this case?
- *
- * Note that all this comes from a cursory read of the source. Don't
- * take any of it as gospel.
* JRM - 5/24/04
*/
for(cwfsno = 0; cwfsno < f->shared->ncwfs; cwfsno++)
@@ -557,8 +600,8 @@ H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/
if(extended < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "error trying to extend heap")
else if(extended == TRUE) {
- if(H5HG_extend(f, f->shared->cwfs[cwfsno], new_need, &heap_flags) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to extend global heap collection")
+ if(H5HG_extend(f, dxpl_id, f->shared->cwfs[cwfsno]->addr, new_need) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to extend global heap collection")
addr = f->shared->cwfs[cwfsno]->addr;
found = TRUE;
break;
@@ -590,11 +633,12 @@ H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/
} /* end if */
} /* end else */
HDassert(H5F_addr_defined(addr));
- if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, f, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+ if(NULL == (heap = H5HG_protect(f, dxpl_id, addr, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap")
/* Split the free space to make room for the new object */
- idx = H5HG_alloc(f, heap, size, &heap_flags);
+ if(0 == (idx = H5HG_alloc(f, heap, size, &heap_flags)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate global heap object")
/* Copy data into the heap */
if(size > 0) {
@@ -613,7 +657,7 @@ H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/
done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, heap->addr, heap, heap_flags) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to unprotect heap.")
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to unprotect heap.")
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* H5HG_insert() */
@@ -653,8 +697,8 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/,
HDassert(hobj);
/* Load the heap */
- if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, f, H5AC_READ)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap")
+ if(NULL == (heap = H5HG_protect(f, dxpl_id, hobj->addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect global heap")
HDassert(hobj->idx < heap->nused);
HDassert(heap->obj[hobj->idx].begin);
@@ -692,7 +736,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/,
done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header")
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release object header")
if(NULL == ret_value && NULL == orig_object && object)
H5MM_free(object);
@@ -735,8 +779,8 @@ H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Load the heap */
- if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, f, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+ if(NULL == (heap = H5HG_protect(f, dxpl_id, hobj->addr, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap")
if(adjust != 0) {
HDassert(hobj->idx < heap->nused);
@@ -754,7 +798,7 @@ H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust)
done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, heap_flags) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header")
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5HG_link() */
@@ -798,8 +842,8 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Load the heap */
- if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, f, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+ if(NULL == (heap = H5HG_protect(f, dxpl_id, hobj->addr, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap")
HDassert(hobj->idx < heap->nused);
HDassert(heap->obj[hobj->idx].begin);
@@ -859,7 +903,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj)
done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, flags) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header")
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL);
} /* end H5HG_remove() */