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 CirqBufferType CirqBuffStatCreate(void *buffer, int maxCnt, size_t dataSize) {
50 CirqBufferType cirqbuffer;
51 cirqbuffer.bufStart = buffer;
52 cirqbuffer.maxCnt = maxCnt;
53 cirqbuffer.bufEnd = (char *)cirqbuffer.bufStart + dataSize*maxCnt;
54 cirqbuffer.head = cirqbuffer.bufStart;
55 cirqbuffer.tail = cirqbuffer.bufStart;
56 cirqbuffer.dataSize = dataSize;
57 cirqbuffer.currCnt = 0;
61 CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
63 cPtr = malloc(sizeof(CirqBufferType));
68 cPtr->dataSize = dataSize;
69 cPtr->bufStart = malloc(dataSize*size);
70 cPtr->bufEnd = (char *)cPtr->bufStart + dataSize*size;
71 cPtr->head = cPtr->bufStart;
72 cPtr->tail = cPtr->bufStart;
79 int CirqBuffDynDestroy(CirqBufferType *cPtr ) {
85 int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr ) {
88 if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
90 return 1; /* No more room */
92 MEMCPY(cPtr->head,dataPtr,cPtr->dataSize);
93 cPtr->head = (char *)cPtr->head + cPtr->dataSize;
94 if( cPtr->head == cPtr->bufEnd) {
95 cPtr->head = cPtr->bufStart;
103 int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr ) {
106 if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
110 MEMCPY(dataPtr,cPtr->tail,cPtr->dataSize);
111 cPtr->tail = (char *)cPtr->tail + cPtr->dataSize;
112 if( cPtr->tail == cPtr->bufEnd) {
113 cPtr->tail = cPtr->bufStart;
122 #ifdef _TEST_CIRQ_BUFFER_DYN_
124 CirqBufferType *cPtr;
130 cPtr = CirqBuffDynCreate(QSIZE, DATA_SIZE );
132 dataPtr = malloc(DATA_SIZE);
134 rv = CirqBuffPush(cPtr,dataPtr);
138 dataPtr = malloc(DATA_SIZE);
140 rv = CirqBuffPush(cPtr,dataPtr);
144 dataPtr = malloc(DATA_SIZE);
145 rv = CirqBuffPop(cPtr,dataPtr);
146 assert( dataPtr[0] == 1);
150 dataPtr = malloc(DATA_SIZE);
151 rv = CirqBuffPop(cPtr,dataPtr);
152 assert( dataPtr[0] == 2);
156 CirqBuffDynDestroy(cPtr);