summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-08-10 20:21:32 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-08-10 20:21:32 (GMT)
commitcbf68fc824f69dcdc0fcd38a83a3fee8c7093c28 (patch)
treeb7075c9f11db1b343593b5e0619a285ccc8418af /src/H5MF.c
parent7d949c9da91b33955d4e253c1093a4f23fb63523 (diff)
downloadhdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.zip
hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.gz
hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.bz2
[svn-r1568] Changes since 19990730
---------------------- This extensive change is the virtual file layer implementation. I've ported and tested the sec2, family, and core drivers and only ported the mpio driver (Albert will test it). So if you need MPIO I would recommend sticking with the previous version for a while. You will get a few compile warnings about split and stdio drivers not being implemented and possibly tracing information not inserted in some of the drivers. You can safely ignore them but I plan to fix them. I'm still working on the split driver because I just realized that it needs a part of the VFL that isn't written yet. Documentation is being updated also because there were some minor changes (mostly just name changes). It should be available on my web site later this week. ./MANIFEST ./src/Makefile.in ./src/hdf5.h ./src/H5Flow.c [REMOVED] ./src/H5Fstdio.c [REMOVED] ./src/H5Fsec2.c [REMOVED] ./src/H5Fsplit.c [REMOVED] ./src/H5Fmpio.c [REMOVED] ./src/H5Ffamily.c [REMOVED] ./src/H5Fcore.c [REMOVED] ./src/H5MFpublic.h [REMOVED] ./src/H5FD.c [NEW] ./src/H5FDcore.c [NEW] ./src/H5FDcore.h [NEW] ./src/H5FDfamily.c [NEW] ./src/H5FDfamily.h [NEW] ./src/H5FDmpio.c [NEW] ./src/H5FDmpio.h [NEW] ./src/H5FDprivate.h [NEW] ./src/H5FDpublic.h [NEW] ./src/H5FDsec2.c [NEW] ./src/H5FDsec2.h [NEW] Removed/added files for virtual file layer. ./bin/trace ./src/H5.c Removed unused public datatypes and added new VFL public datatypes. Changed an error message. ./config/BlankForm ./config/dec-flags ./config/gnu-flags ./config/hpux10.20 ./config/hpux9.03 ./config/irix5.x ./config/irix6.x ./config/solaris2.x ./config/unicosmk Removed the H5F_OPT_SEEK and H5F_LOW_DFLT constants from the configuration since they're no longer applicable. The default file driver is always the sec2 driver and it always optimizes calls to lseek() or lseek64(). ./config/depend.in C preprocessor errors generated during automatic dependency building are sent to /dev/null to prevent them from appearing twice in the make output. ./src/H5AC.c ./src/H5B.c ./src/H5D.c ./src/H5F.c ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c ./src/H5HG.c ./src/H5HL.c ./src/H5O.c ./src/H5Oattr.c ./src/H5Odtype.c ./src/H5Oefl.c ./src/H5Oshared.c ./src/H5T.c ./src/H5detect.c ./test/ohdr.c Changed H5F_ADDR_UNDEF to HADDR_UNDEF to be more consistent with the `haddr_t' datatype which is now a public type. ./src/H5D.c ./src/H5P.c ./src/H5Ppublic.h ./src/H5Tconv.c ./test/cmpd_dset.c ./test/dsets.c ./test/overhead.c ./test/tselect.c ./test/tvltypes.c The H5P_DATASET_XFER constant was changed to H5P_DATA_XFER because the properties apply to all types of I/O operations, not just datasets. ./src/H5B.c ./src/H5Bprivate.h ./src/H5D.c ./src/H5Dpublic.h ./src/H5F.c ./src/H5Farray.c ./src/H5Fistore.c ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5HG.c ./src/H5HL.c ./src/H5O.c ./src/H5R.c ./src/H5Sall.c ./src/H5Shyper.c ./src/H5Smpio.c ./src/H5Spoint.c ./src/H5Sprivate.h ./test/big.c ./test/h5test.c ./test/istore.c ./testpar/t_dset.c ./testpar/t_file.c ./tools/h5debug.c ./tools/h5ls.c Modified to work with the virtual file layer by calling H5FD_* functions instead of H5F_low_* functions and by passing file access and data transfer properties by object ID instead of pointer. Changed H5D_transfer_t to H5FD_mpio_xfer_t since the COLLECTIVE vs. INDEPENDENT transfer mode is specific to the MPIO file driver. Moved MPIO-specific stuff into the MPIO driver. ./src/H5B.c ./src/H5D.c ./src/H5Fprivate.h The H5F_mpio_* private functions were renamed and placed in the H5FDmpio driver except those which appeared in H5Smpio.c. ./src/H5E.c ./src/H5Epublic.h Added major error number H5E_VFL for virtual file layer related errors. ./src/H5F.c ./src/H5Fprivate.h Changed the logic that controls whether the boot block is written. Instead of assuming that the first call to write the boot block is only to allocate space, I've added a function argument which makes this explicit. Changed the way files are compared so that a driver-defined comparison function can be called. Files which belong to different drivers are always considered different. Removed H5F_driver_t since file drivers are now identified by object ID instead of a special non-user-extendible datatype. Removed all the hard-coded low-level file properties which have been replaced by the various file drivers. ./src/H5I.c ./src/H5Iprivate.h Added the H5I_inc_ref() which was removed a few months ago since we finally have a use for it. ./src/H5Ipublic.h Added the H5I_VFL object ID type to identify file drivers in the virtual file layer. ./src/H5MF.c ./src/H5MFprivate.h Moved all the allocation/deallocation code into the virtual file layer which allows file drivers to override much of it. ./src/H5P.c ./src/H5Ppublic.h Moved file driver-specific code into the various file driver files. The H5Pcopy() and H5Pclose() functions make calls into the virtual file driver to manage the memory for driver-specific file access and data transfer properties. ./src/H5private.h ./src/H5public.h The `haddr_t' type is now public. ./test/tfile.c Added a few more comments.
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);
+}