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

📄 heap.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
HEAPNODE   * volatile * npp;HEAPNODE              * fnode;#ifdef DO_CRITICAL    NutEnterCritical( );#endif#ifdef NUTDEBUG    if ( block == 0 )    {        NutPrintString_P( log_dev, PSTR( "\r\nMEMnull" ) );#ifdef DO_CRITICAL        NutExitCritical( );#endif        return -1;    }#endif    /*     * Convert our block into a node.     */    fnode = (HEAPNODE *)( (u_char *)block - HEAP_HEAD_SIZE );    CheckHeapGuards( fnode, PSTR( "free" ) );#ifdef NUTDEBUG    if ( heap_trace != 0 )        NutPrintFormat_P( log_dev, PSTR( "F(%d,%x) " ), fnode->hn_size, (u_short)block );#endif    available += fnode->hn_size;#ifdef USED_HEAP_LIST    RemoveFromUsedList( fnode );#endif    /*     * Walk through the linked list of free nodes and try     * to link us in.     */    node =  heapFreeList;    npp  = &heapFreeList;    while ( node != 0 )    {        /*         * If there' s a free node in front of us, merge it.         */        if ( ( (u_short)node + node->hn_size ) == (u_short)fnode )        {            CheckHeapGuards( node, PSTR( "prev" ) );            node->hn_size += fnode->hn_size;            /*             * If a free node is following us, merge it.             */            if ( ( (u_short)node + node->hn_size ) == (u_short)node->hn_next )            {                CheckHeapGuards( node->hn_next, PSTR( "next" ) );                node->hn_size += node->hn_next->hn_size;                node->hn_next  = node->hn_next->hn_next;            }            AddHeapGuards( node );            break;        }        /*         * If we walked past our address, link us to the list.         */        if ( (u_short)node > (u_short)fnode )        {            *npp = fnode;            /*             * If a free node is following us, merge it.             */            if ( ( (u_short)fnode + fnode->hn_size ) == (u_short)node )            {                fnode->hn_size += node->hn_size;                fnode->hn_next  = node->hn_next;            }            else                fnode->hn_next = node;            break;        }        /*         * If we are within a free node, somebody tried         * to free a block twice.         */        if ( ( (u_short)node + node->hn_size) > (u_short)fnode )        {#ifdef NUTDEBUG            if ( heap_trace != 0 )                NutPrintString_P( log_dev, PSTR( "\r\nTWICE\r\n" ) );#endif#ifdef DO_CRITICAL            NutExitCritical( );#endif            return -1;        }        npp  = &node->hn_next;        node =  node->hn_next;    }    /*     * If no link was found, put us at the end of the list     */    if ( node == 0 )    {        fnode->hn_next = node;        *npp = fnode;    }#ifdef DO_CRITICAL    NutExitCritical( );#endif    return 0;}//--------------------------------------------------------------------------///*! * \brief * Add a new memory region to the free heap. * * This function is automatically called by Nut/OS during * initialization. * * Applications typically do not call this function. * * \param addr Start address of the memory region. * \param size Number of bytes of the memory region. */void NutHeapAdd( void * addr, u_short size ){HEAPNODE      * p_node;    p_node = (HEAPNODE *)addr;#ifdef DO_CRITICAL    NutEnterCritical( );#endif    //  Pretend this is a clean block so no errors appear.    p_node->hn_size = size;    AddHeapGuards( p_node );#ifdef USED_HEAP_LIST    InsertInUsedList( p_node );#else    p_node->hn_next = 0;#endif#ifdef DO_CRITICAL    NutExitCritical( );#endif    NutHeapFree( (void *)( (char *)addr + HEAP_HEAD_SIZE ) );}//--------------------------------------------------------------------------///*! * \brief Return the number of bytes available. * * \return Number of bytes. */u_short NutHeapAvailable( void ){    return available;}//--------------------------------------------------------------------------//u_char NutHeapCheckGuards1( void * block ){    return NutHeapCheckGuards2( (HEAPNODE *)( (char *)block - HEAP_HEAD_SIZE ) );}//--------------------------------------------------------------------------//u_char NutHeapCheckGuards2( HEAPNODE * p_node ){u_char          ret     =   0;#ifdef FRONT_GUARDED_HEAP    if ( p_node->hn_guard != deadmeat )        ret = 2;#endif    if ( ( (HEAPTAIL *)( (char *)p_node + p_node->hn_size - HEAP_TAIL_SIZE ) )->ht_guard != deadmeat )        ret += 1;    return ret;}//--------------------------------------------------------------------------//static void AddHeapGuards( HEAPNODE * p_node ){#ifdef FRONT_GUARDED_HEAP    p_node->hn_guard = deadmeat;#endif    ( (HEAPTAIL *)( (char *)p_node + p_node->hn_size - HEAP_TAIL_SIZE ) )->ht_guard = deadmeat;}//--------------------------------------------------------------------------//static u_char CheckHeapGuards( HEAPNODE * p_node, PGM_P str ){HEAPTAIL      * p_tail;u_char          ret     =   0;int             slime;#ifdef NUTDEBUGchar            temp[ 20 ];#endif#ifdef FRONT_GUARDED_HEAP    if ( p_node->hn_guard != deadmeat )    {        ret = 2;        //  determine how many bytes got slimed.        if ( ( p_node->hn_guard & slime_1 ) == ( deadmeat & slime_1 ) )            slime = 1;        else        {            if ( ( p_node->hn_guard & slime_2 ) == ( deadmeat & slime_2 ) )                slime = 2;            else            {                if ( ( p_node->hn_guard & slime_3 ) == ( deadmeat & slime_3 ) )                    slime = 3;                else                    slime = 4;            }        }#ifdef NUTDEBUG	/* This will not work on ICCAVR */        strncpy_P( temp, str, 19 );        NutPrintFormat( 0, "\r\nMEMCORRUPT-%s-%d-%d\r\n",                                            temp, p_node->hn_size, slime );#endif    }#endif    p_tail = (HEAPTAIL *)( (char *)p_node + p_node->hn_size - HEAP_TAIL_SIZE );    if ( p_tail->ht_guard != deadmeat )    {        ret += 1;        //  determine how many bytes got slimed.        if ( ( p_tail->ht_guard & slime_1 ) == ( deadmeat & slime_1 ) )            slime = 1;        else        {            if ( ( p_tail->ht_guard & slime_2 ) == ( deadmeat & slime_2 ) )                slime = 2;            else            {                if ( ( p_tail->ht_guard & slime_3 ) == ( deadmeat & slime_3 ) )                    slime = 3;                else                    slime = 4;            }        }#ifdef NUTDEBUG	/* This will not work on ICCAVR */        strncpy_P( temp, str, 19 );        NutPrintFormat( log_dev, "\r\nMemCorrupt-%s-%d-%d\r\n",                                            temp, p_node->hn_size, slime );#endif    }    return ret;}//--------------------------------------------------------------------------//#ifdef USED_HEAP_LISTstatic void InsertInUsedList( HEAPNODE *p_node ){HEAPNODE              * p_used;HEAPNODE   * volatile * pp_prev;    p_used  =  heapUsedList;    pp_prev = &heapUsedList;    while ( p_used != 0 )    {        if ( p_used->hn_next > p_node )        {            p_node->hn_next = ( *pp_prev )->hn_next;            ( *pp_prev )->hn_next = p_node;            break;        }        pp_prev = &p_used->hn_next;        p_used  =  p_used->hn_next;    }    if ( p_used == 0 )    {        p_node->hn_next = heapUsedList;        heapUsedList = p_node;    }}#endif//--------------------------------------------------------------------------//#ifdef USED_HEAP_LISTstatic void RemoveFromUsedList( HEAPNODE *p_node ){HEAPNODE   * volatile * pp_used;    pp_used = &heapUsedList;    while ( *pp_used != 0 )    {        if ( *pp_used == p_node )        {            *pp_used = ( *pp_used )->hn_next;            break;        }        pp_used = &( *pp_used )->hn_next;    }#ifdef NUTDEBUG    if ( *pp_used == 0 )        NutPrintString( log_dev, "\r\nMemCorrupt-used\r\n" );#endif}#endif/*@}*///*************************** end of file HEAP.C ***************************//

⌨️ 快捷键说明

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