• <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>

            無我

            讓內心永遠燃燒著偉大的光明的精神之火!
            靈活的思考,嚴謹的實現
            豪邁的氣魄、頑強的意志和周全的思考

            eSNACC的C運行時庫動態內存管理

            本文研究eSNACC的C運行時庫動態內存管理。

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

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

            對內存管理的配置在asn-config.h中,現在代碼如下:

            #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默認使用nibble memory.要記住的是:解碼器始終認為Asn1Alloc得到的內存一定是用0初始化好的!如果我們實現自己的內存方案,一定要記得這一點。

             

            我們先來看看mem.h/c中的實現:

            #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

            實現如下:

            #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);
            }
            相當簡單,只是別忘了,在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,那么在做任何編碼解碼操作之前,需要調用InitNibbleMem函數以初始化全局變量。

            2、在程序最后,調用ShutdownNibbleMem銷毀nibble內存。

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

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

             

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

             

             

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

            <2012年4月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            導航

            統計

            公告

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

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            亚洲精品高清国产一久久| 国产精品久久久久久久| 亚洲国产日韩综合久久精品| 久久久www免费人成精品| 国产精品久久波多野结衣| 久久亚洲2019中文字幕| 久久精品蜜芽亚洲国产AV| 国产精自产拍久久久久久蜜| 午夜精品久久久久久毛片| 99久久国产综合精品网成人影院| 久久无码国产专区精品| 国产精自产拍久久久久久蜜| jizzjizz国产精品久久| 色天使久久综合网天天| 久久er国产精品免费观看8| 久久婷婷五月综合国产尤物app| 久久久久无码精品国产app| 国产精品99精品久久免费| 97精品伊人久久久大香线蕉| 久久精品成人| 国产精品伊人久久伊人电影| 久久精品国产99国产精偷| 久久久久久亚洲精品成人| 99精品久久久久久久婷婷| 久久婷婷国产剧情内射白浆| 久久精品国产亚洲av瑜伽| 国产激情久久久久影院老熟女| 久久水蜜桃亚洲av无码精品麻豆| 中文字幕久久亚洲一区| 99久久国产亚洲综合精品| 久久这里的只有是精品23| 武侠古典久久婷婷狼人伊人| 久久亚洲电影| 一本久道久久综合狠狠躁AV| 污污内射久久一区二区欧美日韩 | 区久久AAA片69亚洲| 亚洲日韩欧美一区久久久久我| 欧美精品丝袜久久久中文字幕 | 久久精品成人国产午夜| 久久国产精品-久久精品| 狠狠干狠狠久久|