]> sigrok.org Git - pulseview.git/commitdiff
Segment: Do not alter chunks when there are active iterators
authorSoeren Apel <redacted>
Sun, 19 Feb 2017 20:19:11 +0000 (21:19 +0100)
committerSoeren Apel <redacted>
Sun, 19 Feb 2017 20:19:11 +0000 (21:19 +0100)
pv/data/analogsegment.cpp
pv/data/analogsegment.hpp
pv/data/logicsegment.cpp
pv/data/logicsegment.hpp
pv/data/segment.cpp
pv/data/segment.hpp

index 38db0f123d3be31e95b98ee849fde237bf46819c..b3f310a144c5cd7ce2e18fb83ed242bd10526b6c 100644 (file)
@@ -106,17 +106,17 @@ const std::pair<float, float> AnalogSegment::get_min_max() const
        return std::make_pair(min_value_, max_value_);
 }
 
-SegmentAnalogDataIterator* AnalogSegment::begin_sample_iteration(uint64_t start) const
+SegmentAnalogDataIterator* AnalogSegment::begin_sample_iteration(uint64_t start)
 {
        return (SegmentAnalogDataIterator*)begin_raw_sample_iteration(start);
 }
 
-void AnalogSegment::continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase) const
+void AnalogSegment::continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase)
 {
        Segment::continue_raw_sample_iteration((SegmentRawDataIterator*)it, increase);
 }
 
-void AnalogSegment::end_sample_iteration(SegmentAnalogDataIterator* it) const
+void AnalogSegment::end_sample_iteration(SegmentAnalogDataIterator* it)
 {
        Segment::end_raw_sample_iteration((SegmentRawDataIterator*)it);
 }
index e6c312ade78d3b7157b43cc2f9584ba283381edb..27c9863b07b0a830806ba7ec5dd122653648a6e2 100644 (file)
@@ -89,9 +89,9 @@ public:
 
        const std::pair<float, float> get_min_max() const;
 
-       SegmentAnalogDataIterator* begin_sample_iteration(uint64_t start) const;
-       void continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase) const;
-       void end_sample_iteration(SegmentAnalogDataIterator* it) const;
+       SegmentAnalogDataIterator* begin_sample_iteration(uint64_t start);
+       void continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase);
+       void end_sample_iteration(SegmentAnalogDataIterator* it);
 
        void get_envelope_section(EnvelopeSection &s,
                uint64_t start, uint64_t end, float min_length) const;
index ddcf308d141be35b5f4e65db3dfe84aa4800f972..61382e6f0212a5e2591fe5863bebb2fe3dd87b14 100644 (file)
@@ -175,17 +175,17 @@ const uint8_t* LogicSegment::get_samples(int64_t start_sample,
        return get_raw_samples(start_sample, (end_sample-start_sample));
 }
 
-SegmentLogicDataIterator* LogicSegment::begin_sample_iteration(uint64_t start) const
+SegmentLogicDataIterator* LogicSegment::begin_sample_iteration(uint64_t start)
 {
        return (SegmentLogicDataIterator*)begin_raw_sample_iteration(start);
 }
 
-void LogicSegment::continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase) const
+void LogicSegment::continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase)
 {
        Segment::continue_raw_sample_iteration((SegmentRawDataIterator*)it, increase);
 }
 
-void LogicSegment::end_sample_iteration(SegmentLogicDataIterator* it) const
+void LogicSegment::end_sample_iteration(SegmentLogicDataIterator* it)
 {
        Segment::end_raw_sample_iteration((SegmentRawDataIterator*)it);
 }
index a7a38ebefa7761a7929073272d5e7dcabf1b0361..c450f0a905d9a96391e5ca759a65f06279acc225 100644 (file)
@@ -81,9 +81,9 @@ public:
 
        const uint8_t* get_samples(int64_t start_sample, int64_t end_sample) const;
 
-       SegmentLogicDataIterator* begin_sample_iteration(uint64_t start) const;
-       void continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase) const;
-       void end_sample_iteration(SegmentLogicDataIterator* it) const;
+       SegmentLogicDataIterator* begin_sample_iteration(uint64_t start);
+       void continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase);
+       void end_sample_iteration(SegmentLogicDataIterator* it);
 
 private:
        uint64_t unpack_sample(const uint8_t *ptr) const;
index cfe9aafa0385b7935e9e67fda9d026bedf4256f3..64d9cd66081a414aa1dc5460e64ec4cdc94d868e 100644 (file)
@@ -39,7 +39,9 @@ Segment::Segment(uint64_t samplerate, unsigned int unit_size) :
        sample_count_(0),
        start_time_(0),
        samplerate_(samplerate),
-       unit_size_(unit_size)
+       unit_size_(unit_size),
+       iterator_count_(0),
+       mem_optimization_requested_(false)
 {
        lock_guard<recursive_mutex> lock(mutex_);
        assert(unit_size_ > 0);
@@ -94,6 +96,12 @@ void Segment::free_unused_memory()
 {
        lock_guard<recursive_mutex> lock(mutex_);
 
+       // Do not mess with the data chunks if we have iterators pointing at them
+       if (iterator_count_ > 0) {
+               mem_optimization_requested_ = true;
+               return;
+       }
+
        // No more data will come in, so re-create the last chunk accordingly
        uint8_t* resized_chunk = new uint8_t[used_samples_ * unit_size_];
        memcpy(resized_chunk, current_chunk_, used_samples_ * unit_size_);
@@ -196,12 +204,14 @@ uint8_t* Segment::get_raw_samples(uint64_t start, uint64_t count) const
        return dest;
 }
 
-SegmentRawDataIterator* Segment::begin_raw_sample_iteration(uint64_t start) const
+SegmentRawDataIterator* Segment::begin_raw_sample_iteration(uint64_t start)
 {
        SegmentRawDataIterator* it = new SegmentRawDataIterator;
 
        assert(start < sample_count_);
 
+       iterator_count_++;
+
        it->sample_index = start;
        it->chunk_num = (start * unit_size_) / chunk_size_;
        it->chunk_offs = (start * unit_size_) % chunk_size_;
@@ -211,7 +221,7 @@ SegmentRawDataIterator* Segment::begin_raw_sample_iteration(uint64_t start) cons
        return it;
 }
 
-void Segment::continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase) const
+void Segment::continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase)
 {
        lock_guard<recursive_mutex> lock(mutex_);
 
@@ -233,9 +243,16 @@ void Segment::continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t
        it->value = it->chunk + it->chunk_offs;
 }
 
-void Segment::end_raw_sample_iteration(SegmentRawDataIterator* it) const
+void Segment::end_raw_sample_iteration(SegmentRawDataIterator* it)
 {
        delete it;
+
+       iterator_count_--;
+
+       if ((iterator_count_ == 0) && mem_optimization_requested_) {
+               mem_optimization_requested_ = false;
+               free_unused_memory();
+       }
 }
 
 
index 14122d6a001a8d1e7cd25c61091a3a38f35e3cb6..f1ff0f527370a80bbf6137d3291ee53715e6698d 100644 (file)
@@ -74,9 +74,9 @@ protected:
        void append_samples(void *data, uint64_t samples);
        uint8_t* get_raw_samples(uint64_t start, uint64_t count) const;
 
-       SegmentRawDataIterator* begin_raw_sample_iteration(uint64_t start) const;
-       void continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase) const;
-       void end_raw_sample_iteration(SegmentRawDataIterator* it) const;
+       SegmentRawDataIterator* begin_raw_sample_iteration(uint64_t start);
+       void continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase);
+       void end_raw_sample_iteration(SegmentRawDataIterator* it);
 
        mutable std::recursive_mutex mutex_;
        std::vector<uint8_t*> data_chunks_;
@@ -87,6 +87,8 @@ protected:
        double samplerate_;
        uint64_t chunk_size_;
        unsigned int unit_size_;
+       int iterator_count_;
+       bool mem_optimization_requested_;
 
        friend struct SegmentTest::SmallSize8Single;
        friend struct SegmentTest::MediumSize8Single;