[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kwave] libkwave: minor optimizations in class Stripe, detach only under lock
From: Thomas Eschenbacher <Thomas.Eschenbacher () gmx ! de>
Date: 2016-10-31 20:25:04
Message-ID: E1c1J8i-0004Ne-Vw () code ! kde ! org
[Download RAW message or body]
Git commit 371b787024cf1806e39bf3f77a049e57bb7965d6 by Thomas Eschenbacher.
Committed on 31/10/2016 at 20:25.
Pushed by eschenbacher into branch 'master'.
minor optimizations in class Stripe, detach only under lock
M +101 -117 libkwave/Stripe.cpp
M +2 -0 libkwave/Stripe.h
http://commits.kde.org/kwave/371b787024cf1806e39bf3f77a049e57bb7965d6
diff --git a/libkwave/Stripe.cpp b/libkwave/Stripe.cpp
index d208441..9262696 100644
--- a/libkwave/Stripe.cpp
+++ b/libkwave/Stripe.cpp
@@ -288,19 +288,17 @@ sample_index_t Kwave::Stripe::end() const
//***************************************************************************
unsigned int Kwave::Stripe::resizeStorage(unsigned int length)
{
- if (!m_data) return 0;
- m_data.detach();
- if (!m_data) return 0; // OOM when detaching
+ Q_ASSERT(!m_data); // (just paranoia)
if (m_data->m_length == length) return length; // nothing to do
// qDebug("Stripe::resizeStorage(%u)", length);
- Kwave::MemoryManager &mem = Kwave::MemoryManager::instance();
-
// check: must not be mapped!
Q_ASSERT(!m_data->mapCount());
if (m_data->mapCount()) return m_data->m_length;
+ Kwave::MemoryManager &mem = Kwave::MemoryManager::instance();
+
// special case: zero length means delete
if (length == 0) {
// delete the array
@@ -340,44 +338,40 @@ unsigned int Kwave::Stripe::resizeStorage(unsigned int length)
//***************************************************************************
unsigned int Kwave::Stripe::resize(unsigned int length, bool initialize)
{
- if (!m_data) return 0;
+ QMutexLocker lock(&m_lock);
m_data.detach();
if (!m_data) return 0; // OOM when detaching
- {
- QMutexLocker lock(&m_lock);
+ unsigned int old_length = m_data->m_length;
+ if (m_data->m_length == length) return old_length; // nothing to do
- unsigned int old_length = m_data->m_length;
- if (m_data->m_length == length) return old_length; // nothing to do
+// qDebug("Stripe::resize() from %d to %d samples", old_length, length);
+ Q_ASSERT(!m_data->mapCount());
+ if (resizeStorage(length) != length) {
+ qWarning("Stripe::resize(%u) failed, out of memory ?", length);
+ return m_data->m_length;
+ }
-// qDebug("Stripe::resize() from %d to %d samples", old_length, length);
+ // fill new samples with zero
+ if (initialize && length) {
Q_ASSERT(!m_data->mapCount());
- if (resizeStorage(length) != length) {
- qWarning("Stripe::resize(%u) failed, out of memory ?", length);
- return m_data->m_length;
- }
-
- // fill new samples with zero
- if (initialize && length) {
- Q_ASSERT(!m_data->mapCount());
- unsigned int pos = old_length;
+ unsigned int pos = old_length;
#ifdef STRICTLY_QT
- MappedArray _samples(*this);
- if (_samples.size() != m_data->m_length) return 0;
+ MappedArray _samples(*this);
+ if (_samples.size() != m_data->m_length) return 0;
- while (pos < length) {
- _samples[pos++] = 0;
- }
+ while (pos < length) {
+ _samples[pos++] = 0;
+ }
#else
- MappedArray _map(*this);
- sample_t *samples = _map.data();
- if (!samples) return 0;
- if (pos < length) {
- memset(&(samples[pos]), 0, (length-pos)*sizeof(sample_t));
- }
-#endif
+ MappedArray _map(*this);
+ sample_t *samples = _map.data();
+ if (!samples) return 0;
+ if (pos < length) {
+ memset(&(samples[pos]), 0, (length - pos) * sizeof(sample_t));
}
+#endif
}
return length;
@@ -388,113 +382,103 @@ unsigned int Kwave::Stripe::append(const Kwave::SampleArray &samples,
unsigned int offset,
unsigned int count)
{
- unsigned int appended = 0;
+ if (!count) return 0; // nothing to do
+ Q_ASSERT(offset + count <= samples.size());
+ if (offset + count > samples.size()) return 0;
- if (!count || !m_data) return 0; // nothing to do
+// qDebug("Stripe::append: adding %d samples", count);
+ QMutexLocker lock(&m_lock);
m_data.detach();
if (!m_data) return 0; // OOM when detaching
- {
- QMutexLocker lock(&m_lock);
-
- Q_ASSERT(offset + count <= samples.size());
- if (offset + count > samples.size()) return 0;
-
-// qDebug("Stripe::append: adding %d samples", count);
+ unsigned int old_length = m_data->m_length;
+ unsigned int new_length = old_length + count;
+ Q_ASSERT(!m_data->mapCount());
+ if (resizeStorage(new_length) != new_length)
+ return 0; // out of memory
- unsigned int old_length = m_data->m_length;
- unsigned int new_length = old_length + count;
- Q_ASSERT(!m_data->mapCount());
- if (resizeStorage(new_length) != new_length)
- return 0; // out of memory
+ // append to the end of the area
+ unsigned int cnt = new_length - old_length;
+ Q_ASSERT(!m_data->mapCount());
+ int bytes_appended = Kwave::MemoryManager::instance().writeTo(
+ m_data->m_storage,
+ old_length * sizeof(sample_t),
+ &(samples[offset]), cnt * sizeof(sample_t)
+ );
- // append to the end of the area
- unsigned int cnt = new_length - old_length;
- Q_ASSERT(!m_data->mapCount());
- appended = Kwave::MemoryManager::instance().writeTo(m_data->m_storage,
- old_length * sizeof(sample_t),
- &(samples[offset]), cnt * sizeof(sample_t))
- / sizeof(sample_t);
- }
// qDebug("Stripe::append(): resized to %d", m_length);
- return appended;
+ return (bytes_appended > 0) ? (bytes_appended / sizeof(sample_t)) : 0;
}
//***************************************************************************
void Kwave::Stripe::deleteRange(unsigned int offset, unsigned int length)
{
// qDebug(" Stripe::deleteRange(offset=%u, length=%u)", offset, length);
- if (!length || !m_data) return; // nothing to do
+ if (!length) return; // nothing to do
+
+ QMutexLocker lock(&m_lock);
m_data.detach();
if (!m_data) return; // OOM when detaching
- {
- QMutexLocker lock(&m_lock);
+ const unsigned int size = m_data->m_length;
+ if (!size) return;
- const unsigned int size = m_data->m_length;
- if (!size) return;
+ unsigned int first = offset;
+ unsigned int last = offset + length - 1;
+// qDebug(" Stripe::deleteRange, me=[%u ... %u] del=[%u ... %u]",
+// m_start, m_start+size-1, m_start + first, m_start + last);
- unsigned int first = offset;
- unsigned int last = offset + length - 1;
-// qDebug(" Stripe::deleteRange, me=[%u ... %u] del=[%u ... %u]",
-// m_start, m_start+size-1, m_start + first, m_start + last);
+ Q_ASSERT(first < size);
+ if (first >= size) return;
- Q_ASSERT(first < size);
- if (first >= size) return;
+ // put first/last into our area
+ if (last >= size) last = size - 1;
+ Q_ASSERT(last >= first);
+ if (last < first) return;
- // put first/last into our area
- if (last >= size) last = size - 1;
- Q_ASSERT(last >= first);
- if (last < first) return;
-
- // move all samples after the deleted area to the left
- unsigned int dst = first;
- unsigned int src = last+1;
- unsigned int len = size - src;
-// qDebug(" Stripe: deleting %u ... %u", dst, src-1);
- if (len) {
- MappedArray _samples(*this);
-
- Q_ASSERT(src + len <= size);
- Q_ASSERT(dst + len <= size);
- if (!_samples.copy(dst, src, len)) return;
- }
+ // move all samples after the deleted area to the left
+ unsigned int dst = first;
+ unsigned int src = last+1;
+ unsigned int len = size - src;
+// qDebug(" Stripe: deleting %u ... %u", dst, src-1);
+ if (len) {
+ MappedArray _samples(*this);
- // resize the buffer to it's new size
- resizeStorage(size - length);
+ Q_ASSERT(src + len <= size);
+ Q_ASSERT(dst + len <= size);
+ if (!_samples.copy(dst, src, len)) return;
}
+
+ // resize the buffer to it's new size
+ resizeStorage(size - length);
}
//***************************************************************************
bool Kwave::Stripe::combine(unsigned int offset, Kwave::Stripe &other)
{
- // detach the data and check for map count zero
- if (!m_data) return false;
+ QMutexLocker lock(&m_lock);
m_data.detach();
if (!m_data) return false; // OOM when detaching
- {
- QMutexLocker lock(&m_lock);
- if (m_data->mapCount()) return false; // data is mapped
+ if (m_data->mapCount()) return false; // data is mapped
- const unsigned int old_len = m_data->m_length;
- const unsigned int combined_len = offset + other.length();
- if (old_len < combined_len) {
- // resize the storage if necessary
- if (resizeStorage(combined_len) != combined_len)
- return false; // resizing failed, maybe OOM ?
- }
+ const unsigned int old_len = m_data->m_length;
+ const unsigned int combined_len = offset + other.length();
+ if (old_len < combined_len) {
+ // resize the storage if necessary
+ if (resizeStorage(combined_len) != combined_len)
+ return false; // resizing failed, maybe OOM ?
+ }
- // copy the data from the other stripe
- MappedArray _src(other);
- MappedArray _dst(*this);
- const sample_t *src = _src.constData();
- sample_t *dst = _dst.data();
- unsigned int len = _src.size() * sizeof(sample_t);
- if (!src || !dst) return false; // mmap of src or dst failed
+ // copy the data from the other stripe
+ MappedArray _src(other);
+ MappedArray _dst(*this);
+ const sample_t *src = _src.constData();
+ sample_t *dst = _dst.data();
+ unsigned int len = _src.size() * sizeof(sample_t);
+ if (!src || !dst) return false; // mmap of src or dst failed
- MEMCPY(dst + offset, src, len);
- }
+ MEMCPY(dst + offset, src, len);
return true;
}
@@ -505,7 +489,6 @@ void Kwave::Stripe::overwrite(unsigned int offset,
unsigned int srcoff, unsigned int srclen)
{
QMutexLocker lock(&m_lock);
- if (!m_data) return;
m_data.detach();
if (!m_data) return; // OOM when detaching
@@ -521,9 +504,8 @@ unsigned int Kwave::Stripe::read(Kwave::SampleArray &buffer,
unsigned int offset,
unsigned int length)
{
- if (!length || !m_data) return 0; // nothing to do !?
-
QMutexLocker lock(&m_lock);
+ if (!length || !m_data) return 0; // nothing to do !?
// for (unsigned int x=dstoff; (dstoff+x < length) && (x < buffer.size()); x++)
// buffer[x] = -(SAMPLE_MAX >> 2);
@@ -533,7 +515,7 @@ unsigned int Kwave::Stripe::read(Kwave::SampleArray &buffer,
Q_ASSERT(offset < m_data->m_length);
if (offset >= m_data->m_length) return 0;
- if (offset+length > m_data->m_length)
+ if ((offset + length) > m_data->m_length)
length = m_data->m_length - offset;
Q_ASSERT(length);
// if (!length) qDebug("--- [%u ... %u] (%u), offset=%u",
@@ -541,12 +523,14 @@ unsigned int Kwave::Stripe::read(Kwave::SampleArray &buffer,
if (!length) return 0;
// read directly through the memory manager, fastest path
- length = Kwave::MemoryManager::instance().readFrom(m_data->m_storage,
+ int bytes_read = Kwave::MemoryManager::instance().readFrom(
+ m_data->m_storage,
offset * sizeof(sample_t),
- &buffer[dstoff], length * sizeof(sample_t)) / sizeof(sample_t);
+ &buffer[dstoff], length * sizeof(sample_t)
+ );
-// qDebug("read done, length=%u", length);
- return length;
+// qDebug("read done, length=%u", read_len);
+ return (bytes_read > 0) ? (bytes_read / sizeof(sample_t)) : 0;
}
//***************************************************************************
@@ -554,11 +538,11 @@ void Kwave::Stripe::minMax(unsigned int first, unsigned int last,
sample_t &min, sample_t &max)
{
QMutexLocker lock(&m_lock);
-
if (!m_data) return;
+
MappedArray _samples(*this);
const sample_t *buffer = _samples.constData();
- if (!buffer || !m_data) return;
+ if (!buffer) return;
// loop over the mapped storage to get min/max
sample_t lo = min;
@@ -572,7 +556,7 @@ void Kwave::Stripe::minMax(unsigned int first, unsigned int last,
// speedup: process a block of 8 samples at once, to allow loop unrolling
const unsigned int block = 8;
while (Q_LIKELY(remaining >= block)) {
- for (unsigned int count = 0; count < block; count++) {
+ for (unsigned int count = 0; Q_LIKELY(count < block); count++) {
sample_t s = *(buffer++);
if (Q_UNLIKELY(s < lo)) lo = s;
if (Q_UNLIKELY(s > hi)) hi = s;
diff --git a/libkwave/Stripe.h b/libkwave/Stripe.h
index 6ea4a2f..641ddbd 100644
--- a/libkwave/Stripe.h
+++ b/libkwave/Stripe.h
@@ -232,6 +232,8 @@ namespace Kwave
* @return the length after the resize operation. Should be equal
* to the length that has been given as parameter. If not,
* something has failed.
+ * @note called internally only, under lock. It is made sure that
+ * m_data is already detached and not null
*/
unsigned int resizeStorage(unsigned int length);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic