LosaDev source snapshot 2019

This commit is contained in:
LosaDev committed 2026-11-07 13:30:45 +07:00
commit c198676e97
20588 files changed
+8812878

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testQueue", "testQueue\testQueue.vcxproj", "{3C73F9FB-7352-4742-BE16-02B9152B8F82}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3C73F9FB-7352-4742-BE16-02B9152B8F82}.Debug|Win32.ActiveCfg = Debug|Win32
{3C73F9FB-7352-4742-BE16-02B9152B8F82}.Debug|Win32.Build.0 = Debug|Win32
{3C73F9FB-7352-4742-BE16-02B9152B8F82}.Release|Win32.ActiveCfg = Release|Win32
{3C73F9FB-7352-4742-BE16-02B9152B8F82}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+31
View File
@@ -0,0 +1,31 @@
#pragma once
struct NodeEntry
{
NodeEntry() : next(nullptr) {}
NodeEntry* volatile next;
};
struct NodeData
{
NodeData() {}
NodeEntry m_nodeEntry;
};
class DummyMPSC
{
public:
DummyMPSC() : data(0)
{}
int data;
};
class DummyWF : public NodeData
{
public:
DummyWF() : data(0)
{}
int data;
};
+88
View File
@@ -0,0 +1,88 @@
template <class T>
struct MemoryElement_
{
void* data;
MemoryElement_* volatile next;
};
template <class T>
class MPSCMempooler
{
public:
MPSCMempooler(void)
{
};
virtual ~MPSCMempooler(void)
{
};
bool Init(int seed)
{
InitializeCriticalSection(&m_cs);
m_head = m_tail = &m_stub;
m_stub.next = 0;
for(int i=0; i<seed; ++i)
{
MemoryElement_<T>* element = new MemoryElement_<T>;
ZeroMemory(&element->data,sizeof(T));
PushNode(element);
}
return true;
}
public:
bool Push(T* inputData)
{
MemoryElement_<T>* element= reinterpret_cast<MemoryElement_<T>*>(inputData);
element->next = NULL;
MemoryElement_<T>* prev =
reinterpret_cast<MemoryElement_<T>*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
return true;
}
T* Pop()
{
MiniLock(m_cs);
MemoryElement_<T>* tmptail = m_tail;
MemoryElement_<T>* next = tmptail->next;
if (tmptail == &m_stub)
{
if (NULL == next)
return NULL;
m_tail = next;
tmptail = next;
next = next->next;
}
if (next)
{
m_tail = next;
return reinterpret_cast<T*>(&tmptail->data);
}
MemoryElement_<T>* tmphead = m_head;
if (tmptail != tmphead)
return NULL;
PushNode(&m_stub);
next = tmptail->next;
if (next)
{
m_tail = next;
return reinterpret_cast<T*>(&tmptail->data);
}
return NULL;
}
private:
void PushNode(MemoryElement_<T>* element)
{
element->next = NULL;
MemoryElement_<T>* prev =
reinterpret_cast<MemoryElement_<T>*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
}
protected:
MemoryElement_<T>* volatile m_head;
MemoryElement_<T>* m_tail;
MemoryElement_<T> m_stub;
CRITICAL_SECTION m_cs;
};
+149
View File
@@ -0,0 +1,149 @@
#pragma once
#define _ASSERTC(expr) \
{ \
if ( !(expr) ) \
{ \
int* dummy = 0 ; \
*dummy = 0xDEADBEEF ; \
} \
}
template <class T>
class MPMCQueue
{
public:
MPMCQueue() : m_headPos(NULL), m_tailPos(NULL) //, m_Elems(NULL)
{
m_maxSize = 0;
m_currentSize = 0;
}
void Init(int max) //가능한 2의 제곱으로 해주는게 좋음
{
try
{
// m_maxSize = MakeSize(max);
// m_Elems = new T*[m_maxSize];
// memset(m_Elems,0,sizeof(T*)*m_maxSize);
// m_maxSizeMask = m_maxSize -1;
m_maxSize = 1048576;
m_maxSizeMask = 1048576 - 1;
}
catch(std::exception& e)
{
}
}
int MakeSize(int size)
{
int nsqrt = 0;
int resultval = size;
while(resultval != 1)
{
resultval = resultval/2;
nsqrt++;
}
int rtval = pow((double)2,nsqrt+1);
return rtval;
}
void Push(T* newElem)
{
__int64 insertPos = InterlockedIncrement64(&m_tailPos) - 1 ;
_ASSERTC( insertPos - m_headPos < m_maxSize) ; ///< overflow
m_Elems[insertPos&(m_maxSizeMask)] = newElem ;
}
T* Pop()
{
T* popVal = (T*) InterlockedExchangePointer((void**)&m_Elems[m_headPos&(m_maxSizeMask)], nullptr) ;
if ( popVal != nullptr )
InterlockedIncrement64(&m_headPos) ;
return popVal ;
}
__int64 GetSize() const
{
return m_tailPos - m_headPos ;
}
private:
int m_currentSize;
int m_maxSize;
int m_maxSizeMask;
//T** m_Elems ;
T* m_Elems[1048576];
volatile __int64 m_headPos ;
volatile __int64 m_tailPos ;
};
template <class T>
class ORIMPMCQueue
{
public:
template<int E>
struct PowerOfTwo
{
enum { value = 2 * PowerOfTwo<E-1>::value } ;
} ;
template<>
struct PowerOfTwo<0>
{
enum { value = 1 } ;
} ;
enum
{
/// 큐의 크기 설정: 반드시 2의 승수로 해야 한다.
QUEUE_MAX_SIZE = PowerOfTwo<16>::value,
QUEUE_SIZE_MASK = QUEUE_MAX_SIZE - 1
} ;
ORIMPMCQueue() : mHeadPos(0), mTailPos(0)
{
memset(mElem, 0, sizeof(mElem)) ;
}
void Push(T* newElem)
{
__int64 insertPos = InterlockedIncrement64(&mTailPos) - 1 ;
_ASSERTC(insertPos - mHeadPos < QUEUE_MAX_SIZE)
if(insertPos - mHeadPos < QUEUE_MAX_SIZE)///< overflow
{
printf("QQQQQQQQQQQQQ\n");
}
mElem[insertPos&QUEUE_SIZE_MASK] = newElem ;
}
T* Pop()
{
T* popVal = (T*) InterlockedExchangePointer((void**)&mElem[mHeadPos&QUEUE_SIZE_MASK], nullptr) ;
if ( popVal != nullptr )
InterlockedIncrement64(&mHeadPos) ;
return popVal ;
}
__int64 GetSize() const
{
return mTailPos - mHeadPos ;
}
private:
T* mElem[QUEUE_MAX_SIZE] ;
volatile __int64 mHeadPos ;
volatile __int64 mTailPos ;
} ;
+88
View File
@@ -0,0 +1,88 @@
template <class T>
struct MemoryElement_
{
void* data;
MemoryElement_* volatile next;
};
template <class T>
class MPSCMempooler
{
public:
MPSCMempooler(void)
{
};
virtual ~MPSCMempooler(void)
{
};
bool Init(int seed)
{
InitializeCriticalSection(&m_cs);
m_head = m_tail = &m_stub;
m_stub.next = 0;
for(int i=0; i<seed; ++i)
{
MemoryElement_<T>* element = new MemoryElement_<T>;
ZeroMemory(&element->data,sizeof(T));
PushNode(element);
}
return true;
}
public:
bool Push(T* inputData)
{
MemoryElement_<T>* element= reinterpret_cast<MemoryElement_<T>*>(inputData);
element->next = NULL;
MemoryElement_<T>* prev =
reinterpret_cast<MemoryElement_<T>*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
return true;
}
T* Pop()
{
MiniLock(m_cs);
MemoryElement_<T>* tmptail = m_tail;
MemoryElement_<T>* next = tmptail->next;
if (tmptail == &m_stub)
{
if (NULL == next)
return NULL;
m_tail = next;
tmptail = next;
next = next->next;
}
if (next)
{
m_tail = next;
return reinterpret_cast<T*>(&tmptail->data);
}
MemoryElement_<T>* tmphead = m_head;
if (tmptail != tmphead)
return NULL;
PushNode(&m_stub);
next = tmptail->next;
if (next)
{
m_tail = next;
return reinterpret_cast<T*>(&tmptail->data);
}
return NULL;
}
private:
void PushNode(MemoryElement_<T>* element)
{
element->next = NULL;
MemoryElement_<T>* prev =
reinterpret_cast<MemoryElement_<T>*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
}
protected:
MemoryElement_<T>* volatile m_head;
MemoryElement_<T>* m_tail;
MemoryElement_<T> m_stub;
CRITICAL_SECTION m_cs;
};
+159
View File
@@ -0,0 +1,159 @@
#pragma once
#include <deque>
#include <list>
#include "cCriticalSection.h"
template <class Type>
class MPMC_MemPooler
{
public:
MPMC_MemPooler(int numofBlock=0, int maximumBlock=0, BOOL threadSafe=TRUE) :
m_allocCount(32),
m_numofBlock(0),
m_maximumBlock(maximumBlock),
m_threadSafe(threadSafe)
{
m_blockSize = sizeof(Type);
Create(numofBlock);
}
~MPMC_MemPooler()
{
Destroy();
}
public:
void CreatePool(const int numofBlock, const int maximumBlock=0, BOOL threadSafe=TRUE)
{
m_numofBlock = 0;
m_maximumBlock = maximumBlock;
m_threadSafe = threadSafe;
Create(numofBlock);
}
void DestroyPool()
{
Destroy();
}
public:
Type* Pop()
{
return Get();
}
Type* Remove()
{
if(m_memPooler.empty())
return (NULL);
return Get();
}
void Push(Type* block)
{
if(block == NULL)
return;
mpmc_queue::node_t * node = CONTAINING_RECORD(block,mpmc_queue::node_t,data);
m_memPooler.enqueue(node);
}
int GetCount() { return m_memPooler.size(); }
int GetTotalCount() { return m_numofBlock; }
protected:
void Create(const int numofBlock)
{
if(numofBlock <= 0) return;
BYTE *memBlock = new BYTE[m_blockSize * numofBlock];
if(memBlock)
{
Type *block;
int nSegment = 0;
for(int i = 0 ; i < numofBlock ; i++)
{
block = reinterpret_cast<Type*>(reinterpret_cast<DWORD>(memBlock) + nSegment);
new (block) Type;
nSegment += m_blockSize;
mpmc_queue::node_t* node = new mpmc_queue::node_t;
node->data = block;
m_memPooler.enqueue(node);
}
m_numofBlock += numofBlock;
m_memBlocks.push_back(memBlock);
}
}
void Destroy()
{
Lock();
for(std::list<BYTE*>::iterator it = m_memBlocks.begin() ; it != m_memBlocks.end() ; ++it)
{
BYTE* memBlock = *it;
if(memBlock)
{
delete []memBlock;
}
}
m_memBlocks.clear();
Unlock();
}
Type* Get()
{
Type* block = NULL;
if(!m_memPooler.empty())
{
mpmc_queue::node_t* node = NULL;
node = m_memPooler.dequeue();
block = node->data;
}
else
{
if(m_numofBlock < m_maximumBlock)
{
int allocCount = m_maximumBlock - m_numofBlock;
(allocCount > m_allocCount) ? Create(m_allocCount) : Create(allocCount);
mpmc_queue::node_t* node = NULL;
node = m_memPooler.dequeue();
block = node->data;
}
}
return (block);
}
void Lock()
{
if(m_threadSafe) m_cs.Lock();
}
void Unlock()
{
if(m_threadSafe) m_cs.Unlock();
}
protected:
int m_allocCount;
int m_numofBlock;
int m_maximumBlock;
int m_blockSize;
BOOL m_threadSafe;
//std::deque<Type*> m_memPooler;
mpmc_queue m_memPooler;
std::list<BYTE*> m_memBlocks;
// For thread-safe.
cCriticalSection m_cs;
};
+75
View File
@@ -0,0 +1,75 @@
#include "stdafx.h"
#include "MPSCQueue.h"
WFQueue::WFQueue(void)
{
Init();
}
WFQueue::~WFQueue(void)
{
}
bool WFQueue::Init()
{
m_head = m_tail = &m_stub;
m_stub.next = NULL;
m_count = 0;
m_offset = reinterpret_cast<__int64>( &((reinterpret_cast<NodeData*>(0))->m_nodeEntry) ) ;
return true;
}
bool WFQueue::Enqueue( NodeData* node )
{
NodeEntry* prev = reinterpret_cast<NodeEntry*>(InterlockedExchangePointer((void*)(&m_head), (void*)(&node->m_nodeEntry)));
prev->next = &(node->m_nodeEntry);
InterlockedIncrement(&m_count);
return true;
}
void WFQueue::PushNode( NodeEntry* element )
{
element->next = NULL;
NodeEntry* prev = reinterpret_cast<NodeEntry*>(InterlockedExchangePointer((void*)(&m_head), element));
prev->next = element;
}
NodeEntry* WFQueue::Dequeue()
{
NodeEntry* tail = m_tail;
NodeEntry* next = tail->next;
if (tail == &m_stub)
{
if (NULL == next)
return NULL;
m_tail = next;
tail = next;
next = next->next;
}
if (next)
{
m_tail = next;
InterlockedDecrement(&m_count);
NodeEntry* node = reinterpret_cast<NodeEntry*>(reinterpret_cast<__int64>(tail) - m_offset);
return (node);
}
NodeEntry* head = m_head;
if (tail != head)
return NULL;
PushNode(&m_stub);
next = tail->next;
if (next)
{
m_tail = next;
InterlockedDecrement(&m_count);
NodeEntry* node = reinterpret_cast<NodeEntry*>(reinterpret_cast<__int64>(tail) - m_offset);
return (node);
}
return NULL;
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include "DATA.h"
class WFQueue
{
public:
WFQueue(void);
virtual ~WFQueue(void);
bool Init();
public:
bool Enqueue( NodeData *node );
NodeEntry* Dequeue();
int GetSize() { return m_count;}
protected:
void PushNode(NodeEntry* element);
private:
NodeEntry* volatile m_head;
NodeEntry* m_tail;
NodeEntry m_stub;
long m_count;
__int64 m_offset;
};
+160
View File
@@ -0,0 +1,160 @@
#pragma once
#include <deque>
#include <list>
#include "cCriticalSection.h"
template <class Type>
class MemPooler
{
public:
MemPooler(int numofBlock=0, int maximumBlock=0, BOOL threadSafe=TRUE) :
m_allocCount(32),
m_numofBlock(0),
m_maximumBlock(maximumBlock),
m_threadSafe(threadSafe)
{
m_blockSize = sizeof(Type);
Create(numofBlock);
}
~MemPooler()
{
Destroy();
}
public:
void CreatePool(const int numofBlock, const int maximumBlock=0, BOOL threadSafe=TRUE)
{
m_numofBlock = 0;
m_maximumBlock = maximumBlock;
m_threadSafe = threadSafe;
Create(numofBlock);
}
void DestroyPool()
{
Destroy();
}
public:
Type* Pop()
{
return Get();
}
Type* Remove()
{
if(m_memPooler.empty())
return (NULL);
return Get();
}
void Push(Type* block)
{
Lock();
m_memPooler.push_back(block);
Unlock();
}
void Push_Front(Type* block)
{
Lock();
m_memPooler.push_front(block);
Unlock();
}
int GetCount() { return m_memPooler.size(); }
int GetTotalCount() { return m_numofBlock; }
protected:
void Create(const int numofBlock)
{
if(numofBlock <= 0) return;
BYTE *memBlock = new BYTE[m_blockSize * numofBlock];
if(memBlock)
{
Type *block;
int nSegment = 0;
for(int i = 0 ; i < numofBlock ; i++)
{
block = reinterpret_cast<Type*>(reinterpret_cast<DWORD>(memBlock) + nSegment);
new (block) Type;
nSegment += m_blockSize;
m_memPooler.push_back(block);
}
m_numofBlock += numofBlock;
m_memBlocks.push_back(memBlock);
}
}
void Destroy()
{
Lock();
for(std::list<BYTE*>::iterator it = m_memBlocks.begin() ; it != m_memBlocks.end() ; ++it)
{
BYTE* memBlock = *it;
if(memBlock)
{
delete []memBlock;
}
}
m_memBlocks.clear();
Unlock();
}
Type* Get()
{
Type* block = NULL;
Lock();
if(!m_memPooler.empty())
{
block = m_memPooler.front();
if(block)
m_memPooler.pop_front();
}
else
{
if(m_numofBlock < m_maximumBlock)
{
int allocCount = m_maximumBlock - m_numofBlock;
(allocCount > m_allocCount) ? Create(m_allocCount) : Create(allocCount);
block = m_memPooler.front();
if(block)
m_memPooler.pop_front();
}
}
Unlock();
return (block);
}
void Lock()
{
if(m_threadSafe) m_cs.Lock();
}
void Unlock()
{
if(m_threadSafe) m_cs.Unlock();
}
protected:
int m_allocCount;
int m_numofBlock;
int m_maximumBlock;
int m_blockSize;
BOOL m_threadSafe;
std::deque<Type*> m_memPooler;
std::list<BYTE*> m_memBlocks;
// For thread-safe.
cCriticalSection m_cs;
};
+38
View File
@@ -0,0 +1,38 @@
========================================================================
콘솔 응용 프로그램 : testQueue 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 testQueue 응용 프로그램을 만들었습니다.
testQueue 응용 프로그램을 구성하는 각 파일에 대한
요약 설명이 포함되어 있습니다.
testQueue.vcxproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
파일을 생성한 Visual C++ 버전에 대한 정보와 응용 프로그램 마법사를 사용하여 선택한 플랫폼,
구성 및 프로젝트 기능에 대한 정보가 포함되어 있습니다.
testQueue.vcxproj.filters
응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 필터 파일입니다.
이 파일에는 프로젝트의 파일과 필터 간의 연결 정보가 들어 있습니다.
이러한 연결은 특정 노드에서 유사한 확장명으로 그룹화된 파일을 표시하기 위해 IDE에서
사용됩니다. 예를 들어 ".cpp" 파일은 "소스 파일" 필터와 연결되어 있습니다.
testQueue.cpp
기본 응용 프로그램 소스 파일입니다.
/////////////////////////////////////////////////////////////////////////////
기타 표준 파일:
StdAfx.h, StdAfx.cpp
이 파일은 미리 컴파일된 헤더(PCH) 파일 testQueue.pch와
미리 컴파일된 형식(PCT) 파일 StdAfx.obj를 빌드하는 데 사용됩니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////
+96
View File
@@ -0,0 +1,96 @@
#include "stdafx.h"
#include "TMPSCQueue.h"
TMPSCQueue::TMPSCQueue(void)
{
m_timeout = 0;
}
TMPSCQueue::~TMPSCQueue(void)
{
}
bool TMPSCQueue::Init( int seed, int timeout )
{
m_head = m_tail = &m_stub;
m_stub.next = NULL;
m_pool.CreatePool(seed/2,seed);
m_count = 0;
m_timeout = timeout;
return true;
}
bool TMPSCQueue::Enqueue( DWORD inputData )
{
TQueueElement_* element= m_pool.Pop();
if(element == NULL)
return false;
element->next = NULL;
element->data = inputData;
TQueueElement_* prev =
reinterpret_cast<TQueueElement_*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
InterlockedIncrement(&m_count);
return true;
}
void TMPSCQueue::PushNode( TQueueElement_* element )
{
element->next = NULL;
TQueueElement_* prev =
reinterpret_cast<TQueueElement_*>(InterlockedExchangePointer((void**)(&m_head),element));
prev->next = element;
}
LPDWORD TMPSCQueue::Dequeue()
{
TQueueElement_* tmptail = m_tail;
TQueueElement_* next = tmptail->next;
if (tmptail == &m_stub)
{
if (NULL == next)
return NULL;
m_tail = next;
tmptail = next;
next = next->next;
}
if (next)
{
m_tail = next;
InterlockedDecrement(&m_count);
DWORD rtval = tmptail->data;
m_pool.Push(tmptail);
return reinterpret_cast<LPDWORD>(rtval);
}
TQueueElement_* tmphead = m_head;
if (tmptail != tmphead)
return NULL;
PushNode(&m_stub);
next = tmptail->next;
if (next)
{
m_tail = next;
InterlockedDecrement(&m_count);
LPDWORD rtval = reinterpret_cast<LPDWORD>(tmptail->data);
m_pool.Push(tmptail);
return reinterpret_cast<LPDWORD>(rtval);
}
return NULL;
}
LPDWORD TMPSCQueue::WaitDequeue()
{
LPDWORD data;
while ((data = Dequeue()) == NULL)
Sleep (m_timeout); // wait for nonbusy result
return data;
}
void TMPSCQueue::ReleaseMemoryPool()
{
m_pool.DestroyPool();
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "MemPooler.h"
struct TQueueElement_
{
DWORD data;
TQueueElement_* volatile next;
};
class TMPSCQueue
{
public:
TMPSCQueue(void);
virtual ~TMPSCQueue(void);
bool Init(int seed,int timeout = 0);
void ReleaseMemoryPool();
public:
bool Enqueue(DWORD inputData);
LPDWORD Dequeue();
LPDWORD WaitDequeue();
int GetSize() { return m_count;}
protected:
void PushNode(TQueueElement_* element);
private:
TQueueElement_* volatile m_head;
TQueueElement_* m_tail;
TQueueElement_ m_stub;
MemPooler<TQueueElement_> m_pool;
long m_count;
int m_timeout;
};
+14
View File
@@ -0,0 +1,14 @@
#include "StdAfx.h"
#include "TestCase.h"
TestCase::TestCase(void)
{
}
TestCase::~TestCase(void)
{
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "DATA.h"
class TestCase
{
public:
TestCase(void);
virtual ~TestCase(void);
virtual void Run() = 0;
template <class T>
int unique_check(std::pair<T,bool> &result)
{
int rtval = 0;;
if(result.second == true)
rtval = 0;
else
rtval = -1;
return rtval;
}
};
+107
View File
@@ -0,0 +1,107 @@
#include "StdAfx.h"
#include "TestIOCPQueue.h"
#include <set>
#include <iostream>
TestIOCPQueue::TestIOCPQueue(void)
{
Startup(1);
}
TestIOCPQueue::~TestIOCPQueue(void)
{
m_nodes.DestroyPool();
}
void TestIOCPQueue::Start()
{
}
void TestIOCPQueue::Run()
{
int tmpval;
// flush(stdin);
printf("\nQueCount : ");
std::cin >> tmpval;
m_nodes.CreatePool(tmpval/2,tmpval);
int quecount = tmpval;
printf("Thread Count : ");
scanf("%d",&tmpval);
std::vector<boost::thread*> m_threads;
for(int i=0; i<tmpval; ++i)
{
m_threads.push_back(new boost::thread(&TestIOCPQueue::Input,this,(quecount/tmpval)*i,quecount/tmpval));
}
//for(int i=0; i<m_threads.size(); ++i)
// m_threads[i]->join();
boost::thread popthread(&TestIOCPQueue::Pop,this,quecount);
popthread.join();
Cleanup();
}
double TestIOCPQueue::Input( int i, int maxcount )
{
DWORD tmp =0;
boost::timer el;
int index = 0;
int tmpval = i;
for(index; index<maxcount; ++index)
{
i++;
NodeData* node = reinterpret_cast<NodeData*>(m_nodes.Pop());
node->data = reinterpret_cast<void*>(i);
Enqueue((DWORD)node,tmp);
}
printf("InputThread(%d) %0.4f\n",tmpval,el.elapsed());
return 0;
}
void TestIOCPQueue::Pop(int quecount)
{
std::set<int> testvalues;
NodeData* popval = NULL;
int popcount = 0;
boost::timer el;
while(1)
{
popval = reinterpret_cast<NodeData*>(Dequeue());
if(popval == NULL)
break;
// printf("%d\n",popval);
if(unique_check(testvalues.insert((int)popval->data)) == -1)
{
printf("Áߺ¹µ¥ÀÌÅÍ \n");
break;
}
if(testvalues.size() > 5000000)
{
// printf("D:%d",popcount);
testvalues.clear();
}
popcount++;
m_nodes.Push((NodeData*)popval);
if(popcount >= quecount)
{
printf("¿Ï·á\n");
break;
}
}
printf("Finished popCount :[%d] time: [%0.4f]\n",popcount,el.elapsed());
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include "TestCase.h"
struct NodeData
{
void* data;
NodeData* volatile next;
};
class TestIOCPQueue : public TestCase, cIocpQueue
{
public:
TestIOCPQueue(void);
virtual ~TestIOCPQueue(void);
virtual void Start();
virtual void Run();
public:
double Input(int i, int maxcount);
void Pop(int quecount);
private:
MemPooler<NodeData> m_nodes;
};
@@ -0,0 +1,112 @@
#include "StdAfx.h"
#include "TestMPMCMemoryPool.h"
#include <boost/timer.hpp>
#define MAXCOUNT 1000000
TestMPMCMemoryPool::TestMPMCMemoryPool(void)
{
}
TestMPMCMemoryPool::~TestMPMCMemoryPool(void)
{
}
void TestMPMCMemoryPool::Run()
{
m_memPooler.CreatePool(MAXCOUNT/2,MAXCOUNT);
test_* tt = new test_;
m_memPooler.CreatePush(tt);
m_orimemPooler.CreatePool(MAXCOUNT/2,MAXCOUNT);
boost::thread newmemt(&TestMPMCMemoryPool::TestFunc,this,0,0);
boost::thread orimemt(&TestMPMCMemoryPool::oriTestFunc,this,0,0);
newmemt.join();
orimemt.join();
}
void TestMPMCMemoryPool::TestFunc( int i, int maxcount )
{
boost::timer el;
std::vector<test_*> tests;
for(int i=0; i<MAXCOUNT; ++i)
{
test_* ptest = m_memPooler.Pop();
ptest->i = i;
tests.push_back(ptest);
}
for(int i=0; i<tests.size(); ++i)
{
m_memPooler.Push(tests[i]);
}
printf("New Mem Finsith[%d]:%0.3f\n",tests.size(),el.elapsed());
std::vector<boost::thread*> threads;
for(int i=0; i<8; ++i)
{
threads.push_back(new boost::thread(&TestMPMCMemoryPool::PopFunc,this,i));
}
for(int i=0; i<threads.size(); ++i)
{
threads[i]->join();
}
}
void TestMPMCMemoryPool::oriTestFunc( int i, int maxcount )
{
boost::timer el;
std::vector<test_*> tests;
for(int i=0; i<MAXCOUNT; ++i)
{
test_* ptest = m_orimemPooler.Pop();
ptest->i = i;
tests.push_back(ptest);
}
for(int i=0; i<tests.size(); ++i)
{
m_orimemPooler.Push(tests[i]);
}
printf("\nOriMem Finsith[%d]:%0.3f\n",tests.size(),el.elapsed());
std::vector<boost::thread*> threads;
for(int i=0; i<8; ++i)
{
threads.push_back(new boost::thread(&TestMPMCMemoryPool::oriPopFunc,this,i));
}
for(int i=0; i<threads.size(); ++i)
{
threads[i]->join();
}
}
#define POPCOUNT 500000
void TestMPMCMemoryPool::PopFunc( int i )
{
boost::timer el;
for(int j = 0; j<POPCOUNT;++j)
{
test_* ptest = m_memPooler.Pop();
if(j% 300000 == 1)
printf("n:%d ",ptest->i);
m_memPooler.Push(ptest);
}
printf("\n[%d]Popfunc Finsh:%0.3f (free:%d)\n",i,el.elapsed(),m_memPooler.GetCount());
}
void TestMPMCMemoryPool::oriPopFunc( int i )
{
boost::timer el;
for(int j = 0; j<POPCOUNT;++j)
{
test_* ptest = m_orimemPooler.Pop();
// printf("O:%d ",ptest->i);
if(j% 300000 == 1)
printf("o:%d ",ptest->i);
m_orimemPooler.Push(ptest);
}
printf("\n[%d]OriPopfunc Finsh:%0.3f (free:%d)\n",i,el.elapsed(),m_orimemPooler.GetCount());
}
@@ -0,0 +1,29 @@
#pragma once
#include "TestCase.h"
#include "mpmc_seh_mempool.h"
#include <set>
#include "MemPooler.h"
struct test_
{
char str[256];
int i;
};
class TestMPMCMemoryPool : public TestCase
{
public:
TestMPMCMemoryPool(void);
virtual ~TestMPMCMemoryPool(void);
virtual void Run();
virtual void TestFunc(int i, int maxcount);
virtual void oriTestFunc(int i, int maxcount);
virtual void PopFunc(int i);
virtual void oriPopFunc(int i);
MPMC_MemPooler<test_> m_memPooler;
MemPooler<test_> m_orimemPooler;
};
+155
View File
@@ -0,0 +1,155 @@
#include "StdAfx.h"
#include "TestMPMCQueue.h"
#include <iostream>
#include <set>
TestMPMCQueue::TestMPMCQueue(void)
{
}
TestMPMCQueue::~TestMPMCQueue(void)
{
}
void TestMPMCQueue::Start()
{
}
#define MAXXX 3
void TestMPMCQueue::Run()
{
#if 0
m_pool.CreatePool(MAXXX/2,MAXXX);
std::vector<int*> ints;
for(int i=0; i<MAXXX; ++i)
{
ints.push_back(m_pool.Pop());
}
for(int i=0; i<ints.size(); ++i)
{
*ints[i] = i;
}
for(int i=0; i<ints.size(); ++i)
{
m_pool.Push(reinterpret_cast<int*>(ints[i]));
}
ints.clear();
for(int i=0; i<MAXXX; ++i)
{
int* a = m_pool.Pop();
printf("P:%d\n",*a);
ints.push_back(a);
}
for(int i=0; i<ints.size(); ++i)
{
m_pool.Push(reinterpret_cast<int*>(ints[i]));
}
ints.clear();
for(int i=0; i<MAXXX; ++i)
{
int* a = m_pool.Pop();
printf("P:%d\n",*a);
ints.push_back(a);
}
for(int i=0; i<ints.size(); ++i)
{
m_pool.Push(reinterpret_cast<int*>(ints[i]));
}
#endif
#if 1
int tmpval;
printf("\nQueCount : ");
std::cin >> tmpval;
int quecount = tmpval;
printf("Thread Count : ");
scanf_s("%d",&tmpval);
std::vector<boost::thread*> m_threads;
for(int i=0; i<tmpval; ++i)
{
m_threads.push_back(new boost::thread(&TestMPMCQueue::Input,this,(quecount/tmpval)*i,quecount/tmpval));
}
for(int i=0; i<m_threads.size(); ++i)
m_threads[i]->join();
printf("\n");
int popcount = 2;
std::vector<boost::thread*> m_popthreads;
std::vector<std::vector<int>* > values;
for(int i=0; i<popcount; ++i)
{
std::vector<int>* tmpset = new std::vector<int>;
values.push_back(tmpset);
}
for(int i =0; i<popcount; ++i)
{
m_popthreads.push_back(new boost::thread(&TestMPMCQueue::Pop,this,i,(quecount/popcount),quecount,values[i]));
}
for(int i=0; i<popcount; ++i)
m_popthreads[i]->join();
printf("\n");
std::set<int> mainset;
for(int i=0; i< values.size(); ++i)
{
for(int j=0; j<values[i]->size(); ++j)
{
if(unique_check(mainset.insert(values[i]->at(j))) == -1)
printf("Áߺ¹µ¥ÀÌÅÍ\n");
}
}
printf("Final size = %d\n",mainset.size());
for(int i=0; i<values.size(); ++i)
{
values[i]->clear();
}
#endif
//m_popthreads.join();
//m_queue.ReleaseMemoryPool();
}
double TestMPMCQueue::Input( int i, int maxcount )
{
boost::timer el;
int index = 0;
for(index; index<maxcount; ++index)
{
mpmc_queue::node_t* tt = new mpmc_queue::node_t;
// tt->data = new int(i+index);
m_queue.enqueue(tt);
}
printf("i:%d max:%d time:%0.3f\n",i,maxcount,el.elapsed());
return 0;
}
void TestMPMCQueue::Pop( int i,int maxcount,int quecount, std::vector<int>* setval)
{
int index =0;
//while(1)
boost::timer el;
for(index; index<maxcount; ++index)
{
mpmc_queue::node_t* valt = m_queue.dequeue();
// int* val = (int*)valt->data;
// if(val == NULL)
{
// printf("NULL Size : %d\n",m_queue.GetSize());
// printf("ºü´Ù:%d\n",val);
break;
}
// setval->push_back(*val);
//printf("P[%d]:%d ",i,*val);
//delete val;
}
printf("Elast::%0.3f\n",el.elapsed());
}
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include "TestCase.h"
#include "MPMCQueue.h"
#include "mpmc_queue.h"
#include "mpmc_seh_mempool.h"
#include <set>
class TestMPMCQueue : public TestCase
{
public:
TestMPMCQueue(void);
virtual ~TestMPMCQueue(void);
virtual void Start();
virtual void Run();
public:
double Input(int i, int maxcount);
void Pop(int i,int maxcount,int quecount, std::vector<int>* sets);
protected:
//MPMCQueue<int> m_queue;
//ORIMPMCQueue<int> m_queue;
mpmc_queue m_queue;
//MPMC_MemPooler<int> m_pool;
MemPooler<int> m_pool;
};
+123
View File
@@ -0,0 +1,123 @@
#include "StdAfx.h"
#include "TestMPSCQueue.h"
#include <set>
#include <iostream>
extern INT G_TESTCOUNT;
extern LONG G_NUMBER;
extern BOOL G_TERMINATE;
TestMPSCQueue::TestMPSCQueue(int count) : m_count(count)
{
}
TestMPSCQueue::~TestMPSCQueue(void)
{
}
void TestMPSCQueue::Run()
{
G_NUMBER = 0;
G_TERMINATE = FALSE;
m_queue.Init(G_TESTCOUNT, 1);
std::vector<boost::thread*> m_threads;
for(int i=0; i< m_count; i++)
{
m_threads.push_back(new boost::thread(&TestMPSCQueue::Input,this));
}
//for(int i=0; i<m_threads.size(); ++i)
// m_threads[i]->join();
boost::thread popthread(&TestMPSCQueue::Pop,this);
popthread.join();
m_queue.ReleaseMemoryPool();
}
double TestMPSCQueue::Input()
{
int count = 0;
while(!G_TERMINATE)
{
DummyMPSC* node = new DummyMPSC;
if(!node)
{
int a;
a = 0;
return 0;
}
++count;
LONG value = InterlockedIncrement(&G_NUMBER);
node->data = value;
if(m_queue.Enqueue((DWORD)node) == false)
{
//printf("Memory Pool Zero\n");
break;
}
if(value >= G_TESTCOUNT)
{
break;
}
}
return 0;
}
void TestMPSCQueue::Pop()
{
int popcount = 0;
boost::timer el;
DummyMPSC* popval = NULL;
while(1)
{
popval = reinterpret_cast<DummyMPSC*>(m_queue.Dequeue());
if(popval == NULL)
{
SwitchToThread();
continue;
}
if(popcount == 0)
{
el.restart();
}
delete popval;
popcount++;
if(popcount >= G_TESTCOUNT)
{
G_TERMINATE = TRUE;
break;
}
}
printf("Finished popCount :[%d] time: [%0.4f], remain : %lu\n",popcount, el.elapsed(), m_queue.GetSize());
while(TRUE)
{
popval = reinterpret_cast<DummyMPSC*>(m_queue.Dequeue());
if(popval == NULL) break;
delete popval;
}
if(m_queue.GetSize() != 0)
{
printf("remove not complete : %lu\n", m_queue.GetSize());
}
}
void TestMPSCQueue::Start()
{
boost::thread thread(&TestMPSCQueue::Run,this);
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "TestCase.h"
#include "TMPSCQueue.h"
class TestMPSCQueue : public TestCase
{
public:
TestMPSCQueue(int count);
virtual ~TestMPSCQueue(void);
virtual void Start();
virtual void Run();
public:
double Input();
void Pop();
protected:
TMPSCQueue m_queue;
int m_count;
};
+125
View File
@@ -0,0 +1,125 @@
#include "StdAfx.h"
#include "TestWFQueue.h"
#include <set>
#include <iostream>
extern INT G_TESTCOUNT;
extern LONG G_NUMBER;
extern BOOL G_TERMINATE;
TestWFQueue::TestWFQueue(int count) : m_count(count)
{
}
TestWFQueue::~TestWFQueue(void)
{
}
void TestWFQueue::Run()
{
G_NUMBER = 0;
G_TERMINATE = FALSE;
std::vector<boost::thread*> m_threads;
for(int i=0; i< m_count; i++)
{
m_threads.push_back(new boost::thread(&TestWFQueue::Input,this));
}
//for(int i=0; i<m_threads.size(); ++i)
// m_threads[i]->join();
boost::thread popthread(&TestWFQueue::Pop,this);
popthread.join();
}
double TestWFQueue::Input()
{
int count = 0;
while(!G_TERMINATE)
{
DummyWF* node = new DummyWF;
if(!node)
{
int a;
a = 0;
return 0;
}
++count;
LONG value = InterlockedIncrement(&G_NUMBER);
node->data = value;
if(m_queue.Enqueue(node) == false)
{
printf("Memory Pool Zero\n");
break;
}
if(value >= G_TESTCOUNT)
{
break;
}
}
return 0;
}
void TestWFQueue::Pop()
{
std::set<int> values;
int popcount = 0;
boost::timer el;
DummyWF* popval = NULL;
while(TRUE)
{
popval = reinterpret_cast<DummyWF*>(m_queue.Dequeue());
if(popval == NULL)
{
SwitchToThread();
continue;
}
if(popcount == 0)
{
el.restart();
}
//if(unique_check(values.insert(popval->data)) == -1)
//{
// printf("Áߺ¹µ¥ÀÌÅÍ \n");
// break;
//}
delete popval;
popcount++;
if(popcount >= G_TESTCOUNT)
{
G_TERMINATE = TRUE;
break;
}
}
printf("Finished popCount :[%d] time: [%0.4f], remain : %lu\n",popcount, el.elapsed(), m_queue.GetSize());
while(TRUE)
{
popval = reinterpret_cast<DummyWF*>(m_queue.Dequeue());
if(popval == NULL) break;
delete popval;
}
if(m_queue.GetSize() != 0)
{
printf("remove not complete : %lu\n", m_queue.GetSize());
}
}
void TestWFQueue::Start()
{
boost::thread thread(&TestWFQueue::Run,this);
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "TestCase.h"
#include "MPSCQueue.h"
class TestWFQueue : public TestCase
{
public:
TestWFQueue(int count);
virtual ~TestWFQueue(void);
virtual void Start();
virtual void Run();
public:
double Input();
void Pop();
protected:
WFQueue m_queue;
int m_count;
};
@@ -0,0 +1,20 @@
#pragma once
class cCriticalSection
{
public:
cCriticalSection()
{
InitializeCriticalSection( &m_criticalSection );
}
~cCriticalSection() { DeleteCriticalSection( &m_criticalSection ); }
public:
void Lock() { EnterCriticalSection( &m_criticalSection ); }
void Unlock() { LeaveCriticalSection( &m_criticalSection ); }
private:
CRITICAL_SECTION m_criticalSection;
};
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#ifndef _LS_BASIC_TYPES_
#define _LS_BASIC_TYPES_
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef unsigned __int64 uint64;
typedef char int8;
typedef short int16;
typedef long int32;
typedef __int64 int64;
typedef uint64 uniq;
typedef uint32 unit;
#endif
+12
View File
@@ -0,0 +1,12 @@
/* Multi-producer/multi-consumer queue
* 2009, Dmitriy V'yukov
* Distributed under the terms of the GNU General Public License
* as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
* See: http://www.gnu.org/licenses
*/
#include "stdafx.h"
#include "mpmc_queue.h"
+149
View File
@@ -0,0 +1,149 @@
/* Multi-producer/multi-consumer queue
* 2009, Dmitriy V'yukov
* Distributed under the terms of the GNU General Public License
* as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
* See: http://www.gnu.org/licenses
*/
#include <assert.h>
#pragma once
class mpmc_queue
{
public:
struct node_t
{
node_t* volatile next_;
};
mpmc_queue()
{
head_.ptr_ = 0;
head_.cnt_ = 0;
tail_ = &head_.ptr_;
m_size = 0;
}
~mpmc_queue()
{
assert(head_.ptr_ == 0);
assert(tail_ == &head_.ptr_);
}
long size()
{
return m_size;
}
bool empty()
{
if(m_size == 0)
return true;
return false;
}
void enqueue(node_t* node)
{
assert(node);
node->next_ = 0;
node_t** prev = (node_t**)
_InterlockedExchange((long*)&tail_, (long)node);
assert(prev);
// <--- the window of inconsistency is HERE (***)
prev[0] = node;
InterlockedIncrement(&m_size);
}
node_t* dequeue()
{
unsigned retry_count = 0;
InterlockedDecrement(&m_size);
retry:
__try
{
head_t h;
h.ptr_= head_.ptr_;
h.cnt_ = head_.cnt_;
for (;;)
{
node_t* n = h.ptr_;
if (n == 0)
return 0;
if (n->next_)
{
head_t xchg = {n->next_, h.cnt_ + 1};
__int64 prev_raw =
_InterlockedCompareExchange64
(&head_.whole_, xchg.whole_, h.whole_);
head_t prev = *(head_t*)&prev_raw;
if (*(__int64*)&prev == *(__int64*)&h)
return n;
h.ptr_ = prev.ptr_;
h.cnt_ = prev.cnt_;
}
else
{
node_t* t = (node_t*)tail_;
if (n != t)
{
// spinning here may only be caused
// by producer preempted in (***)
SwitchToThread();
h.ptr_= head_.ptr_;
h.cnt_ = head_.cnt_;
continue;
}
head_t xchg = {0, h.cnt_ + 1};
head_t prev;
prev.whole_ = _InterlockedCompareExchange64
(&head_.whole_, xchg.whole_, h.whole_);
if (prev.whole_ == h.whole_)
{
node_t* prev_tail = (node_t*)
_InterlockedCompareExchange
((long*)&tail_, (long)&head_.ptr_, (long)n);
if (prev_tail == n)
return n;
// spinning here may only be caused
// by producer preempted in (***)
while (n->next_ == 0)
SwitchToThread();
head_.ptr_ = n->next_;
return n;
}
h.ptr_ = prev.ptr_;
h.cnt_ = prev.cnt_;
}
}
}
__except ((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
&& ++retry_count < 64*1024) ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
goto retry;
}
}
private:
union head_t
{
struct
{
node_t* ptr_;
unsigned cnt_;
};
__int64 whole_;
};
head_t volatile head_;
char pad_ [64];
node_t* volatile* volatile tail_;
mpmc_queue(mpmc_queue const&);
mpmc_queue& operator = (mpmc_queue const&);
long m_size;
};
@@ -0,0 +1,130 @@
#pragma once
#include <deque>
#include <list>
#include "mpmc_queue.h"
template <class Type>
class MPMC_MemPooler
{
struct PoolElement
{
Type data;
mpmc_queue::node_t node;
};
public:
MPMC_MemPooler(int numofBlock=0, int maximumBlock=0 ) :
m_allocCount(32),
m_numofBlock(numofBlock),
m_maximumBlock(maximumBlock)
{
Create(numofBlock);
}
~MPMC_MemPooler()
{
Destroy();
}
public:
void CreatePool(const int numofBlock, const int maximumBlock=0 )
{
m_numofBlock = 0;
m_maximumBlock = maximumBlock;
Create(numofBlock);
}
void DestroyPool()
{
Destroy();
}
public:
Type* Pop()
{
return Get();
}
Type* Remove()
{
if(m_memPooler.empty())
return (NULL);
return Get();
}
void CreatePush(Type* block)
{
if(m_numofBlock < m_maximumBlock)
{
PoolElement* memBlock = new PoolElement;
if(memBlock)
{
memcpy(&memBlock->data,block,sizeof(Type));
m_memPooler.enqueue(&memBlock->node);
}
m_numofBlock++;
}
delete block;
}
void Push(Type* block)
{
if(block == NULL)
return;
PoolElement* tmpdata = reinterpret_cast<PoolElement*>(block);
m_memPooler.enqueue(&tmpdata->node);
}
int GetCount() { return m_memPooler.size(); }
int GetTotalCount() { return m_numofBlock; }
protected:
void Create(const int numofBlock)
{
if(numofBlock <= 0) return;
for(int i = 0 ; i < numofBlock ; i++)
{
PoolElement *memBlock = new PoolElement;
if(memBlock)
m_memPooler.enqueue(&memBlock->node);
}
m_numofBlock += numofBlock;
}
void Destroy()
{
mpmc_queue::node_t* pnode = m_memPooler.dequeue();
PoolElement* tmpdata = CONTAINING_RECORD(pnode,PoolElement,node);
while(tmpdata)
{
delete tmpdata;
mpmc_queue::node_t* pnode = m_memPooler.dequeue();
if(pnode == NULL)
break;
tmpdata = CONTAINING_RECORD(pnode,PoolElement,node);
}
}
Type* Get()
{
Type* block = NULL;
if(!m_memPooler.empty())
{
mpmc_queue::node_t* pnode = m_memPooler.dequeue();
PoolElement* tmpdata = CONTAINING_RECORD(pnode,PoolElement,node);
block = reinterpret_cast<Type*>(tmpdata);
}
else
{
if(m_numofBlock < m_maximumBlock)
{
int allocCount = m_maximumBlock - m_numofBlock;
(allocCount > m_allocCount) ? Create(m_allocCount) : Create(allocCount);
mpmc_queue::node_t* pnode = m_memPooler.dequeue();
PoolElement* tmpdata = CONTAINING_RECORD(pnode,PoolElement,node);
block = reinterpret_cast<Type*>(tmpdata);
}
}
return (block);
}
protected:
int m_allocCount;
int m_numofBlock;
int m_maximumBlock;
mpmc_queue m_memPooler;
};
+8
View File
@@ -0,0 +1,8 @@
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
// testQueue.pch는 미리 컴파일된 헤더가 됩니다.
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
#include "stdafx.h"
// TODO: 필요한 추가 헤더는
// 이 파일이 아닌 STDAFX.H에서 참조합니다.
+18
View File
@@ -0,0 +1,18 @@
// stdafx.h : 자주 사용하지만 자주 변경되지는 않는
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
// 들어 있는 포함 파일입니다.
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
// TODO: 프로그램에 필요한 추가 헤더는 여기에서 참조합니다.
#include <boost/timer.hpp>
#include <boost/thread.hpp>
#include "TMPSCQueue.h"
#include "common.h"
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// SDKDDKVer.h를 포함하면 최고 수준의 가용성을 가진 Windows 플랫폼이 정의됩니다.
// 이전 Windows 플랫폼에 대해 응용 프로그램을 빌드하려는 경우에는 SDKDDKVer.h를 포함하기 전에
// WinSDKVer.h를 포함하고 _WIN32_WINNT 매크로를 지원하려는 플랫폼으로 설정하십시오.
#include <SDKDDKVer.h>
+106
View File
@@ -0,0 +1,106 @@
// testQueue.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include <iostream>
#include <set>
#include <conio.h>
#include "TestMPSCQueue.h"
//#include "TestIOCPQueue.h"
#include "TestMPMCQueue.h"
#include "TestWFQueue.h"
#include "TestMPMCMemoryPool.h"
INT G_TESTCOUNT = 1000000;
LONG G_NUMBER = 0;
BOOL G_TERMINATE = FALSE;
int _tmain(int argc, _TCHAR* argv[])
{
while(1)
{
printf("\t\t ===========================================\t\t\n");
printf("\t\t >> [0] Run MPSC QueueTest\n");
printf("\t\t >> [1] Run IOCP QueueTest\n");
printf("\t\t >> [2] Run MPMC QueueTest\n");
printf("\t\t >> [3] Run MPMC MemoryPoolTest\n");
printf("\t\t >> [4] Run WF QueueTest\n");
printf("\t\t >> [q] Quit TestQueue Program\n");
printf("\t\t >> ========================================\t\t\n\n");
printf("\t\t >> Input : ");
char c;
std::cin >> c;
switch(c)
{
case 'Q':
case 'q':
{
break;
}
break;
case '0':
{
int count;
printf("Thread Count : ");
scanf_s("%d", &count);
for(int i = 0 ; i < 20 ; i++)
{
TestMPSCQueue* m = new TestMPSCQueue(count);
m->Run();
delete m;
}
}
break;
case '1':
{
//TestIOCPQueue* m = new TestIOCPQueue;
//m->Run();
//delete m;
}
break;
case '2':
{
TestMPMCQueue* m = new TestMPMCQueue;
m->Run();
delete m;
}
break;
case '3':
{
TestMPMCMemoryPool* m = new TestMPMCMemoryPool;
m->Run();
delete m;
}
break;
case '4':
{
int count;
printf("Thread Count : ");
scanf_s("%d", &count);
for(int i = 0 ; i < 20 ; i++)
{
TestWFQueue* m = new TestWFQueue(count);
m->Run();
delete m;
}
}
break;
}
}
return 0;
}
+118
View File
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3C73F9FB-7352-4742-BE16-02B9152B8F82}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>testQueue</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files (x86)\boost\boost_1_47\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Program Files %28x86%29\boost\boost_1_47\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>100000000</StackReserveSize>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../../src/iocpSocketDLL;C:\Program Files (x86)\boost\boost_1_47\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>../../../lib;C:\Program Files %28x86%29\boost\boost_1_47\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>iocpsocketdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DATA.h" />
<ClInclude Include="MPMCMemPool.h" />
<ClInclude Include="MPMCQueue.h" />
<ClInclude Include="mpmc_queue.h" />
<ClInclude Include="mpmc_seh_mempool.h" />
<ClInclude Include="MPSCQueue.h" />
<ClInclude Include="TestMPMCMemoryPool.h" />
<ClInclude Include="TestMPMCQueue.h" />
<ClInclude Include="TestWFQueue.h" />
<ClInclude Include="TMPSCQueue.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="TestCase.h" />
<ClInclude Include="TestMPSCQueue.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="mpmc_queue.cpp" />
<ClCompile Include="MPSCQueue.cpp" />
<ClCompile Include="TestMPMCMemoryPool.cpp" />
<ClCompile Include="TestMPMCQueue.cpp" />
<ClCompile Include="TestWFQueue.cpp" />
<ClCompile Include="TMPSCQueue.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="TestCase.cpp" />
<ClCompile Include="TestMPSCQueue.cpp" />
<ClCompile Include="testQueue.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="소스 파일">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="헤더 파일">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="리소스 파일">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="TestCase">
<UniqueIdentifier>{4f0bb767-8c95-41a7-96c4-44641f4eb77c}</UniqueIdentifier>
</Filter>
<Filter Include="Queue">
<UniqueIdentifier>{f3e81d52-bfe9-4643-a59a-04fcbee67702}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="TestMPSCQueue.h">
<Filter>TestCase</Filter>
</ClInclude>
<ClInclude Include="TestCase.h">
<Filter>TestCase</Filter>
</ClInclude>
<ClInclude Include="MPMCQueue.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="TestMPMCQueue.h">
<Filter>TestCase</Filter>
</ClInclude>
<ClInclude Include="mpmc_queue.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="MPMCMemPool.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="MPMCMemPool.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="mpmc_seh_mempool.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="TestMPMCMemoryPool.h">
<Filter>TestCase</Filter>
</ClInclude>
<ClInclude Include="MPSCQueue.h">
<Filter>Queue</Filter>
</ClInclude>
<ClInclude Include="TMPSCQueue.h">
<Filter>Queue</Filter>
</ClInclude>
<ClInclude Include="TestWFQueue.h">
<Filter>TestCase</Filter>
</ClInclude>
<ClInclude Include="DATA.h">
<Filter>TestCase</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="testQueue.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="TestCase.cpp">
<Filter>TestCase</Filter>
</ClCompile>
<ClCompile Include="TestMPSCQueue.cpp">
<Filter>TestCase</Filter>
</ClCompile>
<ClCompile Include="TestMPMCQueue.cpp">
<Filter>TestCase</Filter>
</ClCompile>
<ClCompile Include="mpmc_queue.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="TestMPMCMemoryPool.cpp">
<Filter>TestCase</Filter>
</ClCompile>
<ClCompile Include="MPSCQueue.cpp">
<Filter>Queue</Filter>
</ClCompile>
<ClCompile Include="TMPSCQueue.cpp">
<Filter>Queue</Filter>
</ClCompile>
<ClCompile Include="TestWFQueue.cpp">
<Filter>TestCase</Filter>
</ClCompile>
</ItemGroup>
</Project>