您的位置:首页 > 其它

一个简单的内存池,源码贡献

2009-08-03 09:07 609 查看
头文件

#ifndef MY_MEMPOOL_H

#define MY_MEMPOOL_H

#define MY_MPN_B namespace my_mempool{

#define MY_MPN_E }

#define DECLARE_MY_MEMPOOL using namespace ::my_mempool;

#include <string>

#include <map>

#include <vector>

using namespace ::std;

MY_MPN_B

/**

* /ingroup my_memorypool

* CMPBase,base class ,non copyable.

*

* /par requirements

* win98 or later/n

* win2k or later/n

* MFC/n

*

* /version 1.0

* first version

*

* /date 2009-06-03

*

* /author Jason

*

* /par license

* This code is absolutely free to use and modify. The code is provided "as is" with

* no expressed or implied warranty. The author accepts no liability if it causes

* any damage to your computer, causes your pet to fall ill, increases baldness

* or makes your car start emitting strange noises when you start it up.

* This code has no bugs, just undocumented features!

*

* /todo

*

* /bug

*

*/

class CMPBase

{

private:

CMPBase(const CMPBase &){}

CMPBase & operator = (const CMPBase &){return *this;}

public:

CMPBase(){}

virtual ~CMPBase() = 0;

protected:

int round_up(int size);

public:

/**

* 追加一块内存

* /param size

* 追加内存的大小

* /return

* 返回追加的内存实际大小

*/

virtual int append(int size) = 0;

virtual void reap(void) = 0;

/**

* 计算总空间

* /param void

* /return

*/

virtual int space_(void) = 0;

/**

* 计算分配了多少空间

* /param void

* /return

*/

virtual int malloced(void) = 0;

/**

* 计算剩余空间

* /param void

* /return

*/

virtual int freememory(void) = 0;

/**

* malloc memory,same to stardard c malloc function

* /param size

*/

virtual void * malloc(int size) = 0;

/**

* free memory

* /param mp

*/

virtual void free(void * mp) = 0;

virtual void dump(const string & file) {};

};

/**

* /ingroup my_memorypool

* class CMapMemoryPool

* 简单实现

* /par requirements

* win98 or later/n

* win2k or later/n

* MFC/n

*

* /version 1.0

* first version

*

* /date 2009-06-04

*

* /author Jason

*

* /par license

* This code is absolutely free to use and modify. The code is provided "as is" with

* no expressed or implied warranty. The author accepts no liability if it causes

* any damage to your computer, causes your pet to fall ill, increases baldness

* or makes your car start emitting strange noises when you start it up.

* This code has no bugs, just undocumented features!

*

* /todo

*

* /bug

*

*/

class CMapMemoryPool : public CMPBase

{

enum{DEFAULTSIZE = 2 * 1024 * 1024};

bool initialized;

public:

CMapMemoryPool();

CMapMemoryPool(const int & size);

virtual ~CMapMemoryPool();

//尽量大些

virtual int append(int size);

virtual void reap(void);

virtual int space_(void){ return malloced() + freememory();}

virtual int malloced(void);

virtual int freememory(void);

virtual void * malloc(int size);

virtual void free(void * mp);

virtual void dump(const string & file);

private:

enum { mbMed = 0x00, mbHeader = 0x01, mbTail = 0x02};

struct mem_control_block

{

int is_available;

int flag;//mbHeader,mbMed,mbTail

int size;

int blockcounter;

};

// pointer , memory control block pointer

map<unsigned int,unsigned int> free_memory;

map<unsigned int,unsigned int> malloced_memory;

typedef map<unsigned int,unsigned int> map_type;

typedef pair<const unsigned int, unsigned int> map_it;

int count_space(const map_type & m);

//void realign_right(const unsigned int & pointer);

//void realign_left(const unsigned int & pointer);

class CSimpleCount

{

public:

CSimpleCount()

:count(0)

{}

void operator()(const map_it & t)

{

mem_control_block * p = (mem_control_block *)(t.second);

if(p)

count += p->size;

}

int Count(void)

{

return count;

}

private:

int count;

};

struct temZone

{

void * buf;

int size;

temZone()

:buf(0),size(0)

{

;

}

temZone(void * b,int s)

:buf(b),size(s)

{

;

}

temZone(const temZone& t)

:buf(t.buf),size(t.size)

{

;

}

temZone & operator = (const temZone &t)

{

buf = t.buf;

size = t.size;

return *this;

}

};

vector<temZone> _blocks;

int blockcounter;

};

/**

* /ingroup my_memorypool

* CGeneralMemoryPool,提供线程安全的实现

*

* /par requirements

* win98 or later/n

* win2k or later/n

* MFC/n

*

* /version 1.0

* first version

*

* /date 2009-06-03

*

* /author Jason

*

* /par license

* This code is absolutely free to use and modify. The code is provided "as is" with

* no expressed or implied warranty. The author accepts no liability if it causes

* any damage to your computer, causes your pet to fall ill, increases baldness

* or makes your car start emitting strange noises when you start it up.

* This code has no bugs, just undocumented features!

*

* /todo

*

* /bug

*

*/

template<class MUTEX__,class MPINSTANCE>

class CGeneralMemoryPool : public CMPBase

{

class CSimGuard

{

public:

CSimGuard(MUTEX__ & l)

:lk(l)

{

lk.acquire();

}

~CSimGuard(void)

{

lk.release();

}

private:

MUTEX__ & lk;

};

public:

CGeneralMemoryPool()

{

mp_ins = new MPINSTANCE;

}

CGeneralMemoryPool(int size)

{

mp_ins = new MPINSTANCE(size);

}

virtual ~CGeneralMemoryPool(void)

{

delete mp_ins;

}

virtual int append(int size)

{

CSimGuard b(lock__);

return mp_ins->append(size);

}

virtual void reap(void)

{

CSimGuard b(lock__);

mp_ins->reap();

}

virtual int space_(void)

{

CSimGuard b(lock__);

return mp_ins->space_();

}

virtual int malloced(void)

{

CSimGuard b(lock__);

return mp_ins->malloced();

}

virtual int freememory(void)

{

CSimGuard b(lock__);

return mp_ins->freememory();

}

virtual void * malloc(int size)

{

CSimGuard b(lock__);

return mp_ins->malloc(size);

}

virtual void free(void * mp)

{

CSimGuard b(lock__);

mp_ins->free(mp);

}

virtual void dump(const string & file)

{

CSimGuard b(lock__);

mp_ins->dump(file);

}

private:

CGeneralMemoryPool(const CGeneralMemoryPool &){}

CGeneralMemoryPool & operator = (const CGeneralMemoryPool & t){return *this;}

MUTEX__ lock__;

MPINSTANCE * mp_ins;

};

/**

* /ingroup my_memorypool

* CObjectPool 提供基于内存池的对象级别的内存管理接口

*

* /par requirements

* win98 or later/n

* win2k or later/n

* MFC/n

*

* /version 1.0

* first version

*

* /date 2009-06-05

*

* /author Jason

*

* /par license

* This code is absolutely free to use and modify. The code is provided "as is" with

* no expressed or implied warranty. The author accepts no liability if it causes

* any damage to your computer, causes your pet to fall ill, increases baldness

* or makes your car start emitting strange noises when you start it up.

* This code has no bugs, just undocumented features!

*

* /todo

*

* /bug

*

*/

template<class _ACEMutex,class MPINSTANCE>

class CObjectPool : public CGeneralMemoryPool<_ACEMutex,MPINSTANCE>

{

typedef CGeneralMemoryPool<_ACEMutex,MPINSTANCE> supper;

public:

//这个定义应该会屏蔽超类的定义

template<class T>

T* malloc(/*int size*/T*& p)

{

void* obj = supper::malloc(sizeof(T)/*size*/);

::new (obj) T(/* not args */); // 进行默认构造

p = (T*)obj;

return /*(T*)obj*/p;

}

// 释放对象

template<class T>

void free(T* obj)

{

if (obj != 0)

{

obj->~T();

supper::free(obj);

}

}

};

MY_MPN_E // namespace my_mempool

#endif /*MY_MEMBLOCK_H*/

cpp文件

#include <stdlib.h>

#include <algorithm>

#include <fstream>

#include "MemPool.h"

MY_MPN_B

CMPBase::~CMPBase()

{

;

}

int CMPBase::round_up(int size)

{

return (( size + 7) &~ 7);// 按8字节对齐

}

CMapMemoryPool::CMapMemoryPool()

:blockcounter(1),initialized(false)

{

append(DEFAULTSIZE);

}

CMapMemoryPool::CMapMemoryPool(const int & size)

:blockcounter(1),initialized(false)

{

append(size);

}

CMapMemoryPool::~CMapMemoryPool()

{

reap();

}

int CMapMemoryPool::append(int size)

{

if(size < 1024 * 10)

{

size = 1024 * 10;

}

size = round_up(size);

char * p = (char*)::malloc(size);

if(!p)

return -1;

::memset(p,0,size);

_blocks.push_back(temZone(p,size));

mem_control_block * pMCB = (mem_control_block *)p;

pMCB->flag = mbHeader | mbTail;

pMCB->is_available = 1;

pMCB->blockcounter = 0;

pMCB->size = size;

pMCB->blockcounter = blockcounter++;

unsigned int v2,v1;

v2 = (unsigned int)pMCB;

v1 = (unsigned int)++pMCB;

pair<map_type::iterator, bool> r ;

r = free_memory.insert(make_pair(v1,v2));

if(r.second)

{

initialized = true;

return 0;

}

::free(p);

return -1;

}

void CMapMemoryPool::reap(void)

{

initialized = false;

for(vector<temZone>::iterator i = _blocks.begin(); i != _blocks.end() ; ++i)

{

if(i->buf)

::free(i->buf);

}

_blocks.clear();

}

int CMapMemoryPool::count_space(const map_type & m)

{

if(!initialized)

return -1;

CSimpleCount counter__;

for_each(m.begin(),m.end(),counter__);

return counter__.Count();

}

int CMapMemoryPool::malloced(void)

{

if(!initialized)

return -1;

return count_space(malloced_memory);

}

int CMapMemoryPool::freememory(void)

{

if(!initialized)

return -1;

return count_space(free_memory);

}

void * CMapMemoryPool::malloc(int size)

{

if(!initialized)

return NULL;

size = round_up(size);

mem_control_block * p = NULL, * p1 = NULL;

map_type::iterator i,i1 = free_memory.end();

//修改实际内存

for( i = free_memory.begin(); i != free_memory.end(); ++i)

{

p = (mem_control_block *)(i->second);

if( p && p->size > size )

{

if( p->size < size * 2 )

{

p->is_available = 0;

break;

}

else// larger ,blocking partition, Jason

{

int old_size = p->size;

p->is_available = 0;

if(old_size - size < sizeof(mem_control_block))

{

break;

}

p->size = size + sizeof(mem_control_block);

p1 = (mem_control_block*)((char*)p + p->size);

p1->is_available = 1;

p1->size = old_size - p->size;

p1->blockcounter = p->blockcounter;

if( ( p->flag & mbHeader ) == mbHeader && ( p->flag & mbTail ) == mbTail )

{

p->flag = mbHeader;

p1->flag = mbTail;

}

else if( ( p->flag & mbTail ) == mbTail ) //尾巴

{

p1->flag = mbTail;

}

else //if( ( p->flag | mbHeader ) == 0 ) //头和中间的处理一样

{

p1->flag = mbMed;

i1 = ++i;

--i;

mem_control_block * p3 = (mem_control_block *)(i1->second);

if((unsigned int )p1 + p1->size != i1->second ) //不连续

break;

if(p3->blockcounter == p->blockcounter)// same memory block

{

p1->size += p3->size;

p1->flag = p3->flag;

}

}

break;

}

}//if( p && p->size > size )

}//for

//修改表

if( i != free_memory.end() )

{

malloced_memory.insert(*i);

if(i1 != free_memory.end())

free_memory.erase(i,i1);

else

free_memory.erase(i);

if(p1)//新块,加入进来了

{

char * _p = (char*)(p1+1);

free_memory.insert(make_pair((unsigned int)_p,(unsigned int)p1));

}

return (void*)(++p);

}

return NULL;

}

void CMapMemoryPool::free(void * mp)

{

if(!initialized)

return ;

mem_control_block * p = NULL, * p1 = NULL;

map_type::iterator i;

unsigned int k = (unsigned int)mp;

i = malloced_memory.find(k);

if(i != malloced_memory.end())

{

p = (mem_control_block *)i->second;

malloced_memory.erase(i); // i 无效了

p->is_available = 1;

map_type::iterator previ,nexti;

unsigned int _pos,pos_;

map_type::iterator _i = free_memory.end(), i_ = free_memory.end(), it;

pos_ = (unsigned int)p + p->size + sizeof(mem_control_block);

_pos = 0;

for( it = free_memory.begin(); it != free_memory.end() ; ++it)

{

p1 = (mem_control_block *)it->second;

if(p1->blockcounter != p->blockcounter)

continue;

if( (unsigned) p1 + p1->size == (unsigned)p )//正好是前面的

{

_i = it;

}

else if( (unsigned) p1 == (unsigned)p + p->size )//正好是后面的

{

i_ = it;

break;

}

else if((unsigned) p1 /*+ p1->size*/ > (unsigned)p + p->size )

break;

}

if( _i == free_memory.end() && i_ == free_memory.end() )//没有找到邻接点

{

free_memory.insert( make_pair( (unsigned int) p + sizeof(mem_control_block) ,(unsigned int)p ) );

}

else if( _i != free_memory.end() && i_ != free_memory.end() ) //前驱后继都有

{

mem_control_block * _p, *p_;

_p = (mem_control_block *)_i->second;

p_ = (mem_control_block *)i_->second;

_p->size += p->size + p_->size;

if(p_->flag == mbTail)

_p->flag |= p_->flag;

free_memory.erase(_i,i_);

free_memory.insert( make_pair( (unsigned int) _p + sizeof(mem_control_block) ,(unsigned int)_p ) );

}

else if( _i != free_memory.end() )//有前驱点

{

p1 = (mem_control_block *)_i->second;

if(p->flag == mbTail)

p1->flag |= p->flag;

p1->size += p->size;

free_memory.erase(_i);

free_memory.insert( make_pair( (unsigned int) p1 + sizeof(mem_control_block) ,(unsigned int)p1 ) );

}

else if( i_ != free_memory.end() )//有后继点

{

p1 = (mem_control_block *)i_->second;

if(p1->flag == mbTail)

p->flag |= p1->flag;

p->size += p1->size;

free_memory.erase(i_);

free_memory.insert( make_pair( (unsigned int) p + sizeof(mem_control_block) ,(unsigned int)p ) );

}

}

}

void CMapMemoryPool::dump(const string & file)

{

if(!initialized)

return ;

fstream fs;

fs.open(file.c_str(),/*ios::oct |*/ ios_base::out | ios::binary | ios::ate | ios::app);

if(!fs.bad())

{

for( vector<temZone>::iterator i = _blocks.begin(); i != _blocks.end() ; ++i )

{

fs.write((const char *)i->buf,i->size);

}

fs.close();

}

}

MY_MPN_E
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: