Update RingBuffer - Add immediate read/write and some error checking asserts.
This commit is contained in:
parent
7cfa664b2d
commit
6a67632af1
|
@ -17,6 +17,26 @@ namespace xe {
|
||||||
RingBuffer::RingBuffer(uint8_t* buffer, size_t capacity)
|
RingBuffer::RingBuffer(uint8_t* buffer, size_t capacity)
|
||||||
: buffer_(buffer), capacity_(capacity) {}
|
: buffer_(buffer), capacity_(capacity) {}
|
||||||
|
|
||||||
|
void RingBuffer::AdvanceRead(size_t count) {
|
||||||
|
if (read_offset_ + count < capacity_) {
|
||||||
|
read_offset_ += count;
|
||||||
|
} else {
|
||||||
|
size_t left_half = capacity_ - read_offset_;
|
||||||
|
size_t right_half = count - left_half;
|
||||||
|
read_offset_ = right_half;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RingBuffer::AdvanceWrite(size_t count) {
|
||||||
|
if (write_offset_ + count < capacity_) {
|
||||||
|
write_offset_ += count;
|
||||||
|
} else {
|
||||||
|
size_t left_half = capacity_ - write_offset_;
|
||||||
|
size_t right_half = count - left_half;
|
||||||
|
write_offset_ = right_half;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RingBuffer::ReadRange RingBuffer::BeginRead(size_t count) {
|
RingBuffer::ReadRange RingBuffer::BeginRead(size_t count) {
|
||||||
count = std::min(count, capacity_);
|
count = std::min(count, capacity_);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
|
@ -45,6 +65,14 @@ size_t RingBuffer::Read(uint8_t* buffer, size_t count) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity check: Make sure we don't read over the write offset.
|
||||||
|
if (read_offset_ < write_offset_) {
|
||||||
|
assert_true(read_offset_ + count <= write_offset_);
|
||||||
|
} else if (read_offset_ + count >= capacity_) {
|
||||||
|
size_t left_half = capacity_ - read_offset_;
|
||||||
|
assert_true(count - left_half <= write_offset_);
|
||||||
|
}
|
||||||
|
|
||||||
if (read_offset_ + count < capacity_) {
|
if (read_offset_ + count < capacity_) {
|
||||||
std::memcpy(buffer, buffer_ + read_offset_, count);
|
std::memcpy(buffer, buffer_ + read_offset_, count);
|
||||||
read_offset_ += count;
|
read_offset_ += count;
|
||||||
|
@ -65,6 +93,14 @@ size_t RingBuffer::Write(const uint8_t* buffer, size_t count) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity check: Make sure we don't write over the read offset.
|
||||||
|
if (write_offset_ < read_offset_) {
|
||||||
|
assert_true(write_offset_ + count <= read_offset_);
|
||||||
|
} else if (write_offset_ + count >= capacity_) {
|
||||||
|
size_t left_half = capacity_ - write_offset_;
|
||||||
|
assert_true(count - left_half <= read_offset_);
|
||||||
|
}
|
||||||
|
|
||||||
if (write_offset_ + count < capacity_) {
|
if (write_offset_ + count < capacity_) {
|
||||||
std::memcpy(buffer_ + write_offset_, buffer, count);
|
std::memcpy(buffer_ + write_offset_, buffer, count);
|
||||||
write_offset_ += count;
|
write_offset_ += count;
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/assert.h"
|
||||||
|
#include "xenia/base/byte_order.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
class RingBuffer {
|
class RingBuffer {
|
||||||
|
@ -25,6 +28,7 @@ class RingBuffer {
|
||||||
bool empty() const { return read_offset_ == write_offset_; }
|
bool empty() const { return read_offset_ == write_offset_; }
|
||||||
|
|
||||||
size_t read_offset() const { return read_offset_; }
|
size_t read_offset() const { return read_offset_; }
|
||||||
|
uintptr_t read_ptr() const { return uintptr_t(buffer_) + read_offset_; }
|
||||||
void set_read_offset(size_t offset) { read_offset_ = offset % capacity_; }
|
void set_read_offset(size_t offset) { read_offset_ = offset % capacity_; }
|
||||||
size_t read_count() const {
|
size_t read_count() const {
|
||||||
if (read_offset_ == write_offset_) {
|
if (read_offset_ == write_offset_) {
|
||||||
|
@ -37,6 +41,7 @@ class RingBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t write_offset() const { return write_offset_; }
|
size_t write_offset() const { return write_offset_; }
|
||||||
|
uintptr_t write_ptr() const { return uintptr_t(buffer_) + write_offset_; }
|
||||||
void set_write_offset(size_t offset) { write_offset_ = offset % capacity_; }
|
void set_write_offset(size_t offset) { write_offset_ = offset % capacity_; }
|
||||||
size_t write_count() const {
|
size_t write_count() const {
|
||||||
if (read_offset_ == write_offset_) {
|
if (read_offset_ == write_offset_) {
|
||||||
|
@ -48,6 +53,9 @@ class RingBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvanceRead(size_t count);
|
||||||
|
void AdvanceWrite(size_t count);
|
||||||
|
|
||||||
struct ReadRange {
|
struct ReadRange {
|
||||||
const uint8_t* first;
|
const uint8_t* first;
|
||||||
size_t first_length;
|
size_t first_length;
|
||||||
|
@ -63,12 +71,31 @@ class RingBuffer {
|
||||||
return Read(reinterpret_cast<uint8_t*>(buffer), count);
|
return Read(reinterpret_cast<uint8_t*>(buffer), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Read(bool swap = false) {
|
||||||
|
static_assert(sizeof(T) <= 8, "Immediate read only supports basic types!");
|
||||||
|
|
||||||
|
T imm;
|
||||||
|
size_t read = Read(reinterpret_cast<uint8_t*>(&imm), sizeof(T));
|
||||||
|
assert_true(read == sizeof(T));
|
||||||
|
if (swap) {
|
||||||
|
imm = xe::byte_swap(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return imm;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Write(const uint8_t* buffer, size_t count);
|
size_t Write(const uint8_t* buffer, size_t count);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t Write(const T* buffer, size_t count) {
|
size_t Write(const T* buffer, size_t count) {
|
||||||
return Write(reinterpret_cast<const uint8_t*>(buffer), count);
|
return Write(reinterpret_cast<const uint8_t*>(buffer), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t Write(T& data) {
|
||||||
|
return Write(reinterpret_cast<const uint8_t*>(&data), sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t* buffer_ = nullptr;
|
uint8_t* buffer_ = nullptr;
|
||||||
size_t capacity_ = 0;
|
size_t capacity_ = 0;
|
||||||
|
|
Loading…
Reference in New Issue