Fix integer overflow in ring buffer

This commit is contained in:
GoaLitiuM 2017-10-25 06:11:36 +03:00
parent b5e37d1536
commit 2975be9588
3 changed files with 15 additions and 7 deletions

View file

@ -31,6 +31,10 @@ struct SoundIoAtomicFlag {
std::atomic_flag x; std::atomic_flag x;
}; };
struct SoundIoAtomicULong {
std::atomic<unsigned long> x;
};
#define SOUNDIO_ATOMIC_LOAD(a) (a.x.load()) #define SOUNDIO_ATOMIC_LOAD(a) (a.x.load())
#define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) (a.x.fetch_add(delta)) #define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) (a.x.fetch_add(delta))
#define SOUNDIO_ATOMIC_STORE(a, value) (a.x.store(value)) #define SOUNDIO_ATOMIC_STORE(a, value) (a.x.store(value))
@ -59,6 +63,10 @@ struct SoundIoAtomicFlag {
atomic_flag x; atomic_flag x;
}; };
struct SoundIoAtomicULong {
atomic_ulong x;
};
#define SOUNDIO_ATOMIC_LOAD(a) atomic_load(&a.x) #define SOUNDIO_ATOMIC_LOAD(a) atomic_load(&a.x)
#define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) atomic_fetch_add(&a.x, delta) #define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) atomic_fetch_add(&a.x, delta)
#define SOUNDIO_ATOMIC_STORE(a, value) atomic_store(&a.x, value) #define SOUNDIO_ATOMIC_STORE(a, value) atomic_store(&a.x, value)

View file

@ -43,7 +43,7 @@ int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *rb) {
} }
char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *rb) { char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *rb) {
long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); unsigned long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset);
return rb->mem.address + (write_offset % rb->capacity); return rb->mem.address + (write_offset % rb->capacity);
} }
@ -53,7 +53,7 @@ void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *rb, int cou
} }
char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *rb) { char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *rb) {
long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset);
return rb->mem.address + (read_offset % rb->capacity); return rb->mem.address + (read_offset % rb->capacity);
} }
@ -65,8 +65,8 @@ void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *rb, int coun
int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *rb) { int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *rb) {
// Whichever offset we load first might have a smaller value. So we load // Whichever offset we load first might have a smaller value. So we load
// the read_offset first. // the read_offset first.
long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset);
long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); unsigned long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset);
int count = write_offset - read_offset; int count = write_offset - read_offset;
assert(count >= 0); assert(count >= 0);
assert(count <= rb->capacity); assert(count <= rb->capacity);
@ -78,7 +78,7 @@ int soundio_ring_buffer_free_count(struct SoundIoRingBuffer *rb) {
} }
void soundio_ring_buffer_clear(struct SoundIoRingBuffer *rb) { void soundio_ring_buffer_clear(struct SoundIoRingBuffer *rb) {
long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset);
SOUNDIO_ATOMIC_STORE(rb->write_offset, read_offset); SOUNDIO_ATOMIC_STORE(rb->write_offset, read_offset);
} }

View file

@ -13,8 +13,8 @@
struct SoundIoRingBuffer { struct SoundIoRingBuffer {
struct SoundIoOsMirroredMemory mem; struct SoundIoOsMirroredMemory mem;
struct SoundIoAtomicLong write_offset; struct SoundIoAtomicULong write_offset;
struct SoundIoAtomicLong read_offset; struct SoundIoAtomicULong read_offset;
int capacity; int capacity;
}; };