push() 하면 memcpy 가 일어나지만 getBuffer() 함수를 사용하면 push할 버퍼의 포인터를 가져와 엑세스하므로 퍼포먼스를 향상시킬수 있다.
< BufferQueue.h >
#ifndef __BUFFER_QUEUE_H__
#define __BUFFER_QUEUE_H__
#include <windows.h>
#define BUF_SIZE (1024*1024*8)
#define BUF_ELEM_SIZE (30)
typedef struct BufferElement_t {
int len;
char buffer[BUF_SIZE];
BufferElement_t *next;
} BufferElement;
class BufferQueue
{
public:
BufferQueue();
~BufferQueue();
int count;
int push(char *buffer, int len);
BufferElement* pop();
void clear();
BufferElement* getBuffer();
void releaseBuffer();
protected:
BufferElement *head, *tail;
HANDLE hBufferLock;
};
#endif
< BufferQueue.cpp >
#include "BufferQueue.h"
BufferQueue::BufferQueue()
{
count = 0;
hBufferLock = CreateMutex(NULL, FALSE, NULL);
BufferElement *prev = new BufferElement;
prev->len = 0;
head = tail = prev;
for (int i=0; i < BUF_ELEM_SIZE; i++)
{
BufferElement *elem = new BufferElement;
elem->len = 0;
prev->next = elem;
prev = elem;
}
prev->next = head;
}
BufferQueue::~BufferQueue()
{
WaitForSingleObject(hBufferLock, INFINITE);
BufferElement *tmp;
BufferElement *elem = head;
for (int i=0; i < BUF_ELEM_SIZE; i++) {
tmp = elem;
elem = elem->next;
if (tmp)
delete tmp;
}
if (elem)
delete elem;
count = 0;
ReleaseMutex(hBufferLock);
CloseHandle(hBufferLock);
}
BufferElement* BufferQueue::getBuffer()
{
WaitForSingleObject(hBufferLock, INFINITE);
if (count >= BUF_ELEM_SIZE) {
ReleaseMutex(hBufferLock);
return NULL;
}
BufferElement *elem = tail;
tail = tail->next;
count++;
//ReleaseMutex(hBufferLock);
return elem;
}
void BufferQueue::releaseBuffer()
{
ReleaseMutex(hBufferLock);
}
int BufferQueue::push(char *buffer, int len)
{
WaitForSingleObject(hBufferLock, INFINITE);
if (count >= BUF_ELEM_SIZE) {
ReleaseMutex(hBufferLock);
return -1;
}
if (len >= BUF_SIZE) {
ReleaseMutex(hBufferLock);
return -2;
}
tail->len = len;
memcpy(tail->buffer, buffer, len);
tail = tail->next;
count++;
ReleaseMutex(hBufferLock);
return count;
}
BufferElement* BufferQueue::pop()
{
WaitForSingleObject(hBufferLock, INFINITE);
if (count <= 0) {
ReleaseMutex(hBufferLock);
return NULL;
}
BufferElement *elem = head;
head = head->next;
count--;
ReleaseMutex(hBufferLock);
return elem;
}
void BufferQueue::clear()
{
WaitForSingleObject(hBufferLock, INFINITE);
count = 0;
tail = head;
ReleaseMutex(hBufferLock);
}
댓글 없음:
댓글 쓰기