• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            無我

            讓內(nèi)心永遠燃燒著偉大的光明的精神之火!
            靈活的思考,嚴(yán)謹(jǐn)?shù)膶崿F(xiàn)
            豪邁的氣魄、頑強的意志和周全的思考

            eSNACC的C運行時庫動態(tài)內(nèi)存管理

            本文研究eSNACC的C運行時庫動態(tài)內(nèi)存管理。

            eSNACC的運行時庫和代碼生成用的內(nèi)存管理函數(shù)用的是統(tǒng)一的宏定義原型,但是支持用戶自己配置內(nèi)存管理方案。eSNACC本身提供兩種內(nèi)存管理方案:

            一個是mem.h/c定義的直接分配;另一個是nibble-alloc.h/c定義的Nibble memory系統(tǒng)。

            對內(nèi)存管理的配置在asn-config.h中,現(xiàn)在代碼如下:

            #ifdef USE_NIBBLE_MEMORY

            #include 
            "nibble-alloc.h"

            #define Asn1Alloc( size)        NibbleAlloc (size)
            #define Asn1Free( ptr)            /* empty */
            #define CheckAsn1Alloc( ptr, env)    \
                
            if ((ptr) == NULL)\
                  longjmp (env, 
            -27)

            #else /* !USE_NIBBLE_MEMORY */

            #include 
            "mem.h"

            #define Asn1Alloc( size)        Malloc (size)
            #define Asn1Free( ptr)            Free (ptr)
            #define CheckAsn1Alloc( ptr, env)    \
                
            if ((ptr) == NULL)\
                  longjmp (env, 
            -27)

            #endif /* USE_NIBBLE_MEMORY */

            其中,eSNACC默認(rèn)使用nibble memory.要記住的是:解碼器始終認(rèn)為Asn1Alloc得到的內(nèi)存一定是用0初始化好的!如果我們實現(xiàn)自己的內(nèi)存方案,一定要記得這一點。

             

            我們先來看看mem.h/c中的實現(xiàn):

            #ifdef __cplusplus
            extern "C" {
            #endif

            void    *Malloc PROTO ((int size));
            void    *Realloc PROTO ((void *ptr, int newsize));
            void    Free PROTO ((void *ptr));

            /* malloc type */
            #define MT( type)    (type *)Malloc (sizeof (type))


            #ifdef __cplusplus
            }

            #endif

            實現(xiàn)如下:

            #include "mem.h"
            #include 
            <memory.h>

            void* Malloc PARAMS ((size), int size)
            {
                
            void *retVal = malloc (size);

                
            if (retVal == NULL)
                
            {
                    fprintf (stderr, 
            "out of memory! bye!\n");
                    fprintf (stderr, 
            "tried to allocate %d byes\n", size);
                    exit (
            1);
                }


                memzero (retVal, size);
                
            return retVal;

            }
              /* Malloc */

            void *Realloc PARAMS ((ptr, newsize),
                
            void *ptr _AND_
                
            int newsize)
            {
                
            void *retval = realloc (ptr, newsize);

                
            if (retval == NULL)
                
            {
                    fprintf (stderr, 
            "out of memory! bye!\n");
                    fprintf (stderr, 
            "tried to reallocate %d byes\n", newsize);
                    exit (
            1);
                }


                
            return retval;
            }


            void Free PARAMS ((ptr),
                
            void *ptr)
            {
                free (ptr);
            }
            相當(dāng)簡單,只是別忘了,在malloc之后,要先memzero再返回。

             

            然后我們再來研究一下nibble memory:

            #ifdef __cplusplus
            extern "C" {
            #endif

                typedef 
            struct NibbleBuf
                
            {
                    
            char *start;
                    
            char *end;
                    
            char *curr;
                    
            struct NibbleBuf *next;
                }
             NibbleBuf;

                typedef 
            struct NibbleMem
                
            {
                    NibbleBuf 
            *firstNibbleBuf;
                    NibbleBuf 
            *currNibbleBuf;
                    unsigned 
            long incrementSize;
                }
             NibbleMem;

                
            void InitNibbleMem PROTO ((unsigned long initialSize, unsigned long incrementSize));

                
            void ShutdownNibbleMem();

                
            void ServiceNibbleFault PROTO ((unsigned long size));

                
            void *NibbleAlloc PROTO ((unsigned long size));

                
            void ResetNibbleMem();


            #ifdef __cplusplus
            }

            #endif

             

            #include <malloc.h>
            #include 
            <string.h>
            #include 
            "asn-config.h"
            #include 
            "nibble-alloc.h"


            NibbleMem 
            *nmG = NULL;

            void InitNibbleMem PARAMS ((initialSize, incrementSize),
                unsigned 
            long initialSize _AND_
                unsigned 
            long incrementSize)
            {
                NibbleMem 
            *nm;

                nm 
            = (NibbleMem*) malloc (sizeof (NibbleMem));
                nm
            ->incrementSize = incrementSize;

                nm
            ->currNibbleBuf = nm->firstNibbleBuf = (NibbleBuf*)malloc (sizeof (NibbleBuf));
                nm
            ->firstNibbleBuf->curr = nm->firstNibbleBuf->start = (char*) malloc (initialSize);
                nm
            ->firstNibbleBuf->end = nm->firstNibbleBuf->start + initialSize;
                nm
            ->firstNibbleBuf->next = NULL;
                memzero (nm
            ->currNibbleBuf->start, initialSize);

                nmG 
            = nm;/* set global */

            }
              /* InitNibbleAlloc */


            /*
             * alloc new nibble buf, link in, reset to curr nibble buf
             
            */

            void ServiceNibbleFault PARAMS ((size),
                unsigned 
            long size)
            {
                NibbleMem 
            *nm;
                unsigned 
            long newBufSize;

                nm 
            = nmG;

                
            if (size > nm->incrementSize)
                    newBufSize 
            = size;
                
            else
                    newBufSize 
            = nm->incrementSize;

                nm
            ->currNibbleBuf->next = (NibbleBuf*) malloc (sizeof (NibbleBuf));
                nm
            ->currNibbleBuf = nm->currNibbleBuf->next;
                nm
            ->currNibbleBuf->curr = nm->currNibbleBuf->start = (char*) malloc (newBufSize);
                nm
            ->currNibbleBuf->end = nm->currNibbleBuf->start + newBufSize;
                nm
            ->currNibbleBuf->next = NULL;
                memzero (nm
            ->currNibbleBuf->start, newBufSize);
            }
             /* serviceNibbleFault */


            /*
             * returns requested space filled with zeros
             
            */

            void* NibbleAlloc PARAMS ((size),
                unsigned 
            long size)
            {
                NibbleMem 
            *nm;
                
            char *retVal;
                unsigned 
            long ndiff;

                nm 
            = nmG;
                
                
            /* DAD - although error checking on the mallocs during
                 * ServiceNibbleFault could be more robust, for now i'm
                 * just going to avoid allocating really huge amounts
                 * of memory (which can occur if the ASN.1 data has
                 * become corrupted, and you were trying to decode).
                 
            */

                
            if(size > 1024*1024)    /* say roughly a meg for now */
                    
            return(0);

                
            if ((nm->currNibbleBuf->end - nm->currNibbleBuf->curr) < (int)size)
                     ServiceNibbleFault (size);

                retVal 
            = nm->currNibbleBuf->curr;

                
            /*
                 * maintain word alignment
                 
            */

                ndiff 
            = size % sizeof (long);
                
            if (ndiff != 0)
                
            {
                    nm
            ->currNibbleBuf->curr += size + sizeof (long- ndiff;

                    
            /*
                     * this is a fix from Terry Sullivan <FCLTPS@nervm.nerdc.ufl.edu>
                     *
                     * makes sure curr does not go past the end ptr
                     
            */

                    
            if (nm->currNibbleBuf->curr > nm->currNibbleBuf->end)
                        nm
            ->currNibbleBuf->curr = nm->currNibbleBuf->end;
                }

                
            else
                    nm
            ->currNibbleBuf->curr += size;

                
            return retVal;
            }
              /* NibbleAlloc */



            /*
             * frees all nibble buffers except the first,
             * resets the first to empty and zero's it
             
            */

            void ResetNibbleMem()
            {
                NibbleMem 
            *nm;
                NibbleBuf 
            *tmp;
                NibbleBuf 
            *nextTmp;

                nm 
            = nmG;

                
            /*
                 * reset first nibble buf
                 
            */

                memzero (nm
            ->firstNibbleBuf->start, nm->firstNibbleBuf->curr - nm->firstNibbleBuf->start);

                nm
            ->firstNibbleBuf->curr = nm->firstNibbleBuf->start;

                
            /*
                 * free incrementally added nibble bufs
                 
            */

                
            for (tmp = nm->firstNibbleBuf->next; tmp != NULL; )
                
            {
                    free (tmp
            ->start);
                    nextTmp 
            = tmp->next;
                    free (tmp);
                    tmp 
            = nextTmp;
                }


                
            /* From ftp://ftp.cs.ubc.ca/pub/local/src/snacc/bugs-in-1.1 */
                nm
            ->firstNibbleBuf->next = NULL;
                nm
            ->currNibbleBuf = nm->firstNibbleBuf;

            }
             /* ResetNibbleMem */

            /*
             * frees all nibble buffers, closing this
             * NibbleMem completely
             
            */

            void ShutdownNibbleMem()
            {
                NibbleMem 
            *nm;
                NibbleBuf 
            *tmp;
                NibbleBuf 
            *nextTmp;

                nm 
            = nmG;
                nmG 
            = NULL;
                
            /*
                 * free nibble bufs
                 
            */

                
            if (nm == NULL)
                    
            return;
                
            for (tmp = nm->firstNibbleBuf; tmp != NULL; )
                
            {
                    free (tmp
            ->start);
                    nextTmp 
            = tmp->next;
                    free (tmp);
                    tmp 
            = nextTmp;
                }


                free (nm);
            }
             /* ShutdownNibbleMem */

            這些代碼都比較簡單,而且都基本有注釋,所以就不多具體說了。只是對nibble memory方案的幾個注意點說一下:

            1、如果使用nibble memory,那么在做任何編碼解碼操作之前,需要調(diào)用InitNibbleMem函數(shù)以初始化全局變量。

            2、在程序最后,調(diào)用ShutdownNibbleMem銷毀nibble內(nèi)存。

            3、nibble memory在申請了內(nèi)存塊之后無法釋放指定塊,也就是一直占用著,哪怕那塊數(shù)據(jù)也就不用了,除非Reset或者Shutdown,是不是考慮Asn.1解碼時分配臨時內(nèi)存不多?

            4、正如3中所說,其實nibble memory的效率主要來自于兩方面:一是一次分配一塊大內(nèi)存來減少malloc;另外就是免除了free操作。不過對后者,個人感覺限制太死,會不會導(dǎo)致占用內(nèi)存太多?

             

            好了,eSNACC的內(nèi)存方案就是這些了。如果你對這些都不滿意,可以很方便的修改asn-config.h來配置自己的方案。

             

             

            posted on 2012-04-27 15:42 Tim 閱讀(442) 評論(0)  編輯 收藏 引用 所屬分類: eSNACC學(xué)習(xí)

            <2008年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            導(dǎo)航

            統(tǒng)計

            公告

            本博客原創(chuàng)文章,歡迎轉(zhuǎn)載和交流。不過請注明以下信息:
            作者:TimWu
            郵箱:timfly@yeah.net
            來源:www.shnenglu.com/Tim
            感謝您對我的支持!

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            久久精品无码一区二区日韩AV| 无码精品久久一区二区三区| 久久精品国产亚洲AV无码麻豆 | 无码超乳爆乳中文字幕久久| 日日噜噜夜夜狠狠久久丁香五月| 久久久久亚洲AV片无码下载蜜桃| 国内精品久久久久影院优| 一本大道加勒比久久综合| 亚洲伊人久久成综合人影院| 欧美牲交A欧牲交aⅴ久久| 国产免费久久精品99久久| 亚洲天堂久久久| 国产精品99久久久久久人| 久久久久久青草大香综合精品| 亚洲狠狠婷婷综合久久蜜芽| 91麻豆精品国产91久久久久久| 久久人人爽人人爽人人片AV不| 97久久精品无码一区二区天美 | 久久久中文字幕日本| 国产偷久久久精品专区 | 久久久精品午夜免费不卡| 中文字幕精品无码久久久久久3D日动漫 | 香蕉久久夜色精品国产小说| 久久笫一福利免费导航 | 99久久精品这里只有精品| 综合人妻久久一区二区精品| 日本精品久久久中文字幕| 午夜人妻久久久久久久久| 九九久久精品无码专区| 2021少妇久久久久久久久久| 99久久国产亚洲综合精品| 精品国产乱码久久久久久浪潮| 久久精品99久久香蕉国产色戒 | 亚洲精品无码久久毛片| 大伊人青草狠狠久久| 亚洲狠狠婷婷综合久久久久| 久久精品国产精品亜洲毛片| 青青青青久久精品国产 | 少妇久久久久久被弄到高潮| 精品久久香蕉国产线看观看亚洲 | 伊人久久大香线蕉精品|