mirror of https://github.com/mgba-emu/mgba.git
Have circle buffer work when memory is misaligned
This commit is contained in:
parent
39025dedff
commit
4e88cc86d9
|
@ -3,6 +3,21 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.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) {
|
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) {
|
||||||
buffer->data = malloc(capacity);
|
buffer->data = malloc(capacity);
|
||||||
buffer->capacity = capacity;
|
buffer->capacity = capacity;
|
||||||
|
@ -34,6 +49,11 @@ int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) {
|
||||||
buffer->writePtr = buffer->data;
|
buffer->writePtr = buffer->data;
|
||||||
}
|
}
|
||||||
buffer->size += sizeof(int8_t);
|
buffer->size += sizeof(int8_t);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!_checkIntegrity(buffer)) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +62,14 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) {
|
||||||
if (buffer->size + sizeof(int32_t) > buffer->capacity) {
|
if (buffer->size + sizeof(int32_t) > buffer->capacity) {
|
||||||
return 0;
|
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 = value;
|
||||||
++data;
|
++data;
|
||||||
size_t size = (int8_t*) data - (int8_t*) buffer->data;
|
size_t size = (int8_t*) data - (int8_t*) buffer->data;
|
||||||
|
@ -51,7 +79,12 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) {
|
||||||
buffer->writePtr = buffer->data;
|
buffer->writePtr = buffer->data;
|
||||||
}
|
}
|
||||||
buffer->size += sizeof(int32_t);
|
buffer->size += sizeof(int32_t);
|
||||||
return 1;
|
#ifndef NDEBUG
|
||||||
|
if (!_checkIntegrity(buffer)) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) {
|
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) {
|
||||||
|
@ -68,6 +101,11 @@ int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) {
|
||||||
buffer->readPtr = buffer->data;
|
buffer->readPtr = buffer->data;
|
||||||
}
|
}
|
||||||
buffer->size -= sizeof(int8_t);
|
buffer->size -= sizeof(int8_t);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!_checkIntegrity(buffer)) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +114,14 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) {
|
||||||
if (buffer->size < sizeof(int32_t)) {
|
if (buffer->size < sizeof(int32_t)) {
|
||||||
return 0;
|
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;
|
*value = *data;
|
||||||
++data;
|
++data;
|
||||||
size_t size = (int8_t*) data - (int8_t*) buffer->data;
|
size_t size = (int8_t*) data - (int8_t*) buffer->data;
|
||||||
|
@ -85,7 +131,12 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) {
|
||||||
buffer->readPtr = buffer->data;
|
buffer->readPtr = buffer->data;
|
||||||
}
|
}
|
||||||
buffer->size -= sizeof(int32_t);
|
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) {
|
int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {
|
||||||
|
@ -111,5 +162,10 @@ int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->size -= length;
|
buffer->size -= length;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!_checkIntegrity(buffer)) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue