From: Soeren Apel Date: Sat, 1 Jul 2017 20:24:06 +0000 (+0200) Subject: Make get_raw_samples() use provided mem instead of allocating X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=b82243f74a175f621af26aabbc0f32e2ecb125fa;p=pulseview.git Make get_raw_samples() use provided mem instead of allocating Until now, Segment::get_raw_samples() was allocating the required amount of memory and returned it to the caller to use. This way, there was always enough memory allocated for the data that was written to that memory location. However, in SignalBase::conversion_thread_proc() we want to use one memory location multiple times because we will create several layers of libsigrok wrapper objects around it. This only works if Segment::get_raw_samples() uses a given memory location instead of allocating it by itself. --- diff --git a/pv/data/analogsegment.cpp b/pv/data/analogsegment.cpp index 5e42556c..0860177e 100644 --- a/pv/data/analogsegment.cpp +++ b/pv/data/analogsegment.cpp @@ -96,18 +96,19 @@ void AnalogSegment::append_interleaved_samples(const float *data, prev_sample_count + 1); } -const float* AnalogSegment::get_samples( - int64_t start_sample, int64_t end_sample) const +void AnalogSegment::get_samples(int64_t start_sample, int64_t end_sample, + float* dest) const { assert(start_sample >= 0); assert(start_sample < (int64_t)sample_count_); assert(end_sample >= 0); assert(end_sample < (int64_t)sample_count_); assert(start_sample <= end_sample); + assert(dest != nullptr); lock_guard lock(mutex_); - return (float*)get_raw_samples(start_sample, (end_sample - start_sample)); + get_raw_samples(start_sample, (end_sample - start_sample), (uint8_t*)dest); } const pair AnalogSegment::get_min_max() const diff --git a/pv/data/analogsegment.hpp b/pv/data/analogsegment.hpp index 8dd6f5f1..8cb4d25b 100644 --- a/pv/data/analogsegment.hpp +++ b/pv/data/analogsegment.hpp @@ -86,8 +86,7 @@ public: void append_interleaved_samples(const float *data, size_t sample_count, size_t stride); - const float* get_samples(int64_t start_sample, - int64_t end_sample) const; + void get_samples(int64_t start_sample, int64_t end_sample, float* dest) const; const pair get_min_max() const; diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index 6ac66a1a..1d9f3c8f 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -653,7 +653,10 @@ void DecodeSignal::mux_logic_samples(const int64_t start, const int64_t end) const shared_ptr logic_data = ch.assigned_signal->logic_data(); const shared_ptr segment = logic_data->logic_segments().front(); segments.push_back(segment); - signal_data.push_back(segment->get_samples(start, end)); + + uint8_t* data = new uint8_t[(end - start) * segment->unit_size()]; + segment->get_samples(start, end, data); + signal_data.push_back(data); const int bitpos = ch.assigned_signal->logic_bit_index(); signal_in_bytepos.push_back(bitpos / 8); @@ -784,10 +787,12 @@ void DecodeSignal::decode_data( const int64_t chunk_end = min(i + chunk_sample_count, abs_start_samplenum + sample_count); - const uint8_t* chunk = segment_->get_samples(i, chunk_end); + int64_t data_size = (chunk_end - i) * unit_size; + uint8_t* chunk = new uint8_t[data_size]; + segment_->get_samples(i, chunk_end, chunk); if (srd_session_send(srd_session_, i, chunk_end, chunk, - (chunk_end - i) * unit_size, unit_size) != SRD_OK) { + data_size, unit_size) != SRD_OK) { error_message_ = tr("Decoder reported an error"); delete[] chunk; break; diff --git a/pv/data/logicsegment.cpp b/pv/data/logicsegment.cpp index b648f5d1..dff99c01 100644 --- a/pv/data/logicsegment.cpp +++ b/pv/data/logicsegment.cpp @@ -166,18 +166,19 @@ void LogicSegment::append_payload(void *data, uint64_t data_size) prev_sample_count + 1); } -const uint8_t* LogicSegment::get_samples(int64_t start_sample, - int64_t end_sample) const +void LogicSegment::get_samples(int64_t start_sample, + int64_t end_sample, uint8_t* dest) const { assert(start_sample >= 0); assert(start_sample <= (int64_t)sample_count_); assert(end_sample >= 0); assert(end_sample <= (int64_t)sample_count_); assert(start_sample <= end_sample); + assert(dest != nullptr); lock_guard lock(mutex_); - return get_raw_samples(start_sample, (end_sample - start_sample)); + get_raw_samples(start_sample, (end_sample - start_sample), dest); } SegmentLogicDataIterator* LogicSegment::begin_sample_iteration(uint64_t start) @@ -295,7 +296,8 @@ uint64_t LogicSegment::get_unpacked_sample(uint64_t index) const { assert(index < sample_count_); - const uint8_t* data = get_raw_samples(index, 1); + uint8_t* data = new uint8_t[unit_size_]; + get_raw_samples(index, 1, data); uint64_t sample = unpack_sample(data); delete[] data; diff --git a/pv/data/logicsegment.hpp b/pv/data/logicsegment.hpp index 3c012a45..3621e7f0 100644 --- a/pv/data/logicsegment.hpp +++ b/pv/data/logicsegment.hpp @@ -84,7 +84,7 @@ public: void append_payload(shared_ptr logic); void append_payload(void *data, uint64_t data_size); - const uint8_t* get_samples(int64_t start_sample, int64_t end_sample) const; + void get_samples(int64_t start_sample, int64_t end_sample, uint8_t* dest) const; SegmentLogicDataIterator* begin_sample_iteration(uint64_t start); void continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase); diff --git a/pv/data/segment.cpp b/pv/data/segment.cpp index 905b7927..ae9788fc 100644 --- a/pv/data/segment.cpp +++ b/pv/data/segment.cpp @@ -171,15 +171,16 @@ void Segment::append_samples(void* data, uint64_t samples) sample_count_ += samples; } -uint8_t* Segment::get_raw_samples(uint64_t start, uint64_t count) const +void Segment::get_raw_samples(uint64_t start, uint64_t count, + uint8_t* dest) const { assert(start < sample_count_); assert(start + count <= sample_count_); assert(count > 0); + assert(dest != nullptr); lock_guard lock(mutex_); - uint8_t* dest = new uint8_t[count * unit_size_]; uint8_t* dest_ptr = dest; uint64_t chunk_num = (start * unit_size_) / chunk_size_; @@ -199,8 +200,6 @@ uint8_t* Segment::get_raw_samples(uint64_t start, uint64_t count) const chunk_num++; chunk_offs = 0; } - - return dest; } SegmentRawDataIterator* Segment::begin_raw_sample_iteration(uint64_t start) diff --git a/pv/data/segment.hpp b/pv/data/segment.hpp index 7338bd38..db75ef71 100644 --- a/pv/data/segment.hpp +++ b/pv/data/segment.hpp @@ -76,7 +76,7 @@ public: protected: void append_single_sample(void *data); void append_samples(void *data, uint64_t samples); - uint8_t* get_raw_samples(uint64_t start, uint64_t count) const; + void get_raw_samples(uint64_t start, uint64_t count, uint8_t *dest) const; SegmentRawDataIterator* begin_raw_sample_iteration(uint64_t start); void continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase); diff --git a/pv/data/signalbase.cpp b/pv/data/signalbase.cpp index 3c0305a5..0f3c8f1b 100644 --- a/pv/data/signalbase.cpp +++ b/pv/data/signalbase.cpp @@ -274,6 +274,7 @@ void SignalBase::conversion_thread_proc(QObject* segment) float min_v, max_v; tie(min_v, max_v) = asegment->get_min_max(); + float* asamples = new float[ConversionBlockSize]; vector lsamples; lsamples.reserve(ConversionBlockSize); @@ -284,23 +285,21 @@ void SignalBase::conversion_thread_proc(QObject* segment) // Convert as many sample blocks as we can while ((end_sample - i) > ConversionBlockSize) { - const float* asamples = asegment->get_samples(i, i + ConversionBlockSize); + asegment->get_samples(i, i + ConversionBlockSize, asamples); for (uint32_t j = 0; j < ConversionBlockSize; j++) lsamples.push_back(convert_a2l_threshold(threshold, asamples[j])); lsegment->append_payload(lsamples.data(), lsamples.size()); samples_added(lsegment, i, i + ConversionBlockSize); i += ConversionBlockSize; lsamples.clear(); - delete[] asamples; } // Convert remaining samples - const float* asamples = asegment->get_samples(i, end_sample); + asegment->get_samples(i, end_sample, asamples); for (uint32_t j = 0; j < (end_sample - i); j++) lsamples.push_back(convert_a2l_threshold(threshold, asamples[j])); lsegment->append_payload(lsamples.data(), lsamples.size()); samples_added(lsegment, i, end_sample); - delete[] asamples; } if (conversion_type_ == A2LConversionBySchmittTrigger) { @@ -311,27 +310,27 @@ void SignalBase::conversion_thread_proc(QObject* segment) // Convert as many sample blocks as we can while ((end_sample - i) > ConversionBlockSize) { - const float* asamples = asegment->get_samples(i, i + ConversionBlockSize); + asegment->get_samples(i, i + ConversionBlockSize, asamples); for (uint32_t j = 0; j < ConversionBlockSize; j++) lsamples.push_back(convert_a2l_schmitt_trigger(lo_thr, hi_thr, asamples[j], state)); lsegment->append_payload(lsamples.data(), lsamples.size()); samples_added(lsegment, i, i + ConversionBlockSize); i += ConversionBlockSize; lsamples.clear(); - delete[] asamples; } // Convert remaining samples - const float* asamples = asegment->get_samples(i, end_sample); + asegment->get_samples(i, end_sample, asamples); for (uint32_t j = 0; j < (end_sample - i); j++) lsamples.push_back(convert_a2l_schmitt_trigger(lo_thr, hi_thr, asamples[j], state)); lsegment->append_payload(lsamples.data(), lsamples.size()); samples_added(lsegment, i, end_sample); - delete[] asamples; } // If acquisition is ongoing, start-/endsample may have changed end_sample = asegment->get_sample_count(); + + delete[] asamples; } } diff --git a/pv/storesession.cpp b/pv/storesession.cpp index cb643682..50815c26 100644 --- a/pv/storesession.cpp +++ b/pv/storesession.cpp @@ -240,8 +240,8 @@ void StoreSession::store_proc(vector< shared_ptr > achannel_li shared_ptr achannel = (achannel_list.at(i))->channel(); shared_ptr asegment = asegment_list.at(i); - const float *adata = - asegment->get_samples(start_sample_, start_sample_ + packet_len); + float *adata = new float[packet_len]; + asegment->get_samples(start_sample_, start_sample_ + packet_len, adata); auto analog = context->create_analog_packet( vector >{achannel}, @@ -257,11 +257,11 @@ void StoreSession::store_proc(vector< shared_ptr > achannel_li } if (lsegment) { - const uint8_t* ldata = - lsegment->get_samples(start_sample_, start_sample_ + packet_len); + const size_t data_size = packet_len * lunit_size; + uint8_t* ldata = new uint8_t[data_size]; + lsegment->get_samples(start_sample_, start_sample_ + packet_len, ldata); - const size_t length = packet_len * lunit_size; - auto logic = context->create_logic_packet((void*)ldata, length, lunit_size); + auto logic = context->create_logic_packet((void*)ldata, data_size, lunit_size); const string ldata_str = output_->receive(logic); if (output_stream_.is_open()) diff --git a/pv/views/trace/analogsignal.cpp b/pv/views/trace/analogsignal.cpp index b65eba56..f94a70f8 100644 --- a/pv/views/trace/analogsignal.cpp +++ b/pv/views/trace/analogsignal.cpp @@ -341,16 +341,16 @@ void AnalogSignal::paint_trace(QPainter &p, int64_t sample_count = min(points_count, TracePaintBlockSize); int64_t block_sample = 0; - const float *sample_block = segment->get_samples(start, start + sample_count); + float *sample_block = new float[TracePaintBlockSize]; + segment->get_samples(start, start + sample_count, sample_block); const int w = 2; for (int64_t sample = start; sample != end; sample++, block_sample++) { if (block_sample == TracePaintBlockSize) { block_sample = 0; - delete[] sample_block; sample_count = min(points_count - sample, TracePaintBlockSize); - sample_block = segment->get_samples(sample, sample + sample_count); + segment->get_samples(sample, sample + sample_count, sample_block); } const float x = (sample / samples_per_pixel -