メモリプールバージョン4-マルチスレッド-可変サイズオブジェクトのメモリプール
27873 ワード
#include "stdafx.h"
#include <windows.h>
#include <MMSystem.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "winmm.lib")
class Foo
{
public:
Foo(int a = 0, int b = 0):m(a), n(b) {}
private:
int m;
int n;
};
///////////////////////////////////////////////////////////
template <typename T>
class MemoryPool
{
public:
MemoryPool(size_t size = EXPAND_SIZE)
{
ExpandFreeList(size);
}
~MemoryPool()
{
if (pNext != 0)
{
MemoryPool<T>* ptr = pNext;
for (; ptr != NULL; ptr = pNext)
{
pNext = pNext->pNext;
delete []ptr;
}
}
}
inline void* alloc(size_t size) // T
{
if (pNext == 0)
{
ExpandFreeList(EXPAND_SIZE);
}
MemoryPool<T>* ptr = pNext;
pNext = pNext->pNext;
return ptr;
}
inline void free(void* doomed) // T
{
MemoryPool<T>* ptr = static_cast<MemoryPool<T>* >(doomed);
ptr->pNext = pNext;
pNext = ptr;
}
//private:
enum {EXPAND_SIZE = 3};
MemoryPool<T>* pNext;
void ExpandFreeList(size_t num = EXPAND_SIZE)
{
size_t size = sizeof(T) > sizeof(MemoryPool<T>*) ? sizeof(T) : sizeof(MemoryPool<T>*);
MemoryPool<T>* ptr = (MemoryPool<T>*)(new char[size]);
pNext = ptr;
for (int i=0; i<num; ++i)
{
ptr->pNext = (MemoryPool<T>*)(new char[size]);
ptr = ptr->pNext;
}
ptr->pNext = 0;
}
};
///////////////////////////////////////////////
template <class POOLTYPE, class LOCK>
class MTMeomoryPool
{
public:
MTMeomoryPool() {}
~MTMeomoryPool() {}
void* alloc(size_t size)
{
lock_.lock();
void* pMem = pool_.alloc(size);
lock_.unlock();
return pMem;
}
void free(void* doomed)
{
lock_.lock();
pool_.free(doomed);
lock_.unlock();
}
private:
POOLTYPE pool_;
LOCK lock_;
};
/////////////////////////////////////////////////
class ABCLock
{
public:
virtual ~ABCLock() {}
virtual void lock() = 0;
virtual void unlock() = 0;
};
class MutexLock : public ABCLock
{
public:
MutexLock()
{
create(TEXT("mutex"));
}
~MutexLock()
{
release();
}
void lock()
{
wait();
}
void unlock()
{
}
private:
HANDLE mutex_;
bool create( const std::wstring& str)
{
mutex_ = ::CreateMutex(NULL, FALSE, str.c_str());
if (mutex_ == NULL || ::GetLastError() == ERROR_ALREADY_EXISTS)
return false;
else
return true;
}
bool wait()
{
UINT32 ret = ::WaitForSingleObject(mutex_, 0);
if (WAIT_FAILED == ret || WAIT_TIMEOUT == ret)
return false;
else
return true;
}
void release()
{
if (mutex_ != NULL)
{
ReleaseMutex(mutex_);
CloseHandle(mutex_);
mutex_ = NULL;
}
}
};
class CSLock : public ABCLock
{
public:
CSLock()
{
InitializeCriticalSection(&cs_);
}
~CSLock()
{
DeleteCriticalSection(&cs_);
}
void lock()
{
EnterCriticalSection(&cs_);
}
void unlock()
{
LeaveCriticalSection(&cs_);
}
private:
CRITICAL_SECTION cs_;
};
/////////////////////////////////////////////////////
class Foo4
{
public:
Foo4(int a =0, int b = 0):m_(a), n_(b){}
static void NewMemoryPool()
{
pool_ = new MTMeomoryPool<MemoryPool<Foo4>, CSLock>;
}
static void DeleteMemoryPool()
{
delete pool_;
}
private:
int m_;
int n_;
static MTMeomoryPool< MemoryPool<Foo4>, CSLock>* pool_;
};
MTMeomoryPool< MemoryPool<Foo4>, CSLock>* Foo4::pool_ = 0;
////////////////////////////////////////////////////////////////
int main()
{
DWORD time1, time2, deltaTime;
time1 = timeGetTime();
for (int i=0; i<500; ++i)
{
Foo* ptrArray[1000];
for (int j=0; j<1000; ++j)
{
ptrArray[j] = new Foo;
}
for (int j=0; j<1000; ++j)
{
delete ptrArray[j];
}
}
time2 = timeGetTime();
deltaTime = time2- time1;
cout<<deltaTime<<endl;
Foo4::NewMemoryPool();
time1 = timeGetTime();
for (int i=0; i<500; ++i)
{
Foo4* ptrArray[1000];
for (int j=0; j<1000; ++j)
{
ptrArray[j] = new Foo4;
}
for (int j=0; j<1000; ++j)
{
delete ptrArray[j];
}
}
time2 = timeGetTime();
Foo4::DeleteMemoryPool();
deltaTime = time2- time1;
cout<<deltaTime<<endl;
return 0;
}