summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-06-10 14:43:15 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-06-10 14:43:15 (GMT)
commitac4c35cca592fc598c5a064fd8f769bbef69bd75 (patch)
tree6b23aa1ea8834532ca1de25b3fa469bc3d2a8158 /src/H5MF.c
parent27edf86f6ab408352b4b975669d0759aa47bff78 (diff)
downloadhdf5-ac4c35cca592fc598c5a064fd8f769bbef69bd75.zip
hdf5-ac4c35cca592fc598c5a064fd8f769bbef69bd75.tar.gz
hdf5-ac4c35cca592fc598c5a064fd8f769bbef69bd75.tar.bz2
[svn-r418] ./html/Files.html
./src/H5F.c ./src/HFcore.c ./src/H5Ffamily.c ./src/H5Flow.c ./src/H5Fmpio.c ./src/H5Fprivate.h ./src/H5Fsec2.c ./src/H5Fsplit.c ./src/H5Fstdio.c ./src/H5MF.c ./src/H5P.c ./src/H5Ppublic.h Added H5Pset_alignment() so that it is now possible to align file allocation requests on application-specified boundaries. Any request >= the specified threshold will begin on an address which is a multiple of the specified alignment. Defaults are one for threshold and alignment. The alignment is done on relative addresses, so the size of the user block can affect the location of the data in the file. ./src/H5D.c ./src/dsets.c Added a test for, and fixed the data space caching bug in datasets. Extending a dataset through one handle will cause all other handles to the same dataset to get the new dataset size. ./src/H5S.c ./src/H5Sprivate.h Removed an unused argument from H5S_read() which duplicated information from the other argument. ./config/linux Made `--enable-parallel' the default on my system. It used to be that way before but then I accidently turned it off and forgot about it. ./src/H5Fmpio.c Qualified some function arguments with __unused__. Changed a couple places where NULL was returned on error for herr_t functions. ./src/H5P.c Removed unused autos from H5Pset_mpi().
Diffstat (limited to 'src/H5MF.c')
-rw-r--r--src/H5MF.c155
1 files changed, 134 insertions, 21 deletions
diff --git a/src/H5MF.c b/src/H5MF.c
index a87dc39..6a51ff7 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -11,10 +11,13 @@
* Purpose: File memory management functions.
*
* Modifications:
- *
* Robb Matzke, 5 Aug 1997
* Added calls to H5E.
*
+ * Robb Matzke, 8 Jun 1998
+ * Implemented a very simple free list which is not persistent and which
+ * is lossy.
+ *
*-------------------------------------------------------------------------
*/
#include <H5private.h>
@@ -27,6 +30,7 @@
/* Is the interface initialized? */
static intn interface_initialize_g = FALSE;
#define INTERFACE_INIT NULL
+
/*-------------------------------------------------------------------------
* Function: H5MF_alloc
@@ -53,7 +57,12 @@ static intn interface_initialize_g = FALSE;
herr_t
H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
{
- haddr_t tmp_addr;
+ haddr_t tmp_addr;
+ intn i, found, status;
+ 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);
@@ -63,30 +72,114 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
assert(size > 0);
assert(addr);
+#if 0
+ HDfprintf (stderr, "A %Hu\n", size);
+#endif
+
+
/* 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");
}
/*
- * Eventually we'll maintain a free list(s) and try to satisfy requests
- * from there. But for now we just allocate more memory from the end of
- * the file.
+ * 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.
*/
- if (H5F_low_extend(f->shared->lf, f->shared->access_parms, op,
- size, addr/*out*/) < 0) {
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "low level mem management failed");
+ 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/*out*/))>0) {
+ /* Exact match found */
+ found = i;
+ break;
+ } else if (0==status) {
+ /* Partial match */
+ found = i;
+ }
}
- /* Convert from absolute to relative */
- addr->offset -= f->shared->base_addr.offset;
-
- /* Did we extend the size of the hdf5 data? */
- tmp_addr = *addr;
- H5F_addr_inc(&tmp_addr, size);
- if (H5F_addr_gt(&tmp_addr, &(f->shared->hdf5_eof))) {
- f->shared->hdf5_eof = tmp_addr;
+
+ if (found>=0 &&
+ (status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
+ f->shared->fl_free+found, addr/*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, &(blk.addr))) {
+ /* Free the first part of the free block */
+ n = addr->offset - blk.addr.offset;
+ H5MF_free (f, &(blk.addr), n);
+ blk.addr = *addr;
+ blk.size -= n;
+ }
+
+ if (blk.size > size) {
+ /* Free the second part of the free block */
+ H5F_addr_inc (&(blk.addr), size);
+ blk.size -= size;
+ H5MF_free (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.offset -= f->shared->base_addr.offset;
+
+ /* Did we extend the size of the hdf5 data? */
+ tmp_addr = blk.addr;
+ H5F_addr_inc(&tmp_addr, blk.size);
+ if (H5F_addr_gt(&tmp_addr, &(f->shared->hdf5_eof))) {
+ f->shared->hdf5_eof = tmp_addr;
+ }
+
+ if ((status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
+ &blk, addr/*out*/))>0) {
+ /* Exact match */
+ } else if (0==status) {
+ /* Partial match */
+ if (H5F_addr_gt (addr, &(blk.addr))) {
+ n = addr->offset - blk.addr.offset;
+ H5MF_free (f, &(blk.addr), n);
+ blk.addr = *addr;
+ blk.size -= n;
+ }
+ if (blk.size > size) {
+ H5F_addr_inc (&(blk.addr), size);
+ blk.size -= size;
+ H5MF_free (f, &(blk.addr), blk.size);
+ }
+ }
}
+
FUNC_LEAVE(SUCCEED);
}
@@ -111,8 +204,10 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_free(H5F_t __unused__ *f, const haddr_t *addr, hsize_t size)
+H5MF_free(H5F_t *f, const haddr_t *addr, hsize_t size)
{
+ int i;
+
FUNC_ENTER(H5MF_free, FAIL);
/* check arguments */
@@ -121,11 +216,29 @@ H5MF_free(H5F_t __unused__ *f, const haddr_t *addr, hsize_t size)
HRETURN(SUCCEED);
assert(!H5F_addr_zerop(addr));
+ /*
+ * 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) {
#ifdef H5MF_DEBUG
- fprintf(stderr, "H5MF_free: lost %lu bytes of file storage\n",
- (unsigned long) size);
+ fprintf(stderr, "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;
+ }
+ }
+ } else {
+ i = f->shared->fl_nfree++;
+ f->shared->fl_free[i].addr = *addr;
+ f->shared->fl_free[i].size = size;
+ }
+
FUNC_LEAVE(SUCCEED);
}