From kde-commits Mon Oct 31 20:25:04 2016 From: Thomas Eschenbacher Date: Mon, 31 Oct 2016 20:25:04 +0000 To: kde-commits Subject: [kwave] libkwave: minor optimizations in class Stripe, detach only under lock Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=147794551323832 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 =3D=3D length) return length; // nothing to do // qDebug("Stripe::resizeStorage(%u)", length); = - Kwave::MemoryManager &mem =3D 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 =3D Kwave::MemoryManager::instance(); + // special case: zero length means delete if (length =3D=3D 0) { // delete the array @@ -340,44 +338,40 @@ unsigned int Kwave::Stripe::resizeStorage(unsigned in= t 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 =3D m_data->m_length; + if (m_data->m_length =3D=3D length) return old_length; // nothing to do = - unsigned int old_length =3D m_data->m_length; - if (m_data->m_length =3D=3D 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) !=3D 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) !=3D 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 =3D old_length; + unsigned int pos =3D old_length; = #ifdef STRICTLY_QT - MappedArray _samples(*this); - if (_samples.size() !=3D m_data->m_length) return 0; + MappedArray _samples(*this); + if (_samples.size() !=3D m_data->m_length) return 0; = - while (pos < length) { - _samples[pos++] =3D 0; - } + while (pos < length) { + _samples[pos++] =3D 0; + } #else - MappedArray _map(*this); - sample_t *samples =3D _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 =3D _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::Sam= pleArray &samples, unsigned int offset, unsigned int count) { - unsigned int appended =3D 0; + if (!count) return 0; // nothing to do + Q_ASSERT(offset + count <=3D 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 <=3D samples.size()); - if (offset + count > samples.size()) return 0; - -// qDebug("Stripe::append: adding %d samples", count); + unsigned int old_length =3D m_data->m_length; + unsigned int new_length =3D old_length + count; + Q_ASSERT(!m_data->mapCount()); + if (resizeStorage(new_length) !=3D new_length) + return 0; // out of memory = - unsigned int old_length =3D m_data->m_length; - unsigned int new_length =3D old_length + count; - Q_ASSERT(!m_data->mapCount()); - if (resizeStorage(new_length) !=3D new_length) - return 0; // out of memory + // append to the end of the area + unsigned int cnt =3D new_length - old_length; + Q_ASSERT(!m_data->mapCount()); + int bytes_appended =3D 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 =3D new_length - old_length; - Q_ASSERT(!m_data->mapCount()); - appended =3D 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=3D%u, length=3D%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 =3D m_data->m_length; + if (!size) return; = - const unsigned int size =3D m_data->m_length; - if (!size) return; + unsigned int first =3D offset; + unsigned int last =3D offset + length - 1; +// qDebug(" Stripe::deleteRange, me=3D[%u ... %u] del=3D[%u ... %u]= ", +// m_start, m_start+size-1, m_start + first, m_start + last); = - unsigned int first =3D offset; - unsigned int last =3D offset + length - 1; -// qDebug(" Stripe::deleteRange, me=3D[%u ... %u] del=3D[%u ... %u]", -// m_start, m_start+size-1, m_start + first, m_start + last); + Q_ASSERT(first < size); + if (first >=3D size) return; = - Q_ASSERT(first < size); - if (first >=3D size) return; + // put first/last into our area + if (last >=3D size) last =3D size - 1; + Q_ASSERT(last >=3D first); + if (last < first) return; = - // put first/last into our area - if (last >=3D size) last =3D size - 1; - Q_ASSERT(last >=3D first); - if (last < first) return; - - // move all samples after the deleted area to the left - unsigned int dst =3D first; - unsigned int src =3D last+1; - unsigned int len =3D size - src; -// qDebug(" Stripe: deleting %u ... %u", dst, src-1); - if (len) { - MappedArray _samples(*this); - - Q_ASSERT(src + len <=3D size); - Q_ASSERT(dst + len <=3D size); - if (!_samples.copy(dst, src, len)) return; - } + // move all samples after the deleted area to the left + unsigned int dst =3D first; + unsigned int src =3D last+1; + unsigned int len =3D 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 <=3D size); + Q_ASSERT(dst + len <=3D 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 =3D m_data->m_length; - const unsigned int combined_len =3D offset + other.length(); - if (old_len < combined_len) { - // resize the storage if necessary - if (resizeStorage(combined_len) !=3D combined_len) - return false; // resizing failed, maybe OOM ? - } + const unsigned int old_len =3D m_data->m_length; + const unsigned int combined_len =3D offset + other.length(); + if (old_len < combined_len) { + // resize the storage if necessary + if (resizeStorage(combined_len) !=3D 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 =3D _src.constData(); - sample_t *dst =3D _dst.data(); - unsigned int len =3D _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 =3D _src.constData(); + sample_t *dst =3D _dst.data(); + unsigned int len =3D _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 &bu= ffer, 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=3Ddstoff; (dstoff+x < length) && (x < buffer.size(= )); x++) // buffer[x] =3D -(SAMPLE_MAX >> 2); @@ -533,7 +515,7 @@ unsigned int Kwave::Stripe::read(Kwave::SampleArray &bu= ffer, = Q_ASSERT(offset < m_data->m_length); if (offset >=3D m_data->m_length) return 0; - if (offset+length > m_data->m_length) + if ((offset + length) > m_data->m_length) length =3D m_data->m_length - offset; Q_ASSERT(length); // if (!length) qDebug("--- [%u ... %u] (%u), offset=3D%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 =3D Kwave::MemoryManager::instance().readFrom(m_data->m_storage, + int bytes_read =3D 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=3D%u", length); - return length; +// qDebug("read done, length=3D%u", read_len); + return (bytes_read > 0) ? (bytes_read / sizeof(sample_t)) : 0; } = //************************************************************************= *** @@ -554,11 +538,11 @@ void Kwave::Stripe::minMax(unsigned int first, unsign= ed int last, sample_t &min, sample_t &max) { QMutexLocker lock(&m_lock); - if (!m_data) return; + MappedArray _samples(*this); const sample_t *buffer =3D _samples.constData(); - if (!buffer || !m_data) return; + if (!buffer) return; = // loop over the mapped storage to get min/max sample_t lo =3D 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 unroll= ing const unsigned int block =3D 8; while (Q_LIKELY(remaining >=3D block)) { - for (unsigned int count =3D 0; count < block; count++) { + for (unsigned int count =3D 0; Q_LIKELY(count < block); count++) { sample_t s =3D *(buffer++); if (Q_UNLIKELY(s < lo)) lo =3D s; if (Q_UNLIKELY(s > hi)) hi =3D 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); =20