|
6 | 6 | */ |
7 | 7 | #include "RingBuf.h" |
8 | 8 | #include <string.h> |
| 9 | +#include <util/atomic.h> |
9 | 10 |
|
10 | 11 | /////// Constructor ////////// |
11 | 12 | RingBuf *RingBuf_new(int size, int len) |
@@ -83,56 +84,97 @@ int RingBufIncrStart(RingBuf *self) |
83 | 84 | // Add an object struct to RingBuf |
84 | 85 | int RingBufAdd(RingBuf *self, void *object) |
85 | 86 | { |
86 | | - int index = self->next_end_index(self); |
87 | | - if (index < 0) return -1; |
88 | | - memcpy(self->buf + index*self->size, object, self->size); |
89 | | - //if not empty incriment end index |
90 | | - if (!self->isEmpty(self)) self->incr_end_index(self); |
91 | | - self->elements++; |
92 | | - return index; |
| 87 | + int index; |
| 88 | + // Perform all atomic opertaions |
| 89 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
| 90 | + { |
| 91 | + index = self->next_end_index(self); |
| 92 | + //if not full |
| 93 | + if (index >= 0) |
| 94 | + { |
| 95 | + if (!self->isEmpty(self)) self->incr_end_index(self); |
| 96 | + self->elements++; |
| 97 | + memcpy(self->buf + index*self->size, object, self->size); |
| 98 | + } |
| 99 | + } |
93 | 100 |
|
| 101 | + return index; |
94 | 102 | } |
95 | 103 |
|
96 | 104 | // Return pointer to num element, return null on empty or num out of bounds |
97 | 105 | void *RingBufPeek(RingBuf *self, unsigned int num) |
98 | 106 | { |
99 | | - //empty or out of bounds |
100 | | - if (self->isEmpty(self) || num > self->elements - 1) return NULL; |
101 | | - |
102 | | - return &self->buf[((self->start + num)%self->len)*self->size]; |
| 107 | + void *ret; |
| 108 | + // Perform all atomic opertaions |
| 109 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
| 110 | + { |
| 111 | + //empty or out of bounds |
| 112 | + if (self->isEmpty(self) || num > self->elements - 1) ret = NULL; |
| 113 | + else ret = &self->buf[((self->start + num)%self->len)*self->size]; |
| 114 | + } |
| 115 | + return ret; |
103 | 116 | } |
104 | 117 |
|
105 | 118 | // Returns and removes first buffer element |
106 | 119 | void *RingBufPull(RingBuf *self, void *object) |
107 | 120 | { |
108 | | - if (self->isEmpty(self)) return NULL; |
109 | | - // Copy Object |
110 | | - memcpy(object, self->buf+self->start*self->size, self->size); |
111 | | - //Don't mess things up to much, even if called on an empty buffer |
112 | | - if (!self->isEmpty(self)) |
| 121 | + void *ret; |
| 122 | + // Perform all atomic opertaions |
| 123 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
113 | 124 | { |
114 | | - self->elements--; |
115 | | - // don't incriment if removing last element |
116 | | - if (!self->isEmpty(self)) self->incr_start_index(self); |
| 125 | + if (self->isEmpty(self)) ret = NULL; |
| 126 | + // Else copy Object |
| 127 | + else |
| 128 | + { |
| 129 | + memcpy(object, self->buf+self->start*self->size, self->size); |
| 130 | + self->elements--; |
| 131 | + // don't incriment start if removing last element |
| 132 | + if (!self->isEmpty(self)) self->incr_start_index(self); |
| 133 | + ret = object; |
| 134 | + } |
117 | 135 | } |
118 | 136 |
|
119 | | - return object; |
| 137 | + return ret; |
120 | 138 | } |
121 | 139 |
|
122 | 140 | // Returns number of elemnts in buffer |
123 | 141 | unsigned int RingBufNumElements(RingBuf *self) |
124 | 142 | { |
125 | | - return self->elements; |
| 143 | + unsigned int elements; |
| 144 | + |
| 145 | + // Perform all atomic opertaions |
| 146 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
| 147 | + { |
| 148 | + elements = self->elements; |
| 149 | + } |
| 150 | + |
| 151 | + return elements; |
126 | 152 | } |
127 | 153 |
|
128 | 154 | // Returns true if buffer is full |
129 | 155 | bool RingBufIsFull(RingBuf *self) |
130 | 156 | { |
131 | | - return self->elements == self->len; |
| 157 | + bool ret; |
| 158 | + |
| 159 | + // Perform all atomic opertaions |
| 160 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
| 161 | + { |
| 162 | + ret = self->elements == self->len; |
| 163 | + } |
| 164 | + |
| 165 | + return ret; |
132 | 166 | } |
133 | 167 |
|
134 | 168 | // Returns true if buffer is empty |
135 | 169 | bool RingBufIsEmpty(RingBuf *self) |
136 | 170 | { |
137 | | - return !self->elements; |
| 171 | + bool ret; |
| 172 | + |
| 173 | + // Perform all atomic opertaions |
| 174 | + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
| 175 | + { |
| 176 | + ret = !self->elements; |
| 177 | + } |
| 178 | + |
| 179 | + return ret; |
138 | 180 | } |
0 commit comments