/*------------------------------------------------------------------------- * 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: H5HL_dest * * Purpose: Destroys a heap in memory. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Jan 15 2003 * *------------------------------------------------------------------------- */ herr_t H5HL_dest(H5HL_t *heap) { FUNC_ENTER_NOAPI_NOFUNC(H5HL_dest) /* check arguments */ HDassert(heap); /* Verify that node is unused */ HDassert(heap->prots == 0); HDassert(heap->rc == 0); HDassert(heap->prfx == NULL); HDassert(heap->dblk == NULL); if(heap->dblk_image) heap->dblk_image = H5FL_BLK_FREE(lheap_chunk, heap->dblk_image); while(heap->freelist) { H5HL_free_t *fl; fl = heap->freelist; heap->freelist = fl->next; fl = H5FL_FREE(H5HL_free_t, fl); } /* end while */ heap = H5FL_FREE(H5HL_t, heap); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HL_dest() */
/*------------------------------------------------------------------------- * Function: H5S_none_iter_init * * Purpose: Initializes iteration information for "none" selection. * * Return: non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 * * Modifications: * *------------------------------------------------------------------------- */ herr_t H5S_none_iter_init (H5S_sel_iter_t *iter, const H5S_t UNUSED *space) { FUNC_ENTER_NOAPI_NOFUNC(H5S_none_iter_init); /* Check args */ assert (space && H5S_SEL_NONE==H5S_GET_SELECT_TYPE(space)); assert (iter); /* Initialize type of selection iterator */ iter->type=H5S_sel_iter_none; FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_none_iter_init() */
/*------------------------------------------------------------------------- * Function: H5D_mpio_select_read * * Purpose: MPI-IO function to read directly from app buffer to file. * * Return: non-negative on success, negative on failure. * * Programmer: * * Modifications: * *------------------------------------------------------------------------- */ herr_t H5D_mpio_select_read(H5D_io_info_t *io_info, size_t UNUSED nelmts, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, void *buf/*out*/) { herr_t ret_value; FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_select_read); ret_value = H5D_mpio_spaces_xfer(io_info, elmt_size, file_space, mem_space, buf, 0/*read*/); FUNC_LEAVE_NOAPI(ret_value); } /* end H5D_mpio_select_read() */
/*------------------------------------------------------------------------- * Function: H5D_mpio_select_write * * Purpose: MPI-IO function to write directly from app buffer to file. * * Return: non-negative on success, negative on failure. * * Programmer: * * Modifications: * * *------------------------------------------------------------------------- */ herr_t H5D_mpio_select_write(H5D_io_info_t *io_info, size_t UNUSED nelmts, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, const void *buf) { herr_t ret_value; FUNC_ENTER_NOAPI_NOFUNC(H5D_mpio_select_write); /*OKAY: CAST DISCARDS CONST QUALIFIER*/ ret_value = H5D_mpio_spaces_xfer(io_info, elmt_size, file_space, mem_space, (void*)buf, 1/*write*/); FUNC_LEAVE_NOAPI(ret_value); } /* end H5D_mpio_spaces_write() */
/*------------------------------------------------------------------------- * Function: H5MF_alloc_overflow * * Purpose: Checks if an allocation of file space would cause an overflow. * F is the file whose space is being allocated, SIZE is the amount * of space needed. * * Return: 0 if no overflow would result * 1 if overflow would result (the allocation should not be allowed) * * Programmer: James Laird * Nat Furrer * Tuesday, June 1, 2004 * * Modifications: *------------------------------------------------------------------------- */ hbool_t H5MF_alloc_overflow(H5F_t *f, hsize_t size) { hsize_t space_needed; /* Accumulator variable */ size_t c; /* Local index variable */ hbool_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOFUNC(H5MF_alloc_overflow) /* Start with the current end of the file's address. */ space_needed = (hsize_t)H5F_get_eoa(f); HDassert(H5F_addr_defined(space_needed)); /* Subtract the file's base address to get the actual amount of * space being used: * (end of allocated space - beginning of allocated space) */ HDassert(H5F_BASE_ADDR(f) < space_needed); space_needed -= (hsize_t)H5F_BASE_ADDR(f); /* Add the amount of space requested for this allocation */ space_needed += size; /* Also add space that is "reserved" for data to be flushed * to disk (e.g., for object headers and the heap). * This is the total amount of file space that will be * allocated. */ space_needed += f->shared->lf->reserved_alloc; /* Ensure that this final number is less than the file's * address space. We do this by shifting in multiples * of 16 bits because some systems will do nothing if * we shift by the size of a long long (64 bits) all at * once (<cough> Linux <cough>). Thus, we break one shift * into several smaller shifts. */ for(c=0; c < H5F_SIZEOF_ADDR(f); c += 2) space_needed = space_needed >> 16; if(space_needed != 0) ret_value=TRUE; else ret_value=FALSE; FUNC_LEAVE_NOAPI(ret_value) }
/*------------------------------------------------------------------------- * Function: H5MF_free_reserved * * Purpose: Releases the file space set aside by H5MF_reserve. This should * be called immediately before allocating the file space for which * the space was reserved. * * Return: None * * Programmer: James Laird * Nat Furrer * Thursday, May 27, 2004 * * Modifications: *------------------------------------------------------------------------- */ herr_t H5MF_free_reserved(H5F_t *f, hsize_t size) { FUNC_ENTER_NOAPI_NOFUNC(H5MF_free_reserved) /* Check arguments */ assert(f); /* If this assert breaks, it means that HDF5 is trying to free file space * that was never reserved. */ assert(size <= f->shared->lf->reserved_alloc); f->shared->lf->reserved_alloc -= size; FUNC_LEAVE_NOAPI(SUCCEED) }
/*------------------------------------------------------------------------- * Function: H5G_ent_to_link * * Purpose: Convert a symbol table entry to a link * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Sep 16 2006 * *------------------------------------------------------------------------- */ herr_t H5G_ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, const H5G_entry_t *ent, const char *name) { FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_to_link) /* check arguments */ HDassert(lnk); HDassert(heap); HDassert(ent); HDassert(name); /* Set (default) common info for link */ lnk->cset = H5F_DEFAULT_CSET; lnk->corder = 0; lnk->corder_valid = FALSE; /* Creation order not valid for this link */ lnk->name = H5MM_xstrdup(name); HDassert(lnk->name); /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ s = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset); HDassert(s); /* Copy the link value */ lnk->u.soft.name = H5MM_xstrdup(s); /* Set link type */ lnk->type = H5L_TYPE_SOFT; } /* end if */ else { /* Set address of object */ lnk->u.hard.addr = ent->header; /* Set link type */ lnk->type = H5L_TYPE_HARD; } /* end else */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_ent_to_link() */
/*------------------------------------------------------------------------- * Function: H5MP_free * * Purpose: Release space in a memory pool * * Return: NULL on success/NULL on failure * * Programmer: Quincey Koziol * [email protected] * May 3 2005 * * Note: Should we release pages that have no used blocks? * *------------------------------------------------------------------------- */ void * H5MP_free (H5MP_pool_t *mp, void *spc) { H5MP_page_blk_t *spc_blk; /* Block for space to free */ H5MP_page_t *spc_page; /* Page containing block to free */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOFUNC(H5MP_free) /* Sanity check */ HDassert(mp); HDassert(spc); /* Get block header for space to free */ spc_blk = (H5MP_page_blk_t *)(((unsigned char *)spc) - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))); /* Mark block as free */ HDassert(spc_blk->is_free == FALSE); spc_blk->is_free = TRUE; /* Add it's space to the amount of free space in the page & pool */ spc_page = spc_blk->page; #ifdef QAK HDfprintf(stderr,"%s: Freeing from page = %p\n", "H5MP_free", spc_page); #endif /* QAK */ spc_page->free_size += spc_blk->size; mp->free_size += spc_blk->size; /* Move page with newly freed space to front of list of pages in pool */ if(spc_page != mp->first) { /* Remove page from list */ spc_page->prev->next = spc_page->next; if(spc_page->next) spc_page->next->prev = spc_page->prev; /* Insert page at beginning of list */ spc_page->prev = NULL; spc_page->next = mp->first; mp->first->prev = spc_page; mp->first = spc_page; } /* end if */ /* Check if block can be merged with free space after it on page */ if(spc_blk->next != NULL) { H5MP_page_blk_t *next_blk; /* Block following space to free */ next_blk = spc_blk->next; HDassert(next_blk->prev == spc_blk); if(next_blk->is_free) { spc_blk->size += next_blk->size; spc_blk->next = next_blk->next; } /* end if */ } /* end if */ /* Check if block can be merged with free space before it on page */ if(spc_blk->prev != NULL) { H5MP_page_blk_t *prev_blk; /* Block before space to free */ prev_blk = spc_blk->prev; HDassert(prev_blk->next == spc_blk); if(prev_blk->is_free) { prev_blk->size += spc_blk->size; prev_blk->next = spc_blk->next; } /* end if */ } /* end if */ /* Check if the block freed becomes the first free block on the page */ if(spc_page->free_blk == NULL || spc_blk < spc_page->free_blk) spc_page->free_blk = spc_blk; FUNC_LEAVE_NOAPI(ret_value) } /* end H5MP_free() */