diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2011-07-20 21:47:15 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2011-07-20 21:47:15 (GMT) |
commit | 08bb61054759d30c048af7baf1ca144b93ac9ce0 (patch) | |
tree | 6267483df5703b615d7b657145fa9bbe80ee8ee7 /src/H5Fcwfs.c | |
parent | 0a5bcc1df0ee1008e7c967facaa8b06797b669e1 (diff) | |
download | hdf5-08bb61054759d30c048af7baf1ca144b93ac9ce0.zip hdf5-08bb61054759d30c048af7baf1ca144b93ac9ce0.tar.gz hdf5-08bb61054759d30c048af7baf1ca144b93ac9ce0.tar.bz2 |
[svn-r21133] Description:
More code cleanups to reduce coupling between packages that use the H5F
internal routines, but really aren't part of the H5F "package".
Tested on:
FreeBSD/32 8.2 (loyalty) w/gcc4.6, w/C++ & FORTRAN, in debug mode
FreeBSD/64 8.2 (freedom) w/gcc4.6, w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-amd64 2.6 (koala) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, w/threadsafe, in production mode
Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode
Mac OS X/32 10.6.8 (amazon) in debug mode
Diffstat (limited to 'src/H5Fcwfs.c')
-rw-r--r-- | src/H5Fcwfs.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/src/H5Fcwfs.c b/src/H5Fcwfs.c new file mode 100644 index 0000000..cc3cbd6 --- /dev/null +++ b/src/H5Fcwfs.c @@ -0,0 +1,323 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol <koziol@hdfgroup.org> + * Tuesday, July 19, 2011 + * + * Purpose: Each file has a small cache of global heap collections called + * the CWFS list and recently accessed collections with free + * space appear on this list. As collections are accessed the + * collection is moved toward the front of the list. New + * collections are added to the front of the list while old + * collections are added to the end of the list. + * + * The collection model reduces the overhead which would be + * incurred if the global heap were a single object, and the + * CWFS list allows the library to cheaply choose a collection + * for a new object based on object size, amount of free space + * in the collection, and temporal locality. + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5HGprivate.h" /* Global heaps */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ + + +/****************/ +/* Local Macros */ +/****************/ + +/* + * Maximum length of the CWFS list, the list of remembered collections that + * have free space. + */ +#define H5F_NCWFS 16 + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5F_cwfs_add + * + * Purpose: Add a global heap collection to the CWFS for a file. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, July 19, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_cwfs_add(H5F_t *f, H5HG_heap_t *heap) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_cwfs_add, FAIL) + + /* Check args */ + HDassert(f); + HDassert(f->shared); + HDassert(heap); + + /* + * Add the new heap to the CWFS list, removing some other entry if + * necessary to make room. We remove the right-most entry that has less + * free space than this heap. + */ + if(NULL == f->shared->cwfs) { + if(NULL == (f->shared->cwfs = (H5HG_heap_t **)H5MM_malloc(H5F_NCWFS * sizeof(H5HG_heap_t *)))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate CWFS for file") + f->shared->cwfs[0] = heap; + f->shared->ncwfs = 1; + } else if(H5F_NCWFS == f->shared->ncwfs) { + int i; /* Local index variable */ + + for(i = H5F_NCWFS - 1; i >= 0; --i) + if(H5HG_FREE_SIZE(f->shared->cwfs[i]) < H5HG_FREE_SIZE(heap)) { + HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, (size_t)i * sizeof(H5HG_heap_t *)); + f->shared->cwfs[0] = heap; + break; + } /* end if */ + } else { + HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, f->shared->ncwfs * sizeof(H5HG_heap_t *)); + f->shared->cwfs[0] = heap; + f->shared->ncwfs += 1; + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_cwfs_add() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_cwfs_find_free_heap + * + * Purpose: Find a global heap collection with free space for storing + * a new object. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, July 20, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_cwfs_find_free_heap(H5F_t *f, hid_t dxpl_id, size_t need, haddr_t *addr) +{ + unsigned cwfsno; /* Local index for iterating over collections */ + hbool_t found = FALSE; /* Flag to indicate a heap with enough space was found */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_cwfs_find_free_heap, FAIL) + + /* Check args */ + HDassert(f); + HDassert(f->shared); + HDassert(addr); + + /* Note that we don't have metadata cache locks on the entries in + * f->shared->cwfs. + * + * In the current situation, this doesn't matter, as we are single + * threaded, and as best I can tell, entries are added to and deleted + * from f->shared->cwfs as they are added to and deleted from the + * metadata cache. + * + * To be proper, we should either lock each entry in f->shared->cwfs + * as we examine it, or lock the whole array. However, at present + * I don't see the point as there will be significant overhead, + * and protecting and unprotecting all the collections in the global + * heap on a regular basis will skew the replacement policy. + * + * JRM - 5/24/04 + */ + for(cwfsno = 0; cwfsno < f->shared->ncwfs; cwfsno++) + if(H5HG_FREE_SIZE(f->shared->cwfs[cwfsno]) >= need) { + *addr = H5HG_ADDR(f->shared->cwfs[cwfsno]); + found = TRUE; + break; + } /* end if */ + + /* + * If we didn't find any collection with enough free space the check if + * we can extend any of the collections to make enough room. + */ + if(!found) { + size_t new_need; + + for(cwfsno = 0; cwfsno < f->shared->ncwfs; cwfsno++) { + new_need = need; + new_need -= H5HG_FREE_SIZE(f->shared->cwfs[cwfsno]); + new_need = MAX(H5HG_SIZE(f->shared->cwfs[cwfsno]), new_need); + + if((H5HG_SIZE(f->shared->cwfs[cwfsno]) + new_need) <= H5HG_MAXSIZE) { + htri_t extended; /* Whether the heap was extended */ + + extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_GHEAP, H5HG_ADDR(f->shared->cwfs[cwfsno]), (hsize_t)H5HG_SIZE(f->shared->cwfs[cwfsno]), (hsize_t)new_need); + if(extended < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "error trying to extend heap") + else if(extended == TRUE) { + if(H5HG_extend(f, dxpl_id, H5HG_ADDR(f->shared->cwfs[cwfsno]), new_need) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to extend global heap collection") + *addr = H5HG_ADDR(f->shared->cwfs[cwfsno]); + found = TRUE; + break; + } /* end if */ + } /* end if */ + } /* end for */ + } /* end if */ + + if(found) { + /* Move the collection forward in the CWFS list, if it's not + * already at the front + */ + if(cwfsno > 0) { + H5HG_heap_t *tmp = f->shared->cwfs[cwfsno]; + + f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno - 1]; + f->shared->cwfs[cwfsno - 1] = tmp; + } /* end if */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_cwfs_find_free_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_cwfs_advance_heap + * + * Purpose: Advance a heap in the CWFS + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, July 20, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_cwfs_advance_heap(H5F_t *f, H5HG_heap_t *heap, hbool_t add_heap) +{ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOFUNC(H5F_cwfs_advance_heap) + + /* Check args */ + HDassert(f); + HDassert(f->shared); + HDassert(heap); + + for(u = 0; u < f->shared->ncwfs; u++) + if(f->shared->cwfs[u] == heap) { + if(u) { + f->shared->cwfs[u] = f->shared->cwfs[u - 1]; + f->shared->cwfs[u - 1] = heap; + } /* end if */ + break; + } /* end if */ + if(add_heap && u >= f->shared->ncwfs) { + f->shared->ncwfs = MIN(f->shared->ncwfs + 1, H5F_NCWFS); + f->shared->cwfs[f->shared->ncwfs - 1] = heap; + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_cwfs_advance_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_cwfs_remove_heap + * + * Purpose: Remove a heap from the CWFS + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, July 20, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_cwfs_remove_heap(H5F_file_t *shared, H5HG_heap_t *heap) +{ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOFUNC(H5F_cwfs_remove_heap) + + /* Check args */ + HDassert(shared); + HDassert(heap); + + /* Remove the heap from the CWFS list */ + for(u = 0; u < shared->ncwfs; u++) { + if(shared->cwfs[u] == heap) { + shared->ncwfs -= 1; + HDmemmove(shared->cwfs + u, shared->cwfs + u + 1, (shared->ncwfs - u) * sizeof(H5HG_heap_t *)); + break; + } /* end if */ + } /* end for */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_cwfs_remove_heap() */ + |