青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

2、多線程內存池

 

上一節很簡略的說了下單線程內存池,單線程內存池如果要放在多線程環境下使用是不安全的,我們需要進行保護,如何保護,最簡單的方法就是加臨界區,云風的實現里面是用原子操作模擬一個臨界區,我實測跟臨界區性能非常接近,甚至很多時候不如臨界區,所以我就不追求用原子操作模擬臨界區了,還是直接用臨界區最簡單。

 

class CMemPool

{

public:

        struct memory_list

        {

                memory_list *_next;

        };

        struct alloc_node

        {

                size_t _size;

                size_t _number;

                size_t _bksize;

                long _guard;

                memory_list *_free_list;

        };

        struct chunk_list

        {

                chunk_list *_next;

                memory_list *_data;

                size_t _size;

                size_t _idx;

        };

 

        ~CMemPool();

        static CMemPool &instance()

        {

                if(!_instance)

                {

                        create_instance();

                }

                return *_instance;

        }

        static int chunk_index(size_t size);

        void *allocate(size_t size, size_t *psize=NULL);

        void deallocate(void *p, size_t size);

 

        //以下為幾個檢測和設置預分配參數的函數,2007.06.08

        size_t getallocnumber(size_t size, size_t *psize=NULL);

        size_t setallocnumber(size_t size, size_t number);

        static void dumpallocnode();

 

private:

        static alloc_node _vnode[92];

 

        chunk_list *_chunk_list;

        long _chunk_guard;

 

        static CMemPool *_instance;

        static long _singleton_guard;

        static bool _singleton_destroyed;

        static void create_instance();

        static void build_chunknode();

 

        CMemPool();

        memory_list *alloc_chunk(size_t idx);

};

 

 

CMemPool *CMemPool::_instance = 0;

long CMemPool::_singleton_guard = 0;

bool CMemPool::_singleton_destroyed = false;

CMemPool::alloc_node CMemPool::_vnode[92];

 

struct chunk_desc

{

        int s;                // 區間起始字節

        int e;                // 區間終止字節

        int align; // 區間內分段對齊值

        int number;     // 區間內分段個數,計算屬性

}_cd[] =

{

        {0, 1024, 16, 0},

        {1024, 8192, 256, 0}

};

 

 

void CMemPool::create_instance()

{

        thread_guard guard(&_singleton_guard);

        if(_instance)

                return;

        assert(!_singleton_destroyed);

        static CMemPool obj;

        _instance = &obj;

}

 

void CMemPool::build_chunknode()

{

        const int cdnum = sizeof(_cd)/sizeof(_cd[0]);

        int index=0, number;

        for(int j=0; j<cdnum; j++)

        {

                _cd[j].number = (_cd[j].e-_cd[j].s)/_cd[j].align;

                for(int i=0; i<_cd[j].number; i++)

                {

                        int unitsize = (i+1)*_cd[j].align+_cd[j].s;

                        _vnode[index]._size = unitsize;

 

                        if(unitsize < 512)

                                number = 4096/unitsize;

                        else if(unitsize < 1024)

                                number = 16384/unitsize;

                        else

                                number = 65536/unitsize;

                        _vnode[index]._number = number;

                        _vnode[index]._bksize = unitsize * number;

                        _vnode[index]._guard = 0;

                        _vnode[index]._free_list = NULL;

                        ++index;

                }

        }

}

 

size_t CMemPool::getallocnumber(size_t size, size_t *psize/*=NULL*/)

{

        int idx = chunk_index(size);

        if(idx >= 0)

                return _vnode[idx]._number;

        return 0;

}

 

size_t CMemPool::setallocnumber(size_t size, size_t number)

{

        int idx = chunk_index(size);

        if(idx >= 0)

        {

                size_t on = _vnode[idx]._number;

                _vnode[idx]._number = number;

                return on;

        }

        return 0;

}

 

void CMemPool::dumpallocnode()

{

        int size = sizeof(_vnode)/sizeof(_vnode[0]);

        printf("_vnode.size = %d\r\n", size);

        for(int i=0; i<size; ++i)

        {

                printf("vnode.size %d, vnode.number %d\r\n", _vnode[i]._size, _vnode[i]._number);

        }

}

 

int CMemPool::chunk_index(size_t bytes)

{

#if(0)

        int idx = 0;

        const int cdnum = sizeof(_cd)/sizeof(_cd[0]);

 

        if(bytes > _cd[cdnum-1].e)

                idx = -1;

        else

        {

                for(int i=0; i<cdnum; i++)

                {

                        if((bytes > _cd[i].s) && (bytes <= _cd[i].e))

                        {

                                idx += (bytes-_cd[i].s+_cd[i].align-1)/_cd[i].align-1;

                                break;

                        }

                        idx += _cd[i].number;

                }

        }

//     printf("bytes %d idx = %d\r\n", bytes, idx);

        return idx;

#else

        //下面的代碼是根據靜態數據和上面的代碼做了優化的,

        //如果修改了基礎數據需要對應的修改下面的代碼

        if(bytes > 8192)

        {

                return -1;

        }

        else if(bytes > 1024)

        //     idx = _cd[0].number+(bytes-_cd[1].s+_cd[1].align-1)/_cd[1].align-1;

                return 64+(bytes-1024+255)/256-1;

        //     return _cd[0].number+(bytes-1024+255)/256-1;

        else

        //     idx = (bytes-_cd[0].s+_cd[0].align-1)/_cd[0].align-1;

                return (bytes+15)/16-1;

#endif

}

 

CMemPool::CMemPool()

{

        _chunk_list = NULL;

        _chunk_guard = 0;

        build_chunknode();

}

 

CMemPool::~CMemPool()

{

        int s = 0;

        chunk_list *temp = _chunk_list;

        while(temp)

        {

                ++s;

                temp = temp->_next;

        }

        void **chunk = reinterpret_cast<void **>(malloc(s * sizeof(void *)));

        temp = _chunk_list;

        int i=0;

        while(temp)

        {

                chunk[i] = temp->_data;

                ++i;

                temp = temp->_next;

        }

        for(i=0; i<s; i++)

        {

                free(chunk[i]);

        }

        free(chunk);

 

        _singleton_destroyed = true;

        _instance = 0;

}

 

CMemPool::memory_list *CMemPool::alloc_chunk(size_t idx)

{

        thread_guard guard(&_chunk_guard);

        memory_list *&current_list = _vnode[idx]._free_list;

        if(current_list)

                return current_list;

        const size_t node_size = _vnode[idx]._size;

        const size_t number     = _vnode[idx]._number;

        const size_t chunk_size = node_size * number;

        memory_list *ret = current_list = reinterpret_cast<memory_list *>(malloc(chunk_size));

        memory_list *iter = ret;

        //for(size_t i=0; i<=chunk_size-node_size*2; i+=node_size)

        for(size_t i=0; i<number-1; ++i)

        {

                iter = iter->_next = iter+node_size/sizeof(*iter);

        }

        iter->_next = 0;

 

        return ret;

}

 

void *CMemPool::allocate(size_t size, size_t *psize/*=NULL*/)

{

        int idx = chunk_index(size);

        if(idx < 0)

        {

                if(psize) *psize = size;

                return malloc(size);

        }

        if(psize)

                *psize = _vnode[idx]._size;

 

        thread_guard guard(&_vnode[idx]._guard);

        memory_list *&temp = _vnode[idx]._free_list;

 

        if(!temp)

        {

                memory_list *new_chunk = alloc_chunk(idx);

 

                chunk_list *chunk_node;

                if(chunk_index(sizeof(chunk_list))==idx)

                {

                        chunk_node = reinterpret_cast<chunk_list *>(temp);

                        temp = temp->_next;

                }

                else

                {

                        chunk_node = reinterpret_cast<chunk_list *>(allocate(sizeof(chunk_list)));

                }

 

                thread_guard guard(&_chunk_guard);

                chunk_node->_next = _chunk_list;

                chunk_node->_data = new_chunk;

                chunk_node->_size = _vnode[idx]._bksize;

                chunk_node->_idx = idx;

                _chunk_list = chunk_node;

        }

        void *ret = temp;

        temp = temp->_next;

 

        return ret;

}

 

void CMemPool::deallocate(void *p, size_t size)

{

        int idx = chunk_index(size);

        if(idx < 0)

        {

                free(p);

        }

        else

        {

                memory_list *free_block = reinterpret_cast<memory_list *>(p);

                thread_guard guard(&_vnode[idx]._guard);

               

                memory_list *&temp = _vnode[idx]._free_list;     //_free_list[idx];

                free_block->_next = temp;

                temp = free_block;

        }

}

 

以上基本是云風內存池的一個簡單修改版,這種模式的內存池由于每次分配釋放都要lock unlock,所以效率很低,大概只相當于malloc/free 2-4倍的速度,提速也不是很明顯,大概相當于nedmalloc速度的一半左右。

發表于 @ 2010年02月04日 16:54:00 | 評論( 0 ) | 編輯| 舉報| 收藏

舊一篇:單線程內存池 | 新一篇:dlmalloc、nedmalloc

  • 發表評論
  • 表 情:
  • 評論內容:
  •  
Posted on 2010-10-03 13:52 袁斌 閱讀(827) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品九九| 美日韩精品视频| 国产亚洲aⅴaaaaaa毛片| 欧美色中文字幕| 欧美日韩精品欧美日韩精品一| 嫩模写真一区二区三区三州| 久久综合99re88久久爱| 久久视频一区| 欧美国产视频日韩| 欧美日韩成人免费| 国产精品久久毛片a| 国产精品最新自拍| 国产一区免费视频| 在线欧美影院| 亚洲精品在线观看免费| 一区二区高清| 羞羞答答国产精品www一本| 久久精品夜色噜噜亚洲a∨ | 亚洲黄色精品| 亚洲国产婷婷香蕉久久久久久| 亚洲精品日韩在线| 中文av一区二区| 欧美一区在线视频| 欧美xxx成人| 国产精品免费网站| 1024国产精品| 亚洲欧美综合v| 暖暖成人免费视频| 一区二区欧美激情| 玖玖玖国产精品| 国产精品剧情在线亚洲| 亚洲电影在线免费观看| 日韩小视频在线观看| 巨乳诱惑日韩免费av| 欧美国产视频在线| 午夜一区二区三区不卡视频| 欧美国产日韩一区二区三区| 国产区二精品视| 亚洲精品美女久久7777777| 亚洲欧美色婷婷| 亚洲高清视频在线| 久久精品国产v日韩v亚洲| 亚洲第一精品夜夜躁人人躁 | 欧美一区影院| 国产精品成人一区二区艾草| 在线国产亚洲欧美| 亚洲欧美日韩国产精品| 欧美成人精品1314www| 亚洲欧美中文另类| 欧美日韩一区二区在线观看视频| 国内精品久久久久影院 日本资源| av成人毛片| 欧美aa国产视频| 久久精品视频免费播放| 韩国福利一区| 老鸭窝亚洲一区二区三区| 性久久久久久久久久久久| 国产欧美精品一区二区三区介绍| 午夜精品在线| 亚洲欧美日韩国产综合| 国产亚洲毛片在线| 久久综合国产精品| 美女精品国产| 99re6热只有精品免费观看| 亚洲日本激情| 欧美亚一区二区| 午夜精品久久久久久久99水蜜桃| 中文精品在线| 国产精品一区二区视频| 久久精品噜噜噜成人av农村| 午夜精品久久久久久久99水蜜桃| 欧美午夜一区| 午夜日韩福利| 久久精品99无色码中文字幕 | 国产一级久久| 亚洲一级片在线观看| 亚洲伊人一本大道中文字幕| 日韩视频在线观看一区二区| 亚洲一区在线视频| 久久网站免费| 国产精品五区| 亚洲一区999| 宅男精品视频| 欧美电影免费观看| 亚洲免费成人av电影| 夜夜嗨av一区二区三区网站四季av | 欧美亚洲免费高清在线观看| 亚洲国产精品专区久久| 亚洲视频大全| 欧美国产一区在线| 亚洲精品中文在线| 亚洲人www| 欧美日韩欧美一区二区| 99精品视频网| 日韩网站免费观看| 欧美视频精品在线| 亚洲欧美视频在线观看视频| 久久中文久久字幕| 欧美一区二区免费视频| 国产婷婷精品| 你懂的国产精品永久在线| 久久字幕精品一区| 亚洲欧洲一区二区在线观看| 最新国产の精品合集bt伙计| 欧美www在线| 99视频一区| 亚洲性视频h| 国产一区二区三区奇米久涩 | 伊人久久大香线蕉综合热线| 欧美黄色日本| 欧美精品在线免费播放| 亚洲精品乱码久久久久久| 亚洲精品国产精品国自产在线| 欧美体内she精视频| 香蕉久久a毛片| 久久国产精品色婷婷| 国产精品一区毛片| 一区二区三区日韩精品视频| 99精品欧美一区二区三区综合在线| 欧美日韩一区二区三区| 亚洲综合精品四区| 久久国产精品99久久久久久老狼| 亚洲丰满在线| 亚洲人成人77777线观看| 久久精品国产亚洲高清剧情介绍| 国产亚洲一级高清| 亚洲国产成人久久综合一区| 国产精品高潮呻吟| 男女av一区三区二区色多| 欧美日韩免费在线| 久久野战av| 欧美午夜欧美| 欧美成在线视频| 欧美日韩国产123| 久久综合亚洲社区| 国产精品久久久久久久久动漫| 欧美mv日韩mv国产网站| 国产精品三级视频| 亚洲黄色免费电影| 在线视频亚洲欧美| 亚洲欧美日韩一区二区在线 | 亚洲欧美久久久| 亚洲国产欧美一区二区三区久久 | 亚洲午夜激情网站| 你懂的亚洲视频| 久久久午夜精品| 国产精品亚发布| 久久久亚洲欧洲日产国码αv| 国产一区二区在线观看免费| 亚洲激情啪啪| 在线观看日韩一区| 久久岛国电影| 欧美高清一区| 亚洲高清三级视频| 欧美综合第一页| 亚洲一区日韩在线| 欧美激情亚洲国产| 亚洲国产一区二区视频 | 一区二区三区色| 欧美激情精品久久久| 欧美成人嫩草网站| 国内精品一区二区三区| 亚洲一区成人| 欧美一区二区三区在| 国产精品人人爽人人做我的可爱| 日韩视频在线一区二区三区| 日韩午夜av| 欧美久久99| 一本高清dvd不卡在线观看| 一本色道久久88综合亚洲精品ⅰ| 欧美高清你懂得| 亚洲精品黄色| 99国产精品久久久久老师| 欧美另类久久久品| 一区二区三区国产在线| 亚洲免费中文| 国产日本精品| 久久久综合精品| 亚洲福利一区| 一二三区精品福利视频| 国产精品成人一区二区三区吃奶| 国产精品99久久久久久久久久久久| 亚洲——在线| 国产亚洲一区二区三区| 亚洲一区视频| 蜜臀av在线播放一区二区三区| 亚洲国产精品久久久久婷婷884 | 欧美体内she精视频在线观看| 一区二区三区欧美在线| 亚洲视频网站在线观看| 国产精品色午夜在线观看| 午夜视黄欧洲亚洲| 米奇777超碰欧美日韩亚洲| 亚洲精品免费在线观看| 一区二区三区视频观看| 亚洲电影免费观看高清| 欧美视频中文在线看 | 香蕉久久夜色| 亚洲第一主播视频| 久久免费视频网|