all repos — mgba @ 4e88cc86d97f670d17533fa0293772264bd8d8d4

mGBA Game Boy Advance Emulator

Have circle buffer work when memory is misaligned
Jeffrey Pfau jeffrey@endrift.com
Thu, 16 Jan 2014 01:56:17 -0800
commit

4e88cc86d97f670d17533fa0293772264bd8d8d4

parent

39025dedff6bb67a0d4037c114e38d77b4abc559

1 files changed, 58 insertions(+), 2 deletions(-)

jump to
M src/util/circle-buffer.csrc/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; }