diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-06-10 14:43:15 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-06-10 14:43:15 (GMT) |
commit | ac4c35cca592fc598c5a064fd8f769bbef69bd75 (patch) | |
tree | 6b23aa1ea8834532ca1de25b3fa469bc3d2a8158 /src/H5MF.c | |
parent | 27edf86f6ab408352b4b975669d0759aa47bff78 (diff) | |
download | hdf5-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.c | 155 |
1 files changed, 134 insertions, 21 deletions
@@ -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); } |