⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mvarimpl.inl

📁 实现快速傅立叶变换算法,provides test framwork for FFT testing
💻 INL
📖 第 1 页 / 共 2 页
字号:
        return NULL;

    size = roundup(size);

    do {
        CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
        dq = dq->next;
        if(0 == dq->size) {
            CYG_ASSERT(dq == &head, "bad free block");
            return NULL;
        }
    } while(dq->size < size);

    if( size == dq->size ) {
        // exact fit -- unlink from free list
        dq->prev->next = dq->next;
        dq->next->prev = dq->prev;
        alloced = (cyg_uint8 *)dq;
    } else {

        CYG_ASSERT( dq->size > size, "block found is too small");

        // allocate portion of memory from end of block
        
        dq->size -=size;

        // The portion left over has to be large enough to store a
        // struct memdq.  This is guaranteed because the alignment is
        // larger than the size of this structure.

        CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=dq->size ,
                "not enough space for list item" );

        alloced = (cyg_uint8 *)dq + dq->size;
    }

    CYG_ASSERT( bottom<=alloced && alloced<=top, "alloced outside pool" );

    // Set size on allocated block

    dq = (struct memdq *)alloced;
    dq->size = size;
    dq->next = dq->prev = (struct memdq *)0xd530d53; // magic number

    freemem -=size;

    cyg_uint8 *ptr = memdq2alloc( dq );
    CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0,
                "returned memory not aligned" );
    CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size);

    return ptr;
}

// -------------------------------------------------------------------------
// resize existing allocation, if oldsize is non-NULL, previous
// allocation size is placed into it. If previous size not available,
// it is set to 0. NB previous allocation size may have been rounded up.
// Occasionally the allocation can be adjusted *backwards* as well as,
// or instead of forwards, therefore the address of the resized
// allocation is returned, or NULL if no resizing was possible.
// Note that this differs from ::realloc() in that no attempt is
// made to call malloc() if resizing is not possible - that is left
// to higher layers. The data is copied from old to new though.
// The effects of alloc_ptr==NULL or newsize==0 are undefined

inline cyg_uint8 *
Cyg_Mempool_Variable_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
                                                   cyg_int32 newsize,
                                                   cyg_int32 *oldsize )
{
    cyg_uint8 *ret = NULL;

    CYG_REPORT_FUNCTION();
    
    CYG_CHECK_DATA_PTRC( alloc_ptr );
    if ( NULL != oldsize )
        CYG_CHECK_DATA_PTRC( oldsize );

    CYG_ASSERT( (bottom <= alloc_ptr) && (alloc_ptr <= top),
                "alloc_ptr outside pool" );
    
    struct memdq *dq=alloc2memdq( alloc_ptr );
    
    // check magic number in block for validity
    CYG_ASSERT( (dq->next == dq->prev) &&
                (dq->next == (struct memdq *)0xd530d53), "bad alloc_ptr" );

    newsize = roundup(newsize);

    if ( NULL != oldsize )
        *oldsize = dq->size;

    if ( newsize > dq->size ) {
        // see if we can increase the allocation size
        if ( (cyg_uint8 *)dq + newsize <= top ) { // obviously can't exceed pool
            struct memdq *nextdq = (struct memdq *)((cyg_uint8 *)dq + dq->size);

            if ( (nextdq->next != nextdq->prev) &&
                 (nextdq->size >= (newsize - dq->size)) ) {
                // it's free and it's big enough
                // we therefore temporarily join this block and *all* of
                // the next block, so that the code below can then split it
                nextdq->next->prev = nextdq->prev;
                nextdq->prev->next = nextdq->next;
                dq->size += nextdq->size;
                freemem -= nextdq->size;
            }
        } // if
    } // if

    // this is also used if the allocation size was increased and we need
    // to split it
    if ( newsize < dq->size ) {
        // We can shrink the allocation by splitting into smaller allocation and
        // new free block
        struct memdq *newdq = (struct memdq *)((cyg_uint8 *)dq + newsize);
        
        newdq->size = dq->size - newsize;
        dq->size = newsize;
        
        CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=newdq->size ,
                    "not enough space for list item" );

        // now return the new space back to the freelist
        insert_free_block( newdq );
        
        ret = alloc_ptr;
        
    } // if
    else if ( newsize == dq->size ) {
        ret = alloc_ptr;
    }
        
    CYG_MEMALLOC_FAIL_TEST(ret==NULL, newsize);

    return ret;

} // resize_alloc()


// -------------------------------------------------------------------------
// When no coalescing is done, free is simply a matter of using the
// freed memory as an element of the free list linking it in at the
// start. When coalescing, the free list is sorted
    
inline cyg_bool
Cyg_Mempool_Variable_Implementation::free( cyg_uint8 *p, cyg_int32 size )
{
    CYG_REPORT_FUNCTION();

    CYG_CHECK_DATA_PTRC( p );

    if (!((bottom <= p) && (p <= top)))
        return false;
    
    struct memdq *dq=alloc2memdq( p );

    // check magic number in block for validity
    if ( (dq->next != dq->prev) ||
         (dq->next != (struct memdq *)0xd530d53) )
        return false;

    if ( 0==size ) {
        size = dq->size;
    } else {
        size = roundup(size);
    }

    if( dq->size != size )
        return false;

    CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=size ,
                "not enough space for list item" );

    insert_free_block( dq );

    return true;
}    

// -------------------------------------------------------------------------

inline void
Cyg_Mempool_Variable_Implementation::get_status(
    cyg_mempool_status_flag_t flags,
    Cyg_Mempool_Status &status )
{
    CYG_REPORT_FUNCTION();

// as quick or quicker to just set it, rather than test flag first
    status.arenabase = obase;
    if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
        status.arenasize = top - bottom;
    if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
        status.totalallocated = (top-bottom) - freemem;
// as quick or quicker to just set it, rather than test flag first
    status.totalfree = freemem;
    if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
        struct memdq *dq = &head;
        cyg_int32 mf = 0;
        
        do {
            CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
            dq = dq->next;
            if(0 == dq->size) {
                CYG_ASSERT(dq == &head, "bad free block");
                break;
            }
            if(dq->size > mf)
                mf = dq->size;
        } while(1);
        status.maxfree = mf - sizeof(struct memdq);
    }
// as quick or quicker to just set it, rather than test flag first
    status.origbase = obase;
// as quick or quicker to just set it, rather than test flag first
    status.origsize = osize;
        
    CYG_REPORT_RETURN();

} // get_status()


// -------------------------------------------------------------------------
#endif // ifndef CYGONCE_MEMALLOC_MVARIMPL_INL
// EOF mvarimpl.inl

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -