summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5MF.c')
-rw-r--r--src/H5MF.c267
1 files changed, 69 insertions, 198 deletions
diff --git a/src/H5MF.c b/src/H5MF.c
index d00f056..0a7ba1e 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -23,6 +23,7 @@
#include <H5private.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
+#include <H5FDprivate.h>
#include <H5MFprivate.h>
#define PABLO_MASK H5MF_mask
@@ -35,147 +36,53 @@ static intn interface_initialize_g = 0;
/*-------------------------------------------------------------------------
* Function: H5MF_alloc
*
- * Purpose: Allocate at least SIZE bytes of file memory and return
- * the address where that contiguous chunk of file memory
- * exists. The allocation operation should be either H5MF_META or
- * H5MF_RAW depending on the purpose for which the storage is
- * being requested.
+ * Purpose: Allocate SIZE bytes of file memory and return the relative
+ * address where that contiguous chunk of file memory exists.
+ * The TYPE argument describes the purpose for which the storage
+ * is being requested.
*
- * Return: Success: Non-negative. The file address of new chunk is
- * returned through the ADDR argument.
+ * Return: Success: The file address of new chunk.
*
- * Failure: Negative
+ * Failure: HADDR_UNDEF
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jul 11 1997
*
* Modifications:
- *
+ * Robb Matzke, 1999-08-04
+ * Modified to work with the virtual file layer.
*-------------------------------------------------------------------------
*/
-herr_t
-H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/)
+haddr_t
+H5MF_alloc(H5F_t *f, H5FD_mem_t type, hsize_t size)
{
- haddr_t tmp_addr;
- intn i, found, status=-1;
- hsize_t n;
- H5MF_free_t blk;
- hsize_t thresh = f->shared->access_parms->threshold;
- hsize_t align = f->shared->access_parms->alignment;
-
- FUNC_ENTER(H5MF_alloc, FAIL);
+ haddr_t ret_value=HADDR_UNDEF;
+
+ FUNC_ENTER(H5MF_alloc, HADDR_UNDEF);
/* check arguments */
assert(f);
- assert(H5MF_META == op || H5MF_RAW == op);
assert(size > 0);
- assert(addr_p);
/* Fail if we don't have write access */
if (0==(f->intent & H5F_ACC_RDWR)) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "file is read-only");
+ HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "file is read-only");
}
- /*
- * Try to satisfy the request from the free list. We prefer exact matches
- * to partial matches, so if we find an exact match then we break out of
- * the loop immediately, otherwise we keep looking for an exact match.
- */
- for (i=0, found=-1; i<f->shared->fl_nfree; i++) {
- if ((status=H5F_low_alloc(f->shared->lf, op, align, thresh, size,
- f->shared->fl_free+i, addr_p/*out*/))>0) {
- /* Exact match found */
- found = i;
- break;
- } else if (0==status) {
- /* Partial match */
- found = i;
- }
+ /* Allocate space from the virtual file layer */
+ if (HADDR_UNDEF==(ret_value=H5FD_alloc(f->shared->lf, type, size))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "file allocation failed");
}
- if (found>=0 &&
- (status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
- f->shared->fl_free+found, addr_p/*out*/))>0) {
- /*
- * We found an exact match. Remove that block from the free list and
- * use it to satisfy the request.
- */
- --(f->shared->fl_nfree);
- HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1,
- (f->shared->fl_nfree-found) * sizeof(H5MF_free_t));
-
- } else if (found>=0 && status==0) {
- /*
- * We found a free block which is larger than the requested size.
- * Return the unused parts of the free block to the free list.
- */
- blk = f->shared->fl_free[found];
- --f->shared->fl_nfree;
- HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1,
- (f->shared->fl_nfree-found) * sizeof(H5MF_free_t));
- if (H5F_addr_gt (*addr_p, blk.addr)) {
- /* Free the first part of the free block */
- n = *addr_p - blk.addr;
- H5MF_xfree (f, blk.addr, n);
- blk.addr = *addr_p;
- blk.size -= n;
- }
-
- if (blk.size > size) {
- /* Free the second part of the free block */
- blk.addr += size;
- blk.size -= size;
- H5MF_xfree (f, blk.addr, blk.size);
- }
-
- } else {
- /*
- * No suitable free block was found. Allocate space from the end of
- * the file. We don't know about alignment at this point, so we
- * allocate enough space to align the data also.
- */
- if (size>=thresh) {
- blk.size = size + align - 1;
- } else {
- blk.size = size;
- }
- if (H5F_low_extend(f->shared->lf, f->shared->access_parms, op,
- blk.size, &(blk.addr)/*out*/) < 0) {
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "low level mem management failed");
- }
-
- /* Convert from absolute to relative */
- blk.addr -= f->shared->base_addr;
-
- /* Did we extend the size of the hdf5 data? */
- tmp_addr = blk.addr + blk.size;
- if (H5F_addr_gt(tmp_addr, f->shared->hdf5_eof)) {
- f->shared->hdf5_eof = tmp_addr;
- }
+ /* Convert absolute file address to relative file address */
+ assert(ret_value>=f->shared->base_addr);
+ ret_value -= f->shared->base_addr;
- if ((status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
- &blk, addr_p/*out*/))>0) {
- /* Exact match */
- } else if (0==status) {
- /* Partial match */
- if (H5F_addr_gt (*addr_p, blk.addr)) {
- n = *addr_p - blk.addr;
- H5MF_xfree (f, blk.addr, n);
- blk.addr = *addr_p;
- blk.size -= n;
- }
- if (blk.size > size) {
- blk.addr += size;
- blk.size -= size;
- H5MF_xfree (f, blk.addr, blk.size);
- }
- }
- }
-
- FUNC_LEAVE(SUCCEED);
+ FUNC_LEAVE(ret_value);
}
+
/*-------------------------------------------------------------------------
* Function: H5MF_xfree
@@ -183,8 +90,6 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/)
* Purpose: Frees part of a file, making that part of the file
* available for reuse.
*
- * Note: This version of the function doesn't do anything.
- *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
@@ -194,13 +99,14 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/)
* Modifications:
* Robb Matzke, 1999-07-28
* The ADDR argument is passed by value
+ *
+ * Robb Matzke, 1999-08-03
+ * Modified to use the virtual file layer.
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size)
+H5MF_xfree(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size)
{
- int i;
-
FUNC_ENTER(H5MF_xfree, FAIL);
/* check arguments */
@@ -210,31 +116,20 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size)
}
assert(addr!=0);
- /*
- * Insert this free block into the free list without attempting to
- * combine it with other free blocks. If the list is overfull then
- * remove the smallest free block.
- */
- if (f->shared->fl_nfree>=H5MF_NFREE) {
- for (i=0; i<H5MF_NFREE; i++) {
- if (f->shared->fl_free[i].size<size) {
+ /* Convert relative address to absolute address */
+ addr += f->shared->base_addr;
+
+ /* Allow virtual file layer to free block */
+ if (H5FD_free(f->shared->lf, type, addr, size)<0) {
#ifdef H5MF_DEBUG
- if (H5DEBUG(MF)) {
- fprintf(H5DEBUG(MF),
- "H5MF_free: lost %lu bytes of file storage\n",
- (unsigned long) f->shared->fl_free[i].size);
- }
-#endif
- f->shared->fl_free[i].addr = addr;
- f->shared->fl_free[i].size = size;
- break;
- }
+ if (H5DEBUG(MF)) {
+ fprintf(H5DEBUG(MF),
+ "H5MF_free: lost %lu bytes of file storage\n",
+ (unsigned long)size);
}
- } else {
- i = f->shared->fl_nfree++;
- f->shared->fl_free[i].addr = addr;
- f->shared->fl_free[i].size = size;
+#endif
}
+
FUNC_LEAVE(SUCCEED);
}
@@ -243,12 +138,12 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size)
* Function: H5MF_realloc
*
* Purpose: Changes the size of an allocated chunk, possibly moving it to
- * a new address. The chunk to change is at address ORIG_ADDR
- * and is exactly ORIG_SIZE bytes (if these are zero and undef
- * then this function acts like H5MF_alloc). The new size will
- * be NEW_SIZE and its address is returned though NEW_ADDR_P (if
+ * a new address. The chunk to change is at address OLD_ADDR
+ * and is exactly OLD_SIZE bytes (if these are H5F_ADDR_UNDEF
+ * and zero then this function acts like H5MF_alloc). The new
+ * size will be NEW_SIZE and its address is the return value (if
* NEW_SIZE is zero then this function acts like H5MF_free and
- * an undefined address is returned for NEW_ADDR_P).
+ * an undefined address is returned).
*
* If the new size is less than the old size then the new
* address will be the same as the old address (except for the
@@ -258,7 +153,9 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size)
* new address will be returned. However, under certain
* circumstances the library may return the same address.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Success: The relative file address of the new block.
+ *
+ * Failure: HADDR_UNDEF
*
* Programmer: Robb Matzke
* Thursday, April 16, 1998
@@ -267,59 +164,33 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size)
* Robb Matzke, 1999-07-28
* The ORIG_ADDR is passed by value. The name of NEW_ADDR has
* been changed to NEW_ADDR_P
+ *
+ * Robb Matzke, 1999-08-04
+ * Modified to work with the virtual file layer.
*-------------------------------------------------------------------------
*/
-herr_t
-H5MF_realloc (H5F_t *f, intn op, hsize_t orig_size, haddr_t orig_addr,
- hsize_t new_size, haddr_t *new_addr_p/*out*/)
+haddr_t
+H5MF_realloc(H5F_t *f, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size,
+ hsize_t new_size)
{
- FUNC_ENTER (H5MF_realloc, FAIL);
+ haddr_t ret_value=HADDR_UNDEF;
+
+ FUNC_ENTER (H5MF_realloc, HADDR_UNDEF);
- if (0==orig_size) {
- /* Degenerate to H5MF_alloc() */
- assert (!H5F_addr_defined (orig_addr));
- if (new_size>0) {
- if (H5MF_alloc (f, op, new_size, new_addr_p/*out*/)<0) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL,
- "unable to allocate new file memory");
- }
- } else {
- *new_addr_p = H5F_ADDR_UNDEF;
- }
-
- } else if (0==new_size) {
- /* Degenerate to H5MF_free() */
- assert (H5F_addr_defined (orig_addr));
- if (H5MF_xfree (f, orig_addr, orig_size)<0) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL,
- "unable to free old file memory");
- }
- *new_addr_p = H5F_ADDR_UNDEF;
-
- } else if (new_size > orig_size) {
- /* Size is getting larger */
- if (H5MF_alloc (f, op, new_size, new_addr_p/*out*/)<0) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL,
- "unable to allocate new file memory");
- }
- if (H5MF_xfree (f, orig_addr, orig_size)<0) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL,
- "unable to free old file memory");
- }
+ /* Convert old relative address to absolute address */
+ old_addr += f->shared->base_addr;
- } else {
- /* New size is not larger */
-#ifdef H5MF_DEBUG
- if (H5DEBUG(MF) && new_size<orig_size) {
- HDfprintf (H5DEBUG(MF), "H5MF: realloc lost %Hd bytes\n",
- orig_size-new_size);
- }
-#endif
- *new_addr_p = orig_addr;
+ /* Reallocate memory from the virtual file layer */
+ ret_value = H5FD_realloc(f->shared->lf, type, old_addr, old_size,
+ new_size);
+ if (HADDR_UNDEF==ret_value) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate new file memory");
}
- FUNC_LEAVE (SUCCEED);
-}
+ /* Convert return value to relative address */
+ assert(ret_value>=f->shared->base_addr);
+ ret_value -= f->shared->base_addr;
-
-
+ FUNC_LEAVE(ret_value);
+}