Skip to content

Instantly share code, notes, and snippets.

@indication
Created May 19, 2017 15:44
Show Gist options
  • Save indication/7f8f54bceb08093ad21807d6770e18cc to your computer and use it in GitHub Desktop.
Save indication/7f8f54bceb08093ad21807d6770e18cc to your computer and use it in GitHub Desktop.
ring buffer
typedef struct _SListBuffer {
struct _SRingBuffer * next;
void * pData;
size_t DataSize;
long int Status;
}SListBuffer;
typedef struct _SRingBuffer {
SListBuffer * ListHead;
SListBuffer * ListBottom;
unsigned int Length;
unsigned int Dummy;
pthread_mutex_t MutexLocker;
}SRingBuffer;
typedef enum _EDRingBufferReturnCode{
D_RING_BUFFER_MEMORY_ERROR = -16,
D_RING_BUFFER_MUTEX_ERROR,
D_RING_BUFFER_PARAM_ERROR,
D_RING_BUFFER_SUCCESS = 0,
}EDRingBufferReturnCode;
int RingBufferInitialize(SRingBuffer ** ppRingBuffer){
SRingBuffer * pRingBuffer = NULL;
if(!pRingBuffer)
{
return D_RING_BUFFER_PARAM_ERROR;
}
pRingBuffer = *ppRingBuffer;
if(pRingBuffer)
{
return D_RING_BUFFER_PARAM_ERROR;
}
pRingBuffer = (SRingBuffer*) malloc (sizeof(SRingBuffer));
if(pRingBuffer){
return D_RING_BUFFER_MEMORY_ERROR;
}
memset(pRingBuffer,0x00,sizeof(SRingBuffer));
pthread_mutex_init(&(pRingBuffer->MutexLocker), NULL);
if(pthread_mutex_lock(&(pRingBuffer->MutexLocker)) != 0)
{
free(pRingBuffer);
return D_RING_BUFFER_MUTEX_ERROR;
}
*ppRingBuffer = pRingBuffer;
pthread_mutex_unlock(&(pRingBuffer->MutexLocker));
return D_RING_BUFFER_SUCCESS;
}
int RingBufferDestroy(SRingBuffer ** ppRingBuffer)
{
SRingBuffer * pRingBuffer = NULL;
SListBuffer * pListCurrent= NULL;
SListBuffer * pListBuffer = NULL;
if(!pRingBuffer)
{
return D_RING_BUFFER_PARAM_ERROR;
}
pRingBuffer = *ppRingBuffer;
if(!pRingBuffer)
{
/* すでに解放済みなのでエラーとしない */
return D_RING_BUFFER_SUCCESS;
}
pthread_mutex_lock(&(pRingBuffer->MutexLocker));
*ppRingBuffer = NULL;
/* リング構造を破棄し、リスト構造にする(NULL終端) */
pListCurrent = pRingBuffer->ListBottom->next;
pRingBuffer->ListBottom->next = NULL;
while(pListCurrent){
pListBuffer = pListCurrent;
if(pListCurrent->pData){
free(pListCurrent->pData);
pListCurrent->pData = NULL;
}
pListCurrent->DataSize = 0;
pListCurrent = pListCurrent->next;
free(pListBuffer);
pListBuffer = NULL;
}
pthread_mutex_unlock(&(pRingBuffer->MutexLocker));
pthread_mutex_destroy(&(pRingBuffer->MutexLocker));
free(pRingBuffer);
return D_RING_BUFFER_SUCCESS;
}
int RingBufferAllocate(SRingBuffer ** ppRingBuffer,size_t zSize)
{
SRingBuffer * pRingBuffer = NULL;
SListBuffer * pListBuffer = NULL;
void * pvData = NULL;
if(!pRingBuffer)
{
return D_RING_BUFFER_PARAM_ERROR;
}
pRingBuffer = *ppRingBuffer;
if(!pRingBuffer)
{
return D_RING_BUFFER_PARAM_ERROR;
}
pvData = (void *) malloc (zSize);
pListBuffer = (SListBuffer*) malloc (sizeof(SListBuffer));
if(!pvData || !pListBuffer)
{
if(pvData)
{
free(pvData);
}
if(pListBuffer)
{
free(pListBuffer);
}
return D_RING_BUFFER_MEMORY_ERROR;
}
/* 初期化 */
memset(pvData , 0x00, zSize );
memset(pListBuffer , 0x00, sizeof(SListBuffer) );
/* あらかじめリスト情報を更新しておく */
pListBuffer->pData = pvData;
pListBuffer->DataSize = zSize;
/* 管理情報と連結する */
/* !!Mutex LOCK */
if(pthread_mutex_lock(&(pRingBuffer->MutexLocker)) != 0)
{
free(pvData);
free(pListBuffer);
return D_RING_BUFFER_MUTEX_ERROR;
}
if(!*ppRingBuffer)
{
/* 通常ありえない */
free(pvData);
free(pListBuffer);
return D_RING_BUFFER_MEMORY_ERROR;
}
if(pRingBuffer->ListBottom)
{
pListBuffer->next = pRingBuffer->ListBottom->next;
} else {
pRingBuffer->ListBottom = pListBuffer;
}
pRingBuffer->ListBottom->next = pListBuffer;
(pRingBuffer->Length)++;
/* !!Mutex UNlock */
pthread_mutex_unlock(&(pRingBuffer->MutexLocker));
return D_RING_BUFFER_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment