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

📄 mvarimpl.inl

📁 ecos为实时嵌入式操作系统
💻 INL
字号:
#ifndef CYGONCE_KERNEL_MVARIMPL_INL#define CYGONCE_KERNEL_MVARIMPL_INL//==========================================================================////      mvarimpl.inl////      Memory pool with variable block class declarations////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   hmt// Contributors:        hmt// Date:        1998-03-23// Purpose:     Define Mvarimpl class interface// Description: Inline class for constructing a variable block allocator// Usage:       #include <cyg/kernel/mvarimpl.hxx>//              #include <cyg/kernel/mvarimpl.inl>      ////####DESCRIPTIONEND####////==========================================================================// Simple non-coalescing allocator// The free list is stored on a doubly linked list, each member of// which is stored in the body of the free memory.  The head of the// list has the same structure but its size field is zero.  This// resides in the memory pool structure.  Always having at least one// item on the list simplifies the alloc and free code.// inline cyg_int32Cyg_Mempool_Variable_Implementation::roundup( cyg_int32 size ){    size += sizeof(struct memdq);    size = (size + alignment - 1) & -alignment;    return size;}Cyg_Mempool_Variable_Implementation::Cyg_Mempool_Variable_Implementation(        cyg_uint8 *base,        cyg_int32 size,        CYG_ADDRWORD align ){    CYG_ASSERT( align > 0, "Bad alignment" );    CYG_ASSERT( size > 0, "Bad size" );    CYG_ASSERT(0!=align ,"align is zero");    CYG_ASSERT(0==(align & align-1),"align not a power of 2");    obase=base;    osize=size;    oalign=align;    alignment = align;    while(alignment < (cyg_int32)sizeof(struct memdq))        alignment += alignment;    CYG_ASSERT(0==(alignment & alignment-1),"alignment not a power of 2");    bottom = (cyg_uint8 *)roundup((cyg_int32)base);    top = (cyg_uint8 *)((cyg_int32)(base+size) & -alignment);        CYG_ASSERT( top > bottom , "heap too small" );    CYG_ASSERT( ((cyg_int32)bottom & alignment-1)==0, "bottom badly aligned" );    CYG_ASSERT( ((cyg_int32)top & alignment-1)==0, "top badly aligned" );    struct memdq *hdq = &head, *dq = (struct memdq *)bottom;        hdq->prev = hdq->next = dq;    hdq->size = 0;    dq->prev = dq->next = hdq;    freemem = dq->size = top-bottom;}Cyg_Mempool_Variable_Implementation::~Cyg_Mempool_Variable_Implementation(){}// allocation is simple// First we look down the free list for a large enough block// If we find a block the right size, we unlink the block from//    the free list and return a pointer to it.// If we find a larger block, we chop a piece off the end//    and return that// Otherwise we will eventually get back to the head of the list//    and return NULLinline cyg_uint8 *Cyg_Mempool_Variable_Implementation::alloc( cyg_int32 size ){    struct memdq *dq = &head;    cyg_uint8 *alloced;    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;    return alloced + sizeof(struct memdq);}// As 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.    inline cyg_boolCyg_Mempool_Variable_Implementation::free( cyg_uint8 *p, cyg_int32 size ){    if(!(bottom<=p&&p<=top))        return false;        struct memdq *hdq=&head,*dq=(struct memdq *)(p-sizeof(struct memdq));    // check magic number in block to be freed    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" );#ifdef CYGSEM_KERNEL_MEMORY_COALESCE// For simple coalescing have the free list be sorted by memory base address    struct memdq *idq;        for (idq = hdq->next; idq != hdq; idq = idq->next) {        if (idq->next > dq)            break;    }    dq->size = size;    if (idq != hdq) {        dq->prev = idq;        dq->next = idq->next;        idq->next = dq;        dq->next->prev = dq;    } else {        dq->next = idq;        dq->prev = idq->prev;        idq->prev = dq;        dq->prev->next = dq;    }    // Now do coalescing    if ((char *)dq + dq->size == (char *)dq->next) {        dq->size += dq->next->size;        dq->next = dq->next->next;        dq->next->prev = dq;    }    if ((char *)dq->prev + dq->prev->size == (char *)dq) {        dq->prev->size += dq->size;        dq->prev->next = dq->next;        dq->next->prev = dq->prev;        dq = dq->prev;    }   #else    dq->prev = hdq;    dq->next = hdq->next;    dq->size = size;    hdq->next = dq;    dq->next->prev=dq;#endif    freemem +=size;    return true;}    inline voidCyg_Mempool_Variable_Implementation::get_arena(    cyg_uint8 * &base,    cyg_int32 &size,    CYG_ADDRWORD &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);    base = obase;    size = osize;    maxfree = mf;}inline cyg_int32Cyg_Mempool_Variable_Implementation::get_allocation_size( cyg_uint8 *ptr ){    CYG_CHECK_DATA_PTR(ptr, "Requested allocation size of bad data pointer!");    if(!(bottom<=ptr && ptr<=top))        return -1;        struct memdq *dq=(struct memdq *)(ptr-sizeof(struct memdq));    // check magic number in block to be freed    if(dq->next != dq->prev || dq->next != (struct memdq *)0xd530d53)        return -1;    return dq->size;    } // get_allocation_size()// -------------------------------------------------------------------------#endif // ifndef CYGONCE_KERNEL_MVARIMPL_INL// EOF mvarimpl.inl

⌨️ 快捷键说明

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