]> rtime.felk.cvut.cz Git - arc.git/blob - common/cirq_buffer.c
Merge with ab77725379707368849e4deb9329876662bdc750
[arc.git] / common / cirq_buffer.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
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>.
9  *
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
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15 /*
16  * DESCRIPTION
17  *  A circular buffer implementation.
18  *
19  *  This file implements the following versions:
20  *  1. CirqBuffDynXXXX
21  *     - The size of the data is not known of compile time
22  *       (semidynamic, since there is no free() function )
23  *  2. CirqBuffXXX
24  *     - A static implementation, data is known at compile time.
25  *       (implemented in the header file?)
26  *
27  * Implementation note:
28  * - CirqBuffDynXXXX, valgrind: OK
29  * - coverage: Not run
30  *
31  */
32 //#define _TEST_CIRQ_BUFFER_DYN_
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdint.h>
36 #include "Cpu.h"
37 #include "cirq_buffer.h"
38
39 #ifdef _TEST_CIRQ_BUFFER_DYN_
40 #include <assert.h>
41 #endif
42
43 #define MEMCPY(_x,_y,_z)        __builtin_memcpy(_x,_y,_z)
44 //#define MEMCPY(_x,_y,_z)      memcpy(_x,_y,_z)
45
46
47 /* TODO: Not threadsafe, add DisableAllInterrts()/EnableAllInterrupts() */
48
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;
58         return cirqbuffer;
59 }
60
61 CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
62         CirqBufferType *cPtr;
63         cPtr = malloc(sizeof(CirqBufferType));
64         if( cPtr == NULL ) {
65                 return NULL;
66         }
67         cPtr->maxCnt = size;
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;
73         cPtr->currCnt = 0;
74         return cPtr;
75 }
76
77
78
79 int CirqBuffDynDestroy(CirqBufferType *cPtr ) {
80         free(cPtr->bufStart);
81         free(cPtr);
82         return 0;
83 }
84
85 int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr ) {
86         uint32_t flags;
87         Irq_Save(flags);
88         if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
89                 Irq_Restore(flags);
90                 return 1;       /* No more room */
91         }
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;
96         }
97         ++cPtr->currCnt;
98         Irq_Restore(flags);
99
100         return 0;
101 }
102
103 int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr ) {
104         uint32_t flags;
105         Irq_Save(flags);
106         if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
107                 Irq_Restore(flags);
108                 return 1;
109         }
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;
114         }
115         --cPtr->currCnt;
116         Irq_Restore(flags);
117         return 0;
118 }
119
120
121
122 #ifdef _TEST_CIRQ_BUFFER_DYN_
123 int main( void ) {
124         CirqBufferType *cPtr;
125         uint8_t *dataPtr;
126         int rv;
127
128 #define DATA_SIZE       4
129 #define QSIZE           8
130         cPtr = CirqBuffDynCreate(QSIZE, DATA_SIZE );
131
132         dataPtr = malloc(DATA_SIZE);
133         dataPtr[0] = 1;
134         rv  = CirqBuffPush(cPtr,dataPtr);
135         assert(rv == 0);
136         free(dataPtr);
137
138         dataPtr = malloc(DATA_SIZE);
139         dataPtr[0] = 2;
140         rv  = CirqBuffPush(cPtr,dataPtr);
141         assert(rv == 0);
142         free(dataPtr);
143
144         dataPtr = malloc(DATA_SIZE);
145         rv = CirqBuffPop(cPtr,dataPtr);
146         assert( dataPtr[0] == 1);
147         assert(rv == 0);
148         free(dataPtr);
149
150         dataPtr = malloc(DATA_SIZE);
151         rv = CirqBuffPop(cPtr,dataPtr);
152         assert( dataPtr[0] == 2);
153         assert(rv == 0);
154         free(dataPtr);
155
156         CirqBuffDynDestroy(cPtr);
157 }
158 #endif
159
160