/*------------------------------------------------------------------------- * 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 {