Have circle buffer work when memory is misaligned
Jeffrey Pfau jeffrey@endrift.com
Thu, 16 Jan 2014 01:56:17 -0800
1 files changed,
58 insertions(+),
2 deletions(-)
jump to
M
src/util/circle-buffer.c
→
src/util/circle-buffer.c
@@ -3,6 +3,21 @@
#include <stddef.h> #include <stdlib.h> +#ifndef NDEBUG +static int _checkIntegrity(struct CircleBuffer* buffer) { + if ((int8_t*) buffer->writePtr - (int8_t*) buffer->readPtr == buffer->size) { + return 1; + } + if (buffer->capacity - buffer->size == ((int8_t*) buffer->writePtr - (int8_t*) buffer->readPtr)) { + return 1; + } + if (buffer->capacity - buffer->size == ((int8_t*) buffer->readPtr - (int8_t*) buffer->writePtr)) { + return 1; + } + return 0; +} +#endif + void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) { buffer->data = malloc(capacity); buffer->capacity = capacity;@@ -34,6 +49,11 @@ } else {
buffer->writePtr = buffer->data; } buffer->size += sizeof(int8_t); +#ifndef NDEBUG + if (!_checkIntegrity(buffer)) { + abort(); + } +#endif return 1; }@@ -42,6 +62,14 @@ int32_t* data = buffer->writePtr;
if (buffer->size + sizeof(int32_t) > buffer->capacity) { return 0; } + if ((intptr_t) data & 0x3) { + int written = 0; + written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); + written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); + written += CircleBufferWrite8(buffer, ((int8_t*) &value)[2]); + written += CircleBufferWrite8(buffer, ((int8_t*) &value)[3]); + return written; + } *data = value; ++data; size_t size = (int8_t*) data - (int8_t*) buffer->data;@@ -51,7 +79,12 @@ } else {
buffer->writePtr = buffer->data; } buffer->size += sizeof(int32_t); - return 1; +#ifndef NDEBUG + if (!_checkIntegrity(buffer)) { + abort(); + } +#endif + return 4; } int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) {@@ -68,6 +101,11 @@ } else {
buffer->readPtr = buffer->data; } buffer->size -= sizeof(int8_t); +#ifndef NDEBUG + if (!_checkIntegrity(buffer)) { + abort(); + } +#endif return 1; }@@ -76,6 +114,14 @@ int32_t* data = buffer->readPtr;
if (buffer->size < sizeof(int32_t)) { return 0; } + if ((intptr_t) data & 0x3) { + int read = 0; + read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); + read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); + read += CircleBufferRead8(buffer, &((int8_t*) value)[2]); + read += CircleBufferRead8(buffer, &((int8_t*) value)[3]); + return read; + } *value = *data; ++data; size_t size = (int8_t*) data - (int8_t*) buffer->data;@@ -85,7 +131,12 @@ } else {
buffer->readPtr = buffer->data; } buffer->size -= sizeof(int32_t); - return 1; +#ifndef NDEBUG + if (!_checkIntegrity(buffer)) { + abort(); + } +#endif + return 4; } int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {@@ -111,5 +162,10 @@ buffer->readPtr = (int8_t*) buffer->data + length - remaining;
} buffer->size -= length; +#ifndef NDEBUG + if (!_checkIntegrity(buffer)) { + abort(); + } +#endif return length; }