コード例 #1
0
ファイル: H5MFaggr.c プロジェクト: asteever/thirdparty_hdf5
/*-------------------------------------------------------------------------
 * 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
 *
 *-------------------------------------------------------------------------
 */
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	eoa_frag_addr = HADDR_UNDEF;    /* Address of fragment at EOA */
    hsize_t	eoa_frag_size = 0;      /* Size of fragment at EOA */
    haddr_t	eoa = HADDR_UNDEF;      /* Initial EOA for the file */
    haddr_t 	ret_value;              /* Return value */

    FUNC_ENTER_NOAPI(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);

    /* Get the EOA for the file */
    if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, type)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa")

    /*
     * If the aggregation feature is enabled for this file and strategy is not H5F_FILE_SPACE_VFD,
     * 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) && f->shared->fs_strategy != H5F_FILE_SPACE_VFD) {
        haddr_t	aggr_frag_addr = HADDR_UNDEF;   /* Address of aggregrator fragment */
        hsize_t	aggr_frag_size = 0;             /* Size of aggregator fragment */
        hsize_t alignment;                      /* Alignment of this section */
        hsize_t aggr_mis_align = 0;             /* Mis-alignment of aggregator */
        H5FD_mem_t alloc_type, other_alloc_type;/* Current aggregator & 'other' aggregator types */

#ifdef H5MF_AGGR_DEBUG
HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
#endif /* H5MF_AGGR_DEBUG */

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

        /* Generate fragment if aggregator is mis-aligned */
	if(alignment && aggr->addr > 0 && aggr->size > 0 && (aggr_mis_align = (aggr->addr + H5FD_get_base_addr(f->shared->lf)) % alignment)) {
	    aggr_frag_addr = aggr->addr;
	    aggr_frag_size = alignment - aggr_mis_align;
	} /* end if */

	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 + aggr_frag_size) > aggr->size) {
            htri_t  	was_extended = FALSE;   /* Whether the file was extended */

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

                /* Check for overlapping into file's temporary allocation space */
                if(H5F_addr_gt((aggr->addr + aggr->size + ext_size), f->shared->tmp_addr))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")

		if ((aggr->addr > 0) && (was_extended = H5FD_try_extend(f->shared->lf, alloc_type, f, aggr->addr + aggr->size, ext_size)) < 0)
		    HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space")
		else if (was_extended) {
		    /* aggr->size is unchanged */
		    ret_value = aggr->addr + aggr_frag_size;
		    aggr->addr += ext_size;
		    aggr->tot_size += ext_size;
		} else {
                    /* Check for overlapping into file's temporary allocation space */
                    if(H5F_addr_gt((eoa + size), f->shared->tmp_addr))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")

                    /* Release "other" aggregator, if it exists, is at the end of the allocated space,
                     * has allocated more than one block and the unallocated space is greater than its
                     * allocation block size.
                     */
		    if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
			(other_aggr->tot_size > other_aggr->size) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
                            if(H5MF_aggr_free(f, dxpl_id, other_alloc_type, other_aggr) < 0)
                                HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
		    } /* end if */

                    /* Allocate space from the VFD (i.e. at the end of the file) */
		    if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, dxpl_id, alloc_type, f, size, &eoa_frag_addr, &eoa_frag_size)))
			HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
                } /* end else */
            } /* end if */
コード例 #2
0
/*-------------------------------------------------------------------------
 * 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 {
コード例 #3
0
ファイル: H5Ocache.c プロジェクト: chaako/sceptic3D
/*-------------------------------------------------------------------------
 * Function:	H5O_load
 *
 * Purpose:	Loads an object header from disk.
 *
 * Return:	Success:	Pointer to the new object header.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Aug  5 1997
 *
 *-------------------------------------------------------------------------
 */
static H5O_t *
H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
	 void UNUSED * _udata2)
{
    H5O_t	*oh = NULL;     /* Object header read in */
    uint8_t     read_buf[H5O_SPEC_READ_SIZE];       /* Buffer for speculative read */
    const uint8_t *p;           /* Pointer into buffer to decode */
    size_t	spec_read_size; /* Size of buffer to speculatively read in */
    size_t	prefix_size;    /* Size of object header prefix */
    unsigned	nmesgs;         /* Total # of messages in this object header */
    unsigned	curmesg = 0;    /* Current message being decoded in object header */
    unsigned    merged_null_msgs = 0;   /* Number of null messages merged together */
    haddr_t	chunk_addr;     /* Address of first chunk */
    size_t	chunk_size;     /* Size of first chunk */
    haddr_t     eoa;		/* Relative end of file address	*/
    H5O_t	*ret_value;     /* Return value */

    FUNC_ENTER_NOAPI(H5O_load, NULL)

    /* check args */
    HDassert(f);
    HDassert(H5F_addr_defined(addr));
    HDassert(!_udata1);
    HDassert(!_udata2);

    /* Make certain we don't speculatively read off the end of the file */
    if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR)))
        HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine file size")

    /* Compute the size of the speculative object header buffer */
    H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t);

    /* Attempt to speculatively read both object header prefix and first chunk */
    if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0)
	HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
    p = read_buf;

    /* allocate ohdr and init chunk list */
    if(NULL == (oh = H5FL_CALLOC(H5O_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* File-specific, non-stored information */
    oh->sizeof_size = H5F_SIZEOF_SIZE(f);
    oh->sizeof_addr = H5F_SIZEOF_ADDR(f);

    /* Check for magic number */
    /* (indicates version 2 or later) */
    if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
        /* Magic number */
        p += H5_SIZEOF_MAGIC;

        /* Version */
        oh->version = *p++;
        if(H5O_VERSION_2 != oh->version)
            HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")

        /* Flags */
        oh->flags = *p++;
        if(oh->flags & ~H5O_HDR_ALL_FLAGS)
            HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)")

        /* Number of messages (to allocate initially) */
        nmesgs = 1;

        /* Number of links to object (unless overridden by refcount message) */
        oh->nlink = 1;

        /* Time fields */
        if(oh->flags & H5O_HDR_STORE_TIMES) {
            uint32_t tmp;       /* Temporary value */

            UINT32DECODE(p, tmp);
            oh->atime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->mtime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->ctime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->btime = (time_t)tmp;
        } /* end if */
        else
            oh->atime = oh->mtime = oh->ctime = oh->btime = 0;

        /* Attribute fields */
        if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
            UINT16DECODE(p, oh->max_compact);
            UINT16DECODE(p, oh->min_dense);
            if(oh->max_compact < oh->min_dense)
                HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header attribute phase change values")
        } /* end if */