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_
43 #define MEMCPY(_x,_y,_z) __builtin_memcpy(_x,_y,_z)
44 //#define MEMCPY(_x,_y,_z) memcpy(_x,_y,_z)
47 /* TODO: Not threadsafe, add DisableAllInterrts()/EnableAllInterrupts() */
49 void CirqBuff_Init(CirqBufferType *cirqbuffer, void *buffer, int maxCnt, size_t dataSize) {
50 cirqbuffer->bufStart = buffer;
51 cirqbuffer->maxCnt = maxCnt;
52 cirqbuffer->bufEnd = (char *)cirqbuffer->bufStart + dataSize*maxCnt;
53 cirqbuffer->head = cirqbuffer->bufStart;
54 cirqbuffer->tail = cirqbuffer->bufStart;
55 cirqbuffer->dataSize = dataSize;
56 cirqbuffer->currCnt = 0;
61 CirqBufferType CirqBuffStatCreate(void *buffer, int maxCnt, size_t dataSize) {
62 CirqBufferType cirqbuffer;
63 cirqbuffer.bufStart = buffer;
64 cirqbuffer.maxCnt = maxCnt;
65 cirqbuffer.bufEnd = (char *)cirqbuffer.bufStart + dataSize*maxCnt;
66 cirqbuffer.head = cirqbuffer.bufStart;
67 cirqbuffer.tail = cirqbuffer.bufStart;
68 cirqbuffer.dataSize = dataSize;
69 cirqbuffer.currCnt = 0;
70 #error returning AUTO variable......
75 CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
77 cPtr = malloc(sizeof(CirqBufferType));
82 cPtr->dataSize = dataSize;
83 cPtr->bufStart = malloc(dataSize*size);
84 cPtr->bufEnd = (char *)cPtr->bufStart + dataSize*size;
85 cPtr->head = cPtr->bufStart;
86 cPtr->tail = cPtr->bufStart;
93 int CirqBuffDynDestroy(CirqBufferType *cPtr ) {
99 int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr ) {
102 if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
104 return 1; /* No more room */
106 MEMCPY(cPtr->head,dataPtr,cPtr->dataSize);
107 cPtr->head = (char *)cPtr->head + cPtr->dataSize;
108 if( cPtr->head == cPtr->bufEnd) {
109 cPtr->head = cPtr->bufStart;
119 int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr ) {
122 if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
126 MEMCPY(dataPtr,cPtr->tail,cPtr->dataSize);
127 cPtr->tail = (char *)cPtr->tail + cPtr->dataSize;
128 if( cPtr->tail == cPtr->bufEnd) {
129 cPtr->tail = cPtr->bufStart;
136 void *CirqBuff_PushLock( CirqBufferType *cPtr) {
138 if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
139 return NULL; /* No more room */
141 dataPtr = cPtr->head;
142 cPtr->head = (char *)cPtr->head + cPtr->dataSize;
143 if( cPtr->head == cPtr->bufEnd) {
144 cPtr->head = cPtr->bufStart;
150 void * CirqBuff_PopLock(CirqBufferType *cPtr ) {
152 if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
155 dataPtr = cPtr->tail;
156 cPtr->tail = (char *)cPtr->tail + cPtr->dataSize;
157 if( cPtr->tail == cPtr->bufEnd) {
158 cPtr->tail = cPtr->bufStart;
166 #ifdef _TEST_CIRQ_BUFFER_DYN_
168 CirqBufferType *cPtr;
174 cPtr = CirqBuffDynCreate(QSIZE, DATA_SIZE );
176 dataPtr = malloc(DATA_SIZE);
178 rv = CirqBuffPush(cPtr,dataPtr);
182 dataPtr = malloc(DATA_SIZE);
184 rv = CirqBuffPush(cPtr,dataPtr);
188 dataPtr = malloc(DATA_SIZE);
189 rv = CirqBuffPop(cPtr,dataPtr);
190 assert( dataPtr[0] == 1);
194 dataPtr = malloc(DATA_SIZE);
195 rv = CirqBuffPop(cPtr,dataPtr);
196 assert( dataPtr[0] == 2);
200 CirqBuffDynDestroy(cPtr);