mirror of
https://github.com/bkaradzic/bx.git
synced 2026-10-22 08:41:00 +00:00
Fixed RingBufferControl::resize moving heads that are at the write head, and leaving heads outside the buffer when shrinking past the end of buffer. (#436)
This commit is contained in:
committed by
GitHub
parent
3b8366af83
commit
1c986bd1e9
@@ -54,10 +54,16 @@ namespace bx
|
||||
: _size
|
||||
;
|
||||
|
||||
// empty slots past the end of buffer are removed from the start of buffer.
|
||||
const int32_t back = bx::max(_size, int32_t(m_write) - int32_t(m_size) );
|
||||
const int32_t front = _size - back;
|
||||
const uint32_t write = m_write;
|
||||
|
||||
m_size += _size;
|
||||
|
||||
m_current += m_current >= m_write ? _size : 0;
|
||||
m_read += m_read >= m_write ? _size : 0;
|
||||
m_current = (m_current + (m_current > write ? back : front) ) % m_size;
|
||||
m_read = (m_read + (m_read > write ? back : front) ) % m_size;
|
||||
m_write = (m_write + front) % m_size;
|
||||
}
|
||||
|
||||
inline uint32_t RingBufferControl::consume(uint32_t _size)
|
||||
@@ -177,10 +183,16 @@ namespace bx
|
||||
: _size
|
||||
;
|
||||
|
||||
// empty slots past the end of buffer are removed from the start of buffer.
|
||||
const int32_t back = bx::max(_size, int32_t(m_write) - int32_t(m_size) );
|
||||
const int32_t front = _size - back;
|
||||
const uint32_t write = m_write;
|
||||
|
||||
m_size += _size;
|
||||
|
||||
m_current += m_current >= m_write ? _size : 0;
|
||||
m_read += m_read >= m_write ? _size : 0;
|
||||
m_current = (m_current + (m_current > write ? back : front) ) % m_size;
|
||||
m_read = (m_read + (m_read > write ? back : front) ) % m_size;
|
||||
m_write = (m_write + front) % m_size;
|
||||
}
|
||||
|
||||
inline uint32_t SpScRingBufferControl::consume(uint32_t _size)
|
||||
|
||||
@@ -71,7 +71,9 @@ namespace bx
|
||||
/// forward or backward if write head is behind them.
|
||||
///
|
||||
/// @param[in] _size Amount to resize. Value can be positive when growing size or negative
|
||||
/// when shrinking size of buffer.
|
||||
/// when shrinking size of buffer. Shrinking is limited to number of empty slots. Empty slots
|
||||
/// are removed from write head to the end of buffer, and remainder is removed from the start
|
||||
/// of buffer.
|
||||
///
|
||||
void resize(int32_t _size);
|
||||
|
||||
@@ -176,7 +178,9 @@ namespace bx
|
||||
/// forward or backward if write head is behind them.
|
||||
///
|
||||
/// @param[in] _size Amount to resize. Value can be positive when growing size or negative
|
||||
/// when shrinking size of buffer.
|
||||
/// when shrinking size of buffer. Shrinking is limited to number of empty slots. Empty slots
|
||||
/// are removed from write head to the end of buffer, and remainder is removed from the start
|
||||
/// of buffer.
|
||||
///
|
||||
void resize(int32_t _size);
|
||||
|
||||
|
||||
@@ -123,3 +123,120 @@ TEST_CASE("RingBufferControl resize", "")
|
||||
REQUIRE(control.m_write == 0);
|
||||
REQUIRE(control.m_read == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("RingBufferControl resize without reserved slots", "")
|
||||
{
|
||||
{
|
||||
bx::RingBufferControl control(8);
|
||||
|
||||
REQUIRE(5 == control.reserve(5) );
|
||||
REQUIRE(5 == control.commit(5) );
|
||||
REQUIRE(2 == control.consume(2) );
|
||||
|
||||
control.resize(8);
|
||||
REQUIRE(16 == control.getSize() );
|
||||
REQUIRE(3 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(12 == control.getNumEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 5);
|
||||
REQUIRE(control.m_write == 5);
|
||||
REQUIRE(control.m_read == 2);
|
||||
}
|
||||
|
||||
{
|
||||
bx::RingBufferControl control(8);
|
||||
|
||||
REQUIRE(6 == control.reserve(6) );
|
||||
REQUIRE(6 == control.commit(6) );
|
||||
REQUIRE(5 == control.consume(5) );
|
||||
REQUIRE(4 == control.reserve(4) );
|
||||
REQUIRE(4 == control.commit(4) );
|
||||
|
||||
REQUIRE(control.m_current == 2);
|
||||
REQUIRE(control.m_write == 2);
|
||||
REQUIRE(control.m_read == 5);
|
||||
|
||||
control.resize(8);
|
||||
REQUIRE(16 == control.getSize() );
|
||||
REQUIRE(5 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(10 == control.getNumEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 2);
|
||||
REQUIRE(control.m_write == 2);
|
||||
REQUIRE(control.m_read == 13);
|
||||
|
||||
control.resize(-8);
|
||||
REQUIRE(8 == control.getSize() );
|
||||
REQUIRE(5 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(2 == control.getNumEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 2);
|
||||
REQUIRE(control.m_write == 2);
|
||||
REQUIRE(control.m_read == 5);
|
||||
}
|
||||
|
||||
{
|
||||
bx::RingBufferControl control(8);
|
||||
|
||||
REQUIRE(3 == control.reserve(3) );
|
||||
REQUIRE(3 == control.commit(3) );
|
||||
REQUIRE(3 == control.consume(3) );
|
||||
|
||||
control.resize(8);
|
||||
REQUIRE(16 == control.getSize() );
|
||||
REQUIRE(0 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(15 == control.getNumEmpty() );
|
||||
REQUIRE(control.isEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 3);
|
||||
REQUIRE(control.m_write == 3);
|
||||
REQUIRE(control.m_read == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("RingBufferControl shrink past the end of buffer", "")
|
||||
{
|
||||
{
|
||||
bx::RingBufferControl control(16);
|
||||
|
||||
REQUIRE(10 == control.reserve(10) );
|
||||
REQUIRE(10 == control.commit(10) );
|
||||
REQUIRE(8 == control.consume(8) );
|
||||
|
||||
REQUIRE(13 == control.getNumEmpty() );
|
||||
|
||||
control.resize(-13);
|
||||
REQUIRE(3 == control.getSize() );
|
||||
REQUIRE(2 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(0 == control.getNumEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 0);
|
||||
REQUIRE(control.m_write == 0);
|
||||
REQUIRE(control.m_read == 1);
|
||||
}
|
||||
|
||||
{
|
||||
bx::RingBufferControl control(32);
|
||||
|
||||
REQUIRE(29 == control.reserve(29) );
|
||||
REQUIRE(29 == control.commit(29) );
|
||||
REQUIRE(18 == control.consume(18) );
|
||||
|
||||
REQUIRE(20 == control.getNumEmpty() );
|
||||
|
||||
control.resize(-4);
|
||||
REQUIRE(28 == control.getSize() );
|
||||
REQUIRE(11 == control.getNumUsed() );
|
||||
REQUIRE(0 == control.getNumReserved() );
|
||||
REQUIRE(16 == control.getNumEmpty() );
|
||||
|
||||
REQUIRE(control.m_current == 0);
|
||||
REQUIRE(control.m_write == 0);
|
||||
REQUIRE(control.m_read == 17);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user