Beispiel #1
0
/*-------------------------------------------------------------------------
 * Function:    H5MF_xfree
 *
 * Purpose:     Frees part of a file, making that part of the file
 *              available for reuse.
 *
 * Return:      Non-negative on success/Negative on failure
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Jul 17 1997
 *
 * 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, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI_NOFUNC(H5MF_xfree);

    /* check arguments */
    assert(f);
    if (!H5F_addr_defined(addr) || 0 == size)
        HGOTO_DONE(SUCCEED);
    assert(addr!=0);

    /* 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, dxpl_id, addr, size)<0) {
#ifdef H5MF_DEBUG
	if (H5DEBUG(MF)) {
	    fprintf(H5DEBUG(MF),
		    "H5MF_free: lost %lu bytes of file storage\n",
		    (unsigned long)size);
	}
#endif
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}
/*-------------------------------------------------------------------------
 * Function:    H5MF_aggr_alloc
 *
 * Purpose:     Try to allocate SIZE bytes of memory from an aggregator
 *              block if possible.
 *
 * Return:      Success:    The format address of the new file memory.
 *              Failure:    The undefined address HADDR_UNDEF
 *
 * Programmer:  Quincey Koziol
 *              Thursday, December 13, 2007
 *
 * Modifications:
 *	Vailin Choi, July 29th, 2008
 *	  The whole routine is modified to handle alignment
 *
 *-------------------------------------------------------------------------
 */
haddr_t
H5MF_aggr_alloc(H5F_t *f, hid_t dxpl_id, H5F_blk_aggr_t *aggr,
                H5F_blk_aggr_t *other_aggr, H5FD_mem_t type, hsize_t size)
{
    haddr_t 	ret_value;
    hsize_t 	alignment = 0, mis_align = 0;
    haddr_t	frag_addr = 0, eoa_frag_addr = 0;
    hsize_t	frag_size = 0, eoa_frag_size = 0;
    haddr_t	eoa = 0, new_space = 0;
    htri_t  	extended = 0;
    H5FD_mem_t 	alloc_type, other_alloc_type;

    FUNC_ENTER_NOAPI(H5MF_aggr_alloc, HADDR_UNDEF)
#ifdef H5MF_AGGR_DEBUG
    HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
#endif /* H5MF_AGGR_DEBUG */

    /* check args */
    HDassert(f);
    HDassert(aggr);
    HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
    HDassert(other_aggr);
    HDassert(other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
    HDassert(other_aggr->feature_flag != aggr->feature_flag);
    HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
    HDassert(size > 0);

    /*
     * If the aggregation feature is enabled for this file, allocate "generic"
     * space and sub-allocate out of that, if possible. Otherwise just allocate
     * through H5FD_alloc()
     */
    if(f->shared->feature_flags & aggr->feature_flag) {
#ifdef H5MF_AGGR_DEBUG
        HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
#endif /* H5MF_AGGR_DEBUG */

        alignment = f->shared->alignment;
        if (!((alignment > 1) && (size >= f->shared->threshold)))
            alignment = 0; /* no alignment */

        if (alignment && aggr->addr > 0 && aggr->size > 0 && (mis_align = aggr->addr % alignment)) {
            frag_addr = aggr->addr;
            frag_size = alignment - mis_align;
        }

        if (HADDR_UNDEF == (eoa = H5F_get_eoa(f, type)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "Unable to get eoa")

            alloc_type = aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW;
        other_alloc_type = other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW;

        /* Check if the space requested is larger than the space left in the block */
        if((size + frag_size) > aggr->size) {

            /* Check if the block asked for is too large for 'normal' aggregator block */
            if(size >= aggr->alloc_size) {

                hsize_t ext_size = size + frag_size;

                if ((aggr->addr > 0) && (extended=H5FD_try_extend(f->shared->lf, alloc_type, aggr->addr + aggr->size, ext_size)) < 0)
                    HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space")
                    else if (extended) {
                        /* aggr->size is unchanged */
                        ret_value = aggr->addr + frag_size;
                        aggr->addr += ext_size;
                        aggr->tot_size += ext_size;
                    } else {
                        if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
                                ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {

                            if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, other_aggr->addr, other_aggr->size) < 0)
                                HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")

                                other_aggr->addr = 0;
                            other_aggr->tot_size = 0;
                            other_aggr->size = 0;
                        }

                        if(HADDR_UNDEF == (new_space = H5FD_alloc(f->shared->lf, dxpl_id, type, size, &eoa_frag_addr, &eoa_frag_size)))
                            HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")

                            /* Use the new space allocated, leaving the old block */
                            ret_value = new_space;
                    } /* end else */
            } /* end if */
            else {