• <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 閱讀(450) 評論(0)  編輯 收藏 引用 所屬分類: eSNACC學習

            <2007年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導航

            統計

            公告

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

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            国产激情久久久久影院小草 | 国内精品久久久久影院亚洲| 青青国产成人久久91网| 99久久精品免费看国产| 久久这里只有精品首页| 久久成人18免费网站| 久久人人爽人人爽人人爽| 色偷偷偷久久伊人大杳蕉| 国产精品成人久久久久三级午夜电影| 精品国产综合区久久久久久| 久久综合色老色| 青青青青久久精品国产| 久久综合九色综合网站| 91视频国产91久久久| 久久久久一本毛久久久| 久久精品国产99久久久| 久久天天躁狠狠躁夜夜av浪潮| 久久国产亚洲高清观看| 成人综合久久精品色婷婷| 99久久国产综合精品五月天喷水 | 99热精品久久只有精品| 久久人妻少妇嫩草AV蜜桃| 精品99久久aaa一级毛片| 欧美熟妇另类久久久久久不卡 | 亚洲日本久久久午夜精品| 精品久久久久久| 人妻无码αv中文字幕久久琪琪布| 久久夜色精品国产www| 久久中文娱乐网| 九九久久99综合一区二区| 亚洲va中文字幕无码久久| 一日本道伊人久久综合影| 一本久久a久久精品综合夜夜| 国产精品久久久久久一区二区三区| 久久久久久国产精品美女| 色妞色综合久久夜夜| 亚洲日韩欧美一区久久久久我| 久久国产美女免费观看精品| 久久青草国产手机看片福利盒子| 国产Av激情久久无码天堂| 色诱久久久久综合网ywww|