1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
17 * A circular buffer implementation.
19 * This file implements the following versions:
21 * - The size of the data is not known of compile time
22 * (semidynamic, since there is no free() function )
24 * - A static implementation, data is known at compile time.
25 * (implemented in the header file?)
27 * Implementation note:
28 * - CirqBuffDynXXXX, valgrind: OK
32 //#define _TEST_CIRQ_BUFFER_DYN_
37 #include "cirq_buffer.h"
39 #ifdef _TEST_CIRQ_BUFFER_DYN_
44 #define MEMCPY(_x,_y,_z) __builtin_memcpy(_x,_y,_z)
46 #define MEMCPY(_x,_y,_z) memcpy(_x,_y,_z)
48 //#define MEMCPY(_x,_y,_z) memcpy(_x,_y,_z)
51 /* TODO: Not threadsafe, add DisableAllInterrts()/EnableAllInterrupts() */
53 void CirqBuff_Init(CirqBufferType *cirqbuffer, void *buffer, int maxCnt, size_t dataSize) {
54 cirqbuffer->bufStart = buffer;
55 cirqbuffer->maxCnt = maxCnt;
56 cirqbuffer->bufEnd = (char *)cirqbuffer->bufStart + dataSize*maxCnt;
57 cirqbuffer->head = cirqbuffer->bufStart;
58 cirqbuffer->tail = cirqbuffer->bufStart;
59 cirqbuffer->dataSize = dataSize;
60 cirqbuffer->currCnt = 0;
64 CirqBufferType CirqBuffStatCreate(void *buffer, int maxCnt, size_t dataSize) {
65 CirqBufferType cirqbuffer;
66 cirqbuffer.bufStart = buffer;
67 cirqbuffer.maxCnt = maxCnt;
68 cirqbuffer.bufEnd = (char *)cirqbuffer.bufStart + dataSize*maxCnt;
69 cirqbuffer.head = cirqbuffer.bufStart;
70 cirqbuffer.tail = cirqbuffer.bufStart;
71 cirqbuffer.dataSize = dataSize;
72 cirqbuffer.currCnt = 0;
73 /*return whole object */
77 CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
79 cPtr = malloc(sizeof(CirqBufferType));
84 cPtr->dataSize = dataSize;
85 cPtr->bufStart = malloc(dataSize*size);
86 cPtr->bufEnd = (char *)cPtr->bufStart + dataSize*size;
87 cPtr->head = cPtr->bufStart;
88 cPtr->tail = cPtr->bufStart;
95 int CirqBuffDynDestroy(CirqBufferType *cPtr ) {
101 int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr ) {
104 if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
106 return 1; /* No more room */
108 MEMCPY(cPtr->head,dataPtr,cPtr->dataSize);
109 cPtr->head = (char *)cPtr->head + cPtr->dataSize;
110 if( cPtr->head == cPtr->bufEnd) {
111 cPtr->head = cPtr->bufStart;
121 int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr ) {
124 if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
128 MEMCPY(dataPtr,cPtr->tail,cPtr->dataSize);
129 cPtr->tail = (char *)cPtr->tail + cPtr->dataSize;
130 if( cPtr->tail == cPtr->bufEnd) {
131 cPtr->tail = cPtr->bufStart;
138 void *CirqBuff_PushLock( CirqBufferType *cPtr) {
140 if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
141 return NULL; /* No more room */
143 dataPtr = cPtr->head;
144 cPtr->head = (char *)cPtr->head + cPtr->dataSize;
145 if( cPtr->head == cPtr->bufEnd) {
146 cPtr->head = cPtr->bufStart;
152 void * CirqBuff_PopLock(CirqBufferType *cPtr ) {
154 if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
157 dataPtr = cPtr->tail;
158 cPtr->tail = (char *)cPtr->tail + cPtr->dataSize;
159 if( cPtr->tail == cPtr->bufEnd) {
160 cPtr->tail = cPtr->bufStart;
168 #ifdef _TEST_CIRQ_BUFFER_DYN_
170 CirqBufferType *cPtr;
176 cPtr = CirqBuffDynCreate(QSIZE, DATA_SIZE );
178 dataPtr = malloc(DATA_SIZE);
180 rv = CirqBuffPush(cPtr,dataPtr);
184 dataPtr = malloc(DATA_SIZE);
186 rv = CirqBuffPush(cPtr,dataPtr);
190 dataPtr = malloc(DATA_SIZE);
191 rv = CirqBuffPop(cPtr,dataPtr);
192 assert( dataPtr[0] == 1);
196 dataPtr = malloc(DATA_SIZE);
197 rv = CirqBuffPop(cPtr,dataPtr);
198 assert( dataPtr[0] == 2);
202 CirqBuffDynDestroy(cPtr);