| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Ring Buffer | * Carla Ring Buffer | ||||
| * Copyright (C) 2013-2022 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -62,21 +62,21 @@ struct HeapBuffer { | |||||
| }; | }; | ||||
| struct SmallStackBuffer { | struct SmallStackBuffer { | ||||
| static const uint32_t size = 4096; | |||||
| static constexpr const uint32_t size = 4096; | |||||
| uint32_t head, tail, wrtn; | uint32_t head, tail, wrtn; | ||||
| bool invalidateCommit; | bool invalidateCommit; | ||||
| uint8_t buf[size]; | uint8_t buf[size]; | ||||
| }; | }; | ||||
| struct BigStackBuffer { | struct BigStackBuffer { | ||||
| static const uint32_t size = 16384; | |||||
| static constexpr const uint32_t size = 16384; | |||||
| uint32_t head, tail, wrtn; | uint32_t head, tail, wrtn; | ||||
| bool invalidateCommit; | bool invalidateCommit; | ||||
| uint8_t buf[size]; | uint8_t buf[size]; | ||||
| }; | }; | ||||
| struct HugeStackBuffer { | struct HugeStackBuffer { | ||||
| static const uint32_t size = 65536; | |||||
| static constexpr const uint32_t size = 65536; | |||||
| uint32_t head, tail, wrtn; | uint32_t head, tail, wrtn; | ||||
| bool invalidateCommit; | bool invalidateCommit; | ||||
| uint8_t buf[size]; | uint8_t buf[size]; | ||||
| @@ -238,6 +238,42 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void skipRead(const uint32_t size) noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||||
| CARLA_SAFE_ASSERT_RETURN(size > 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size,); | |||||
| // empty | |||||
| if (fBuffer->head == fBuffer->tail) | |||||
| return; | |||||
| const uint32_t head = fBuffer->head; | |||||
| const uint32_t tail = fBuffer->tail; | |||||
| const uint32_t wrap = head > tail ? 0 : fBuffer->size; | |||||
| if (size > wrap + head - tail) | |||||
| { | |||||
| if (! fErrorReading) | |||||
| { | |||||
| fErrorReading = true; | |||||
| carla_stderr2("CarlaRingBuffer::skipRead(%u): failed, not enough space", size); | |||||
| } | |||||
| return; | |||||
| } | |||||
| uint32_t readto = tail + size; | |||||
| if (readto >= fBuffer->size) | |||||
| readto -= fBuffer->size; | |||||
| fBuffer->tail = readto; | |||||
| fErrorReading = false; | |||||
| return; | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| bool writeBool(const bool value) noexcept | bool writeBool(const bool value) noexcept | ||||
| { | { | ||||
| return tryWrite(&value, sizeof(bool)); | return tryWrite(&value, sizeof(bool)); | ||||
| @@ -320,14 +356,14 @@ protected: | |||||
| bool tryRead(void* const buf, const uint32_t size) noexcept | bool tryRead(void* const buf, const uint32_t size) noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | ||||
| #if defined(__clang__) | |||||
| # pragma clang diagnostic push | |||||
| # pragma clang diagnostic ignored "-Wtautological-pointer-compare" | |||||
| #endif | |||||
| #if defined(__clang__) | |||||
| #pragma clang diagnostic push | |||||
| #pragma clang diagnostic ignored "-Wtautological-pointer-compare" | |||||
| #endif | |||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer->buf != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer->buf != nullptr, false); | ||||
| #if defined(__clang__) | |||||
| # pragma clang diagnostic pop | |||||
| #endif | |||||
| #if defined(__clang__) | |||||
| #pragma clang diagnostic pop | |||||
| #endif | |||||
| CARLA_SAFE_ASSERT_RETURN(buf != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(buf != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false); | CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false); | ||||
| @@ -336,23 +372,23 @@ protected: | |||||
| if (fBuffer->head == fBuffer->tail) | if (fBuffer->head == fBuffer->tail) | ||||
| return false; | return false; | ||||
| uint8_t* const bytebuf(static_cast<uint8_t*>(buf)); | |||||
| uint8_t* const bytebuf = static_cast<uint8_t*>(buf); | |||||
| const uint32_t head(fBuffer->head); | |||||
| const uint32_t tail(fBuffer->tail); | |||||
| const uint32_t wrap((head > tail) ? 0 : fBuffer->size); | |||||
| const uint32_t head = fBuffer->head; | |||||
| const uint32_t tail = fBuffer->tail; | |||||
| const uint32_t wrap = head > tail ? 0 : fBuffer->size; | |||||
| if (size > wrap + head - tail) | if (size > wrap + head - tail) | ||||
| { | { | ||||
| if (! fErrorReading) | if (! fErrorReading) | ||||
| { | { | ||||
| fErrorReading = true; | fErrorReading = true; | ||||
| carla_stderr2("CarlaRingBuffer::tryRead(%p, " P_SIZE "): failed, not enough space", buf, size); | |||||
| carla_stderr2("CarlaRingBuffer::tryRead(%p, %u): failed, not enough space", buf, size); | |||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| uint32_t readto(tail + size); | |||||
| uint32_t readto = tail + size; | |||||
| if (readto > fBuffer->size) | if (readto > fBuffer->size) | ||||
| { | { | ||||
| @@ -364,7 +400,7 @@ protected: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const uint32_t firstpart(fBuffer->size - tail); | |||||
| const uint32_t firstpart = fBuffer->size - tail; | |||||
| std::memcpy(bytebuf, fBuffer->buf + tail, firstpart); | std::memcpy(bytebuf, fBuffer->buf + tail, firstpart); | ||||
| std::memcpy(bytebuf + firstpart, fBuffer->buf, readto); | std::memcpy(bytebuf + firstpart, fBuffer->buf, readto); | ||||
| } | } | ||||
| @@ -389,24 +425,24 @@ protected: | |||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, false); | ||||
| CARLA_SAFE_ASSERT_UINT2_RETURN(size < fBuffer->size, size, fBuffer->size, false); | CARLA_SAFE_ASSERT_UINT2_RETURN(size < fBuffer->size, size, fBuffer->size, false); | ||||
| const uint8_t* const bytebuf(static_cast<const uint8_t*>(buf)); | |||||
| const uint8_t* const bytebuf = static_cast<const uint8_t*>(buf); | |||||
| const uint32_t tail(fBuffer->tail); | |||||
| const uint32_t wrtn(fBuffer->wrtn); | |||||
| const uint32_t wrap((tail > wrtn) ? 0 : fBuffer->size); | |||||
| const uint32_t tail = fBuffer->tail; | |||||
| const uint32_t wrtn = fBuffer->wrtn; | |||||
| const uint32_t wrap = tail > wrtn ? 0 : fBuffer->size; | |||||
| if (size >= wrap + tail - wrtn) | if (size >= wrap + tail - wrtn) | ||||
| { | { | ||||
| if (! fErrorWriting) | if (! fErrorWriting) | ||||
| { | { | ||||
| fErrorWriting = true; | fErrorWriting = true; | ||||
| carla_stderr2("CarlaRingBuffer::tryWrite(%p, " P_SIZE "): failed, not enough space", buf, size); | |||||
| carla_stderr2("CarlaRingBuffer::tryWrite(%p, %u): failed, not enough space", buf, size); | |||||
| } | } | ||||
| fBuffer->invalidateCommit = true; | fBuffer->invalidateCommit = true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| uint32_t writeto(wrtn + size); | |||||
| uint32_t writeto = wrtn + size; | |||||
| if (writeto > fBuffer->size) | if (writeto > fBuffer->size) | ||||
| { | { | ||||
| @@ -418,7 +454,7 @@ protected: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const uint32_t firstpart(fBuffer->size - wrtn); | |||||
| const uint32_t firstpart = fBuffer->size - wrtn; | |||||
| std::memcpy(fBuffer->buf + wrtn, bytebuf, firstpart); | std::memcpy(fBuffer->buf + wrtn, bytebuf, firstpart); | ||||
| std::memcpy(fBuffer->buf, bytebuf + firstpart, writeto); | std::memcpy(fBuffer->buf, bytebuf + firstpart, writeto); | ||||
| } | } | ||||
| @@ -484,7 +520,7 @@ public: | |||||
| CARLA_SAFE_ASSERT_RETURN(fHeapBuffer.buf == nullptr,); | CARLA_SAFE_ASSERT_RETURN(fHeapBuffer.buf == nullptr,); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0,); | CARLA_SAFE_ASSERT_RETURN(size > 0,); | ||||
| const uint32_t p2size(carla_nextPowerOf2(size)); | |||||
| const uint32_t p2size = carla_nextPowerOf2(size); | |||||
| try { | try { | ||||
| fHeapBuffer.buf = new uint8_t[p2size]; | fHeapBuffer.buf = new uint8_t[p2size]; | ||||