メモリプールバージョン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;
}