From b1446b780d6d0b18dacb12e32b988ecdcea7c083 Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Fri, 10 Jun 2016 10:02:08 +0800 Subject: [PATCH] Improve memory alloc and free for each capture --- DSView/darkstyle/style.qss | 7 +- DSView/dsapplication.cpp | 10 +- DSView/icons/wait.gif | Bin 10071 -> 9469 bytes DSView/pv/data/analog.cpp | 6 + DSView/pv/data/analog.h | 1 + DSView/pv/data/analogsnapshot.cpp | 92 ++++++-- DSView/pv/data/analogsnapshot.h | 3 +- DSView/pv/data/decode/annotation.cpp | 6 + DSView/pv/data/decode/annotation.h | 2 + DSView/pv/data/decode/rowdata.h | 1 - DSView/pv/data/decoderstack.cpp | 81 +++++-- DSView/pv/data/decoderstack.h | 14 +- DSView/pv/data/dso.cpp | 7 + DSView/pv/data/dso.h | 1 + DSView/pv/data/dsosnapshot.cpp | 117 +++++++--- DSView/pv/data/dsosnapshot.h | 3 +- DSView/pv/data/group.cpp | 11 +- DSView/pv/data/group.h | 1 + DSView/pv/data/groupsnapshot.cpp | 22 +- DSView/pv/data/groupsnapshot.h | 5 +- DSView/pv/data/logic.cpp | 7 + DSView/pv/data/logic.h | 2 + DSView/pv/data/logicsnapshot.cpp | 91 ++++++-- DSView/pv/data/logicsnapshot.h | 3 +- DSView/pv/data/mathstack.cpp | 3 + DSView/pv/data/mathstack.h | 1 + DSView/pv/data/signaldata.cpp | 1 - DSView/pv/data/signaldata.h | 2 + DSView/pv/data/snapshot.cpp | 64 ++---- DSView/pv/data/snapshot.h | 10 +- DSView/pv/dialogs/fftoptions.cpp | 2 + DSView/pv/dialogs/protocolexp.cpp | 4 +- DSView/pv/dialogs/protocollist.cpp | 4 +- DSView/pv/dialogs/waitingdialog.cpp | 8 +- DSView/pv/dialogs/waitingdialog.h | 2 + DSView/pv/mainwindow.cpp | 5 +- DSView/pv/sigsession.cpp | 258 ++++++++++----------- DSView/pv/sigsession.h | 10 +- DSView/pv/storesession.cpp | 8 +- DSView/pv/storesession.h | 2 +- DSView/pv/toolbars/samplingbar.cpp | 6 +- DSView/pv/toolbars/trigbar.cpp | 5 + DSView/pv/toolbars/trigbar.h | 2 + DSView/pv/view/analogsignal.cpp | 2 +- DSView/pv/view/analogsignal.h | 2 +- DSView/pv/view/decodetrace.cpp | 31 +-- DSView/pv/view/decodetrace.h | 1 + DSView/pv/view/devmode.cpp | 2 +- DSView/pv/view/dsosignal.cpp | 2 +- DSView/pv/view/dsosignal.h | 2 +- DSView/pv/view/logicsignal.cpp | 4 +- DSView/pv/view/logicsignal.h | 4 +- DSView/pv/view/mathtrace.cpp | 4 +- DSView/pv/view/signal.cpp | 11 +- DSView/pv/view/signal.h | 11 +- DSView/pv/view/view.cpp | 13 +- DSView/pv/view/viewport.cpp | 4 + DSView/pv/widgets/decodergroupbox.cpp | 16 +- DSView/pv/widgets/decodergroupbox.h | 2 +- libsigrok4DSL/hardware/DSL/dscope.c | 3 + libsigrok4DSL/hardware/DSL/dsl.h | 1 + libsigrok4DSL/hardware/DSL/dslogic.c | 313 ++++++++++++++------------ libsigrok4DSL/hardware/demo/demo.c | 86 ++++--- libsigrok4DSL/libsigrok.h | 2 +- libsigrok4DSL/session.c | 66 +++--- libsigrok4DSL/trigger.c | 9 +- 66 files changed, 919 insertions(+), 562 deletions(-) diff --git a/DSView/darkstyle/style.qss b/DSView/darkstyle/style.qss index fdb48dec..975afee6 100755 --- a/DSView/darkstyle/style.qss +++ b/DSView/darkstyle/style.qss @@ -495,6 +495,7 @@ QTextEdit background-color: #201F1F; color: silver; border: 1px solid #3A3939; + margin: 0; } QPlainTextEdit @@ -591,7 +592,7 @@ QComboBox border: 1px solid #3A3939; border-radius: 2px; padding: 2px; - min-width: 75px; + min-width: 30px; } QPushButton:checked{ @@ -662,7 +663,7 @@ QAbstractSpinBox { background-color: #201F1F; color: silver; border-radius: 2px; - min-width: 75px; + min-width: 50px; } QAbstractSpinBox:up-button @@ -705,6 +706,8 @@ QAbstractSpinBox::down-arrow:hover QLabel { border: 0px solid black; + margin-left: 2px; + margin-right: 2px; } QTabWidget{ diff --git a/DSView/dsapplication.cpp b/DSView/dsapplication.cpp index 6ac6f80d..9facc855 100644 --- a/DSView/dsapplication.cpp +++ b/DSView/dsapplication.cpp @@ -39,7 +39,13 @@ bool DSApplication::notify(QObject *receiver_, QEvent *event_) msg.setStandardButtons(QMessageBox::Ok); msg.setIcon(QMessageBox::Warning); msg.exec(); - //QMessageBox::warning(NULL, "Application Error", e.what()) - return false; + } catch (...) { + QMessageBox msg(NULL); + msg.setText("Application Error"); + msg.setInformativeText("An unexpected error occurred"); + msg.setStandardButtons(QMessageBox::Ok); + msg.setIcon(QMessageBox::Warning); + msg.exec(); } + return false; } diff --git a/DSView/icons/wait.gif b/DSView/icons/wait.gif index 58279b9f1806d1c6ac1287f5e6cd86b600fce917..b3ba36a619d15ef20c1e7f5087fcfcef2ea452f9 100644 GIT binary patch literal 9469 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 F{ttdz>ZJex diff --git a/DSView/pv/data/analog.cpp b/DSView/pv/data/analog.cpp index 790c12a5..4d3c5ca5 100644 --- a/DSView/pv/data/analog.cpp +++ b/DSView/pv/data/analog.cpp @@ -53,6 +53,12 @@ void Analog::clear() BOOST_FOREACH(const boost::shared_ptr s, _snapshots) s->clear(); } +void Analog::init() +{ + //_snapshots.clear(); + BOOST_FOREACH(const boost::shared_ptr s, _snapshots) + s->init(); +} } // namespace data } // namespace pv diff --git a/DSView/pv/data/analog.h b/DSView/pv/data/analog.h index dc2a8571..c28b649f 100644 --- a/DSView/pv/data/analog.h +++ b/DSView/pv/data/analog.h @@ -46,6 +46,7 @@ public: get_snapshots(); void clear(); + void init(); private: std::deque< boost::shared_ptr > _snapshots; diff --git a/DSView/pv/data/analogsnapshot.cpp b/DSView/pv/data/analogsnapshot.cpp index 4b8c1719..005885c7 100644 --- a/DSView/pv/data/analogsnapshot.cpp +++ b/DSView/pv/data/analogsnapshot.cpp @@ -54,15 +54,41 @@ AnalogSnapshot::AnalogSnapshot() : AnalogSnapshot::~AnalogSnapshot() { - boost::lock_guard lock(_mutex); - BOOST_FOREACH(Envelope &e, _envelope_levels[0]) - free(e.samples); + free_envelop(); +} + +void AnalogSnapshot::free_envelop() +{ + for (unsigned int i = 0; i < _channel_num; i++) { + BOOST_FOREACH(Envelope &e, _envelope_levels[i]) { + if (e.samples) + free(e.samples); + } + } + memset(_envelope_levels, 0, sizeof(_envelope_levels)); +} + +void AnalogSnapshot::init() +{ + boost::lock_guard lock(_mutex); + _sample_count = 0; + _ring_sample_count = 0; + _memory_failed = false; + _last_ended = true; + for (unsigned int i = 0; i < _channel_num; i++) { + for (unsigned int level = 0; level < ScaleStepCount; level++) { + _envelope_levels[i][level].length = 0; + _envelope_levels[i][level].data_length = 0; + } + } } void AnalogSnapshot::clear() { - _sample_count = 0; - _ring_sample_count = 0; + boost::lock_guard lock(_mutex); + free_data(); + free_envelop(); + init(); } void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, unsigned int channel_num) @@ -70,17 +96,51 @@ void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t to _total_sample_count = total_sample_count; _channel_num = channel_num; _unit_size = sizeof(uint16_t)*channel_num; - boost::lock_guard lock(_mutex); - if (init(_total_sample_count*_channel_num) == SR_OK) { + + bool isOk = true; + uint64_t size = _total_sample_count * _unit_size + sizeof(uint64_t); + if (size != _capacity) { + free_data(); + _data = malloc(size); + if (_data) { + free_envelop(); + for (unsigned int i = 0; i < _channel_num; i++) { + uint64_t envelop_count = _total_sample_count / EnvelopeScaleFactor; + for (unsigned int level = 0; level < ScaleStepCount; level++) { + envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / + EnvelopeDataUnit) * EnvelopeDataUnit; + _envelope_levels[i][level].samples = (EnvelopeSample*)malloc(envelop_count * sizeof(EnvelopeSample)); + if (!_envelope_levels[i][level].samples) { + isOk = false; + break; + } + envelop_count = envelop_count / EnvelopeScaleFactor; + } + if (!isOk) + break; + } + } else { + isOk = true; + } + } + + if (isOk) { + _capacity = size; + _memory_failed = false; append_payload(analog); _last_ended = false; + } else { + free_data(); + free_envelop(); + _capacity = 0; + _memory_failed = true; } } void AnalogSnapshot::append_payload( const sr_datafeed_analog &analog) { - boost::lock_guard lock(_mutex); + boost::lock_guard lock(_mutex); append_data(analog.data, analog.num_samples); // Generate the first mip-map from the data @@ -98,13 +158,11 @@ const uint16_t* AnalogSnapshot::get_samples( assert(end_sample < (int64_t)get_sample_count()); assert(start_sample <= end_sample); - boost::lock_guard lock(_mutex); - // uint16_t *const data = new uint16_t[end_sample - start_sample]; // memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) * // (end_sample - start_sample)); // return data; - return (uint16_t*)_data.data() + start_sample * _channel_num; + return (uint16_t*)_data + start_sample * _channel_num; } void AnalogSnapshot::get_envelope_section(EnvelopeSection &s, @@ -114,8 +172,6 @@ void AnalogSnapshot::get_envelope_section(EnvelopeSection &s, assert(start <= end); assert(min_length > 0); - boost::lock_guard lock(_mutex); - const unsigned int min_level = max((int)floorf(logf(min_length) / LogEnvelopeScaleFactor) - 1, 0); const unsigned int scale_power = (min_level + 1) * @@ -139,8 +195,8 @@ void AnalogSnapshot::reallocate_envelope(Envelope &e) if (new_data_length > e.data_length) { e.data_length = new_data_length; - e.samples = (EnvelopeSample*)realloc(e.samples, - new_data_length * sizeof(EnvelopeSample)); +// e.samples = (EnvelopeSample*)realloc(e.samples, +// new_data_length * sizeof(EnvelopeSample)); } } @@ -154,7 +210,7 @@ void AnalogSnapshot::append_payload_to_envelope_levels() // Expand the data buffer to fit the new samples prev_length = e0.length; - e0.length = get_sample_count() / EnvelopeScaleFactor; + e0.length = _sample_count / EnvelopeScaleFactor; // Break off if there are no new samples to compute // if (e0.length == prev_length) @@ -169,7 +225,7 @@ void AnalogSnapshot::append_payload_to_envelope_levels() dest_ptr = e0.samples + prev_length; // Iterate through the samples to populate the first level mipmap - const uint16_t *const stop_src_ptr = (uint16_t*)_data.data() + + const uint16_t *const stop_src_ptr = (uint16_t*)_data + e0.length * EnvelopeScaleFactor * _channel_num; // for (const uint16_t *src_ptr = (uint16_t*)_data + // prev_length * EnvelopeScaleFactor; @@ -182,7 +238,7 @@ void AnalogSnapshot::append_payload_to_envelope_levels() // *dest_ptr++ = sub_sample; // } - for (const uint16_t *src_ptr = (uint16_t*)_data.data() + + for (const uint16_t *src_ptr = (uint16_t*)_data + prev_length * EnvelopeScaleFactor * _channel_num + i; src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num) { diff --git a/DSView/pv/data/analogsnapshot.h b/DSView/pv/data/analogsnapshot.h index b7a8813d..3f2b015a 100644 --- a/DSView/pv/data/analogsnapshot.h +++ b/DSView/pv/data/analogsnapshot.h @@ -74,6 +74,7 @@ public: virtual ~AnalogSnapshot(); void clear(); + void init(); void first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, unsigned int channel_num); @@ -86,8 +87,8 @@ public: uint64_t start, uint64_t end, float min_length, int probe_index) const; private: + void free_envelop(); void reallocate_envelope(Envelope &l); - void append_payload_to_envelope_levels(); private: diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp index 1cf20090..f2d30df5 100644 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -42,6 +42,7 @@ Annotation::Annotation(const srd_proto_data *const pdata) : assert(pda); _format = pda->ann_class; + _type = pda->ann_type; const char *const *annotations = (char**)pda->ann_text; while(*annotations) { @@ -76,6 +77,11 @@ int Annotation::format() const return _format; } +int Annotation::type() const +{ + return _type; +} + const std::vector& Annotation::annotations() const { return _annotations; diff --git a/DSView/pv/data/decode/annotation.h b/DSView/pv/data/decode/annotation.h index cba04c99..03e208ef 100644 --- a/DSView/pv/data/decode/annotation.h +++ b/DSView/pv/data/decode/annotation.h @@ -42,12 +42,14 @@ public: uint64_t start_sample() const; uint64_t end_sample() const; int format() const; + int type() const; const std::vector& annotations() const; private: uint64_t _start_sample; uint64_t _end_sample; int _format; + int _type; std::vector _annotations; }; diff --git a/DSView/pv/data/decode/rowdata.h b/DSView/pv/data/decode/rowdata.h index e2a84f31..40792cb7 100644 --- a/DSView/pv/data/decode/rowdata.h +++ b/DSView/pv/data/decode/rowdata.h @@ -35,7 +35,6 @@ class RowData public: RowData(); ~RowData(); - public: uint64_t get_max_sample() const; diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index c480a006..e0b64ab9 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -60,7 +60,7 @@ const int64_t DecoderStack::DecodeChunkLength = 4 * 1024; //const int64_t DecoderStack::DecodeChunkLength = 1024 * 1024; const unsigned int DecoderStack::DecodeNotifyPeriod = 1024; -mutex DecoderStack::_global_decode_mutex; +//mutex DecoderStack::_global_decode_mutex; DecoderStack::DecoderStack(pv::SigSession &session, const srd_decoder *const dec) : @@ -190,7 +190,7 @@ void DecoderStack::build_row() int64_t DecoderStack::samples_decoded() const { - lock_guard decode_lock(_output_mutex); + lock_guard decode_lock(_output_mutex); return _samples_decoded; } @@ -199,7 +199,7 @@ void DecoderStack::get_annotation_subset( const Row &row, uint64_t start_sample, uint64_t end_sample) const { - lock_guard lock(_output_mutex); + //lock_guard lock(_output_mutex); std::map::const_iterator iter = _rows.find(row); @@ -210,7 +210,7 @@ void DecoderStack::get_annotation_subset( uint64_t DecoderStack::get_max_annotation(const Row &row) { - lock_guard lock(_output_mutex); + //lock_guard lock(_output_mutex); std::map::const_iterator iter = _rows.find(row); @@ -222,7 +222,7 @@ uint64_t DecoderStack::get_max_annotation(const Row &row) uint64_t DecoderStack::get_min_annotation(const Row &row) { - lock_guard lock(_output_mutex); + //lock_guard lock(_output_mutex); std::map::const_iterator iter = _rows.find(row); @@ -232,14 +232,24 @@ uint64_t DecoderStack::get_min_annotation(const Row &row) return 0; } -std::map& DecoderStack::get_rows_gshow() +std::map DecoderStack::get_rows_gshow() { - return _rows_gshow; + std::map rows_gshow; + for (std::map::const_iterator i = _rows_gshow.begin(); + i != _rows_gshow.end(); i++) { + rows_gshow[(*i).first] = (*i).second; + } + return rows_gshow; } -std::map& DecoderStack::get_rows_lshow() +std::map DecoderStack::get_rows_lshow() { - return _rows_lshow; + std::map rows_lshow; + for (std::map::const_iterator i = _rows_lshow.begin(); + i != _rows_lshow.end(); i++) { + rows_lshow[(*i).first] = (*i).second; + } + return rows_lshow; } void DecoderStack::set_rows_gshow(const decode::Row row, bool show) @@ -260,7 +270,7 @@ void DecoderStack::set_rows_lshow(const decode::Row row, bool show) bool DecoderStack::has_annotations(const Row &row) const { - lock_guard lock(_output_mutex); + //lock_guard lock(_output_mutex); std::map::const_iterator iter = _rows.find(row); @@ -275,6 +285,7 @@ bool DecoderStack::has_annotations(const Row &row) const uint64_t DecoderStack::list_annotation_size() const { + lock_guard lock(_output_mutex); uint64_t max_annotation_size = 0; int row = 0; for (map::const_iterator i = _rows.begin(); @@ -291,6 +302,7 @@ uint64_t DecoderStack::list_annotation_size() const bool DecoderStack::list_annotation(pv::data::decode::Annotation &ann, uint16_t row_index, uint64_t col_index) const { + //lock_guard lock(_output_mutex); int row = 0; for (map::const_iterator i = _rows.begin(); i != _rows.end(); i++) { @@ -308,6 +320,7 @@ bool DecoderStack::list_annotation(pv::data::decode::Annotation &ann, bool DecoderStack::list_row_title(int row, QString &title) const { + //lock_guard lock(_output_mutex); int index = 0; for (map::const_iterator i = _rows.begin(); i != _rows.end(); i++) { @@ -324,23 +337,33 @@ bool DecoderStack::list_row_title(int row, QString &title) const QString DecoderStack::error_message() { - lock_guard lock(_output_mutex); + //lock_guard lock(_output_mutex); return _error_message; } void DecoderStack::clear() { + //lock_guard decode_lock(_output_mutex); _sample_count = 0; - _frame_complete = false; - _samples_decoded = 0; + _frame_complete = false; + _samples_decoded = 0; new_decode_data(); _error_message = QString(); - for (map::const_iterator i = _rows.begin(); + for (map::iterator i = _rows.begin(); i != _rows.end(); i++) _rows[(*i).first] = decode::RowData(); +// _rows.clear(); +// _rows_gshow.clear(); +// _rows_lshow.clear(); +// _class_rows.clear(); _no_memory = false; } +void DecoderStack::init() +{ + clear(); +} + void DecoderStack::stop_decode() { //_snapshot.reset(); @@ -380,6 +403,9 @@ void DecoderStack::begin_decode() return; } +// // Build rows +// build_row(); + // We get the logic data of the first channel in the list. // This works because we are currently assuming all // LogicSignals have the same data/snapshot @@ -425,10 +451,10 @@ uint64_t DecoderStack::get_max_sample_count() const boost::optional DecoderStack::wait_for_data() const { - unique_lock input_lock(_input_mutex); + //unique_lock input_lock(_input_mutex); while(!boost::this_thread::interruption_requested() && !_frame_complete && (uint64_t)_samples_decoded >= _sample_count) - _input_cond.wait(input_lock); + //_input_cond.wait(input_lock); return boost::make_optional( !boost::this_thread::interruption_requested() && ((uint64_t)_samples_decoded < _sample_count || !_frame_complete), @@ -456,6 +482,7 @@ void DecoderStack::decode_data( } } + uint64_t entry_cnt = 0; uint8_t chunk_type = 0; uint64_t i = decode_start; while(!boost::this_thread::interruption_requested() && @@ -475,6 +502,7 @@ void DecoderStack::decode_data( if (logic_di && logic_di->logic_mask != 0) { uint64_t cur_pos = logic_di->cur_pos; + assert(cur_pos < _snapshot->get_sample_count()); uint64_t sample = _snapshot->get_sample(cur_pos) & logic_di->logic_mask; if (logic_di->edge_index == -1) { std::vector pos_vector; @@ -509,7 +537,7 @@ void DecoderStack::decode_data( } { - lock_guard lock(_output_mutex); + lock_guard lock(_output_mutex); _samples_decoded = i - decode_start + 1; } @@ -517,6 +545,7 @@ void DecoderStack::decode_data( last_cnt = i; new_decode_data(); } + entry_cnt++; } _options_changed = false; decode_done(); @@ -524,7 +553,7 @@ void DecoderStack::decode_data( void DecoderStack::decode_proc() { - lock_guard decode_lock(_global_decode_mutex); + //lock_guard decode_lock(_global_decode_mutex); optional sample_count; srd_session *session; @@ -545,7 +574,7 @@ void DecoderStack::decode_proc() // Get the intial sample count { - unique_lock input_lock(_input_mutex); + //unique_lock input_lock(_input_mutex); sample_count = _sample_count = _snapshot->get_sample_count(); } @@ -610,7 +639,7 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder) DecoderStack *const d = (DecoderStack*)decoder; assert(d); - lock_guard lock(d->_output_mutex); + //lock_guard lock(d->_output_mutex); if (d->_no_memory) return; @@ -638,13 +667,14 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder) assert(row_iter != d->_rows.end()); if (row_iter == d->_rows.end()) { - qDebug() << "Unexpected annotation: decoder = " << decc << - ", format = " << a.format(); - assert(0); - return; - } + qDebug() << "Unexpected annotation: decoder = " << decc << + ", format = " << a.format(); + assert(0); + return; + } // Add the annotation + lock_guard lock(d->_output_mutex); if (!(*row_iter).second.push_annotation(a)) d->_no_memory = true; } @@ -678,6 +708,7 @@ void DecoderStack::on_frame_ended() int DecoderStack::list_rows_size() { + //lock_guard lock(_output_mutex); int rows_size = 0; int row = 0; for (map::const_iterator i = _rows.begin(); diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index 7516c907..8f38d361 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -99,8 +99,8 @@ public: uint64_t get_max_annotation(const decode::Row &row); uint64_t get_min_annotation(const decode::Row &row); // except instant(end=start) annotation - std::map &get_rows_gshow(); - std::map &get_rows_lshow(); + std::map get_rows_gshow(); + std::map get_rows_lshow(); void set_rows_gshow(const decode::Row row, bool show); void set_rows_lshow(const decode::Row row, bool show); @@ -117,6 +117,7 @@ public: QString error_message(); void clear(); + void init(); uint64_t get_max_sample_count() const; @@ -168,18 +169,19 @@ private: * @todo A proper solution should be implemented to allow multiple * decode operations. */ - static boost::mutex _global_decode_mutex; + //static boost::mutex _global_decode_mutex; std::list< boost::shared_ptr > _stack; boost::shared_ptr _snapshot; - mutable boost::mutex _input_mutex; - mutable boost::condition_variable _input_cond; + //mutable boost::mutex _input_mutex; + //mutable boost::condition_variable _input_cond; uint64_t _sample_count; bool _frame_complete; - mutable boost::mutex _output_mutex; + mutable boost::recursive_mutex _output_mutex; + //mutable boost::mutex _output_mutex; int64_t _samples_decoded; std::map _rows; diff --git a/DSView/pv/data/dso.cpp b/DSView/pv/data/dso.cpp index fe3ce699..2a6ce2c7 100644 --- a/DSView/pv/data/dso.cpp +++ b/DSView/pv/data/dso.cpp @@ -53,5 +53,12 @@ void Dso::clear() s->clear(); } +void Dso::init() +{ + //_snapshots.clear(); + BOOST_FOREACH(const boost::shared_ptr s, _snapshots) + s->init(); +} + } // namespace data } // namespace pv diff --git a/DSView/pv/data/dso.h b/DSView/pv/data/dso.h index 0e724ed6..0902972a 100644 --- a/DSView/pv/data/dso.h +++ b/DSView/pv/data/dso.h @@ -45,6 +45,7 @@ public: get_snapshots(); void clear(); + void init(); private: std::deque< boost::shared_ptr > _snapshots; diff --git a/DSView/pv/data/dsosnapshot.cpp b/DSView/pv/data/dsosnapshot.cpp index b4f93c91..0bd6c6c2 100644 --- a/DSView/pv/data/dsosnapshot.cpp +++ b/DSView/pv/data/dsosnapshot.cpp @@ -58,15 +58,42 @@ DsoSnapshot::DsoSnapshot() : DsoSnapshot::~DsoSnapshot() { - boost::lock_guard lock(_mutex); - BOOST_FOREACH(Envelope &e, _envelope_levels[0]) - free(e.samples); + free_envelop(); +} + +void DsoSnapshot::free_envelop() +{ + for (unsigned int i = 0; i < _channel_num; i++) { + BOOST_FOREACH(Envelope &e, _envelope_levels[i]) { + if (e.samples) + free(e.samples); + } + } + memset(_envelope_levels, 0, sizeof(_envelope_levels)); +} + +void DsoSnapshot::init() +{ + boost::lock_guard lock(_mutex); + _sample_count = 0; + _ring_sample_count = 0; + _memory_failed = false; + _last_ended = true; + _envelope_done = false; + for (unsigned int i = 0; i < _channel_num; i++) { + for (unsigned int level = 0; level < ScaleStepCount; level++) { + _envelope_levels[i][level].length = 0; + _envelope_levels[i][level].data_length = 0; + } + } } void DsoSnapshot::clear() { - _sample_count = 0; - _ring_sample_count = 0; + boost::lock_guard lock(_mutex); + free_data(); + free_envelop(); + init(); } void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, unsigned int channel_num, bool instant) @@ -74,18 +101,52 @@ void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sampl _total_sample_count = total_sample_count; _channel_num = channel_num; _instant = instant; - boost::lock_guard lock(_mutex); - if (init(_total_sample_count) == SR_OK) { + + bool isOk = true; + uint64_t size = _total_sample_count * _unit_size + sizeof(uint64_t); + if (size != _capacity) { + free_data(); + _data = malloc(size); + if (_data) { + free_envelop(); + for (unsigned int i = 0; i < _channel_num; i++) { + uint64_t envelop_count = _total_sample_count / EnvelopeScaleFactor; + for (unsigned int level = 0; level < ScaleStepCount; level++) { + envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / + EnvelopeDataUnit) * EnvelopeDataUnit; + _envelope_levels[i][level].samples = (EnvelopeSample*)malloc(envelop_count * sizeof(EnvelopeSample)); + if (!_envelope_levels[i][level].samples) { + isOk = false; + break; + } + envelop_count = envelop_count / EnvelopeScaleFactor; + } + if (!isOk) + break; + } + } else { + isOk = true; + } + } + + if (isOk) { + _capacity = size; + _memory_failed = false; append_payload(dso); _last_ended = false; + } else { + free_data(); + free_envelop(); + _capacity = 0; + _memory_failed = true; } } void DsoSnapshot::append_payload(const sr_datafeed_dso &dso) { - boost::lock_guard lock(_mutex); + boost::lock_guard lock(_mutex); - if (_channel_num > 0) { + if (_channel_num > 0 && dso.num_samples != 0) { refill_data(dso.data, dso.num_samples, _instant); // Generate the first mip-map from the data @@ -96,6 +157,7 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso) void DsoSnapshot::enable_envelope(bool enable) { + boost::lock_guard lock(_mutex); if (!_envelope_done && enable) append_payload_to_envelope_levels(true); _envelope_en = enable; @@ -112,13 +174,11 @@ const uint8_t *DsoSnapshot::get_samples( assert(end_sample < (int64_t)get_sample_count()); assert(start_sample <= end_sample); - boost::lock_guard lock(_mutex); - // uint16_t *const data = new uint16_t[end_sample - start_sample]; // memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) * // (end_sample - start_sample)); // return data; - return (uint8_t*)_data.data() + start_sample * _channel_num + index * (_channel_num != 1); + return (uint8_t*)_data + start_sample * _channel_num + index * (_channel_num != 1); } void DsoSnapshot::get_envelope_section(EnvelopeSection &s, @@ -128,7 +188,10 @@ void DsoSnapshot::get_envelope_section(EnvelopeSection &s, assert(start <= end); assert(min_length > 0); - boost::lock_guard lock(_mutex); + if (!_envelope_done) { + s.length = 0; + return; + } const unsigned int min_level = max((int)floorf(logf(min_length) / LogEnvelopeScaleFactor) - 1, 0); @@ -156,8 +219,8 @@ void DsoSnapshot::reallocate_envelope(Envelope &e) if (new_data_length > e.data_length) { e.data_length = new_data_length; - e.samples = (EnvelopeSample*)realloc(e.samples, - new_data_length * sizeof(EnvelopeSample)); +// e.samples = (EnvelopeSample*)realloc(e.samples, +// new_data_length * sizeof(EnvelopeSample)); } } @@ -185,9 +248,9 @@ void DsoSnapshot::append_payload_to_envelope_levels(bool header) dest_ptr = e0.samples + prev_length; // Iterate through the samples to populate the first level mipmap - const uint8_t *const stop_src_ptr = (uint8_t*)_data.data() + + const uint8_t *const stop_src_ptr = (uint8_t*)_data + e0.length * EnvelopeScaleFactor * _channel_num; - for (const uint8_t *src_ptr = (uint8_t*)_data.data() + + for (const uint8_t *src_ptr = (uint8_t*)_data + prev_length * EnvelopeScaleFactor * _channel_num + i; src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num) { @@ -255,7 +318,7 @@ void DsoSnapshot::append_payload_to_envelope_levels(bool header) double DsoSnapshot::cal_vrms(double zero_off, int index) const { assert(index >= 0); - assert(index < _channel_num); + //assert(index < _channel_num); // root-meam-squart value double vrms_pre = 0; @@ -263,9 +326,9 @@ double DsoSnapshot::cal_vrms(double zero_off, int index) const double tmp; // Iterate through the samples to populate the first level mipmap - const uint8_t *const stop_src_ptr = (uint8_t*)_data.data() + - _sample_count * _channel_num; - for (const uint8_t *src_ptr = (uint8_t*)_data.data() + index; + const uint8_t *const stop_src_ptr = (uint8_t*)_data + + get_sample_count() * _channel_num; + for (const uint8_t *src_ptr = (uint8_t*)_data + (index % _channel_num); src_ptr < stop_src_ptr; src_ptr += VrmsScaleFactor * _channel_num) { const uint8_t * begin_src_ptr = @@ -279,7 +342,7 @@ double DsoSnapshot::cal_vrms(double zero_off, int index) const vrms += tmp * tmp; begin_src_ptr += _channel_num; } - vrms = vrms_pre + vrms / _sample_count; + vrms = vrms_pre + vrms / get_sample_count(); vrms_pre = vrms; } vrms = std::pow(vrms, 0.5); @@ -290,16 +353,16 @@ double DsoSnapshot::cal_vrms(double zero_off, int index) const double DsoSnapshot::cal_vmean(int index) const { assert(index >= 0); - assert(index < _channel_num); + //assert(index < _channel_num); // mean value double vmean_pre = 0; double vmean = 0; // Iterate through the samples to populate the first level mipmap - const uint8_t *const stop_src_ptr = (uint8_t*)_data.data() + - _sample_count * _channel_num; - for (const uint8_t *src_ptr = (uint8_t*)_data.data() + index; + const uint8_t *const stop_src_ptr = (uint8_t*)_data + + get_sample_count() * _channel_num; + for (const uint8_t *src_ptr = (uint8_t*)_data + (index % _channel_num); src_ptr < stop_src_ptr; src_ptr += VrmsScaleFactor * _channel_num) { const uint8_t * begin_src_ptr = @@ -312,7 +375,7 @@ double DsoSnapshot::cal_vmean(int index) const vmean += *begin_src_ptr; begin_src_ptr += _channel_num; } - vmean = vmean_pre + vmean / _sample_count; + vmean = vmean_pre + vmean / get_sample_count(); vmean_pre = vmean; } diff --git a/DSView/pv/data/dsosnapshot.h b/DSView/pv/data/dsosnapshot.h index e1488374..df6376e0 100644 --- a/DSView/pv/data/dsosnapshot.h +++ b/DSView/pv/data/dsosnapshot.h @@ -75,6 +75,7 @@ public: virtual ~DsoSnapshot(); void clear(); + void init(); void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, unsigned int channel_num, bool instant); @@ -92,8 +93,8 @@ public: double cal_vmean(int index) const; private: + void free_envelop(); void reallocate_envelope(Envelope &l); - void append_payload_to_envelope_levels(bool header); private: diff --git a/DSView/pv/data/group.cpp b/DSView/pv/data/group.cpp index 3d086e08..7d027db3 100644 --- a/DSView/pv/data/group.cpp +++ b/DSView/pv/data/group.cpp @@ -23,6 +23,8 @@ #include "group.h" #include "groupsnapshot.h" +#include + using namespace boost; using namespace std; @@ -46,7 +48,14 @@ deque< boost::shared_ptr >& Group::get_snapshots() void Group::clear() { - _snapshots.clear(); + BOOST_FOREACH(const boost::shared_ptr s, _snapshots) + s->clear(); +} + +void Group::init() +{ + BOOST_FOREACH(const boost::shared_ptr s, _snapshots) + s->init(); } } // namespace data diff --git a/DSView/pv/data/group.h b/DSView/pv/data/group.h index f166bf94..1312c6ee 100644 --- a/DSView/pv/data/group.h +++ b/DSView/pv/data/group.h @@ -45,6 +45,7 @@ public: get_snapshots(); void clear(); + void init(); private: std::deque< boost::shared_ptr > _snapshots; diff --git a/DSView/pv/data/groupsnapshot.cpp b/DSView/pv/data/groupsnapshot.cpp index 6f0026dd..e7cac5d3 100644 --- a/DSView/pv/data/groupsnapshot.cpp +++ b/DSView/pv/data/groupsnapshot.cpp @@ -54,7 +54,7 @@ GroupSnapshot::GroupSnapshot(const boost::shared_ptr &_logic_snap { assert(_logic_snapshot); - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); memset(_envelope_levels, 0, sizeof(_envelope_levels)); _data = _logic_snapshot->get_data(); _sample_count = _logic_snapshot->get_sample_count(); @@ -96,20 +96,30 @@ GroupSnapshot::GroupSnapshot(const boost::shared_ptr &_logic_snap GroupSnapshot::~GroupSnapshot() { - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); BOOST_FOREACH(Envelope &e, _envelope_levels) free(e.samples); } +void GroupSnapshot::init() +{ + +} + +void GroupSnapshot::clear() +{ + +} + uint64_t GroupSnapshot::get_sample_count() const { - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); return _sample_count; } void GroupSnapshot::append_payload() { - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); // Generate the first mip-map from the data append_payload_to_envelope_levels(); @@ -126,7 +136,7 @@ const uint16_t* GroupSnapshot::get_samples( int64_t i; uint16_t tmpl, tmpr; - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); uint16_t *const data = new uint16_t[end_sample - start_sample]; // memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) * @@ -155,7 +165,7 @@ void GroupSnapshot::get_envelope_section(EnvelopeSection &s, assert(start <= end); assert(min_length > 0); - boost::lock_guard lock(_mutex); + //boost::lock_guard lock(_mutex); const unsigned int min_level = max((int)floorf(logf(min_length) / LogEnvelopeScaleFactor) - 1, 0); diff --git a/DSView/pv/data/groupsnapshot.h b/DSView/pv/data/groupsnapshot.h index 6ad65522..4d87b001 100644 --- a/DSView/pv/data/groupsnapshot.h +++ b/DSView/pv/data/groupsnapshot.h @@ -79,6 +79,9 @@ public: virtual ~GroupSnapshot(); + void clear(); + void init(); + void append_payload(); uint64_t get_sample_count() const; @@ -96,7 +99,7 @@ private: private: struct Envelope _envelope_levels[ScaleStepCount]; - mutable boost::recursive_mutex _mutex; + //mutable boost::recursive_mutex _mutex; const void *_data; uint64_t _sample_count; int _unit_size; diff --git a/DSView/pv/data/logic.cpp b/DSView/pv/data/logic.cpp index f2a7cee4..ee499f43 100644 --- a/DSView/pv/data/logic.cpp +++ b/DSView/pv/data/logic.cpp @@ -55,5 +55,12 @@ void Logic::clear() s->clear(); } +void Logic::init() +{ + //_snapshots.clear(); + BOOST_FOREACH(const boost::shared_ptr s, _snapshots) + s->init(); +} + } // namespace data } // namespace pv diff --git a/DSView/pv/data/logic.h b/DSView/pv/data/logic.h index fe815264..f163b35c 100644 --- a/DSView/pv/data/logic.h +++ b/DSView/pv/data/logic.h @@ -47,6 +47,8 @@ public: void clear(); + void init(); + private: std::deque< boost::shared_ptr > _snapshots; }; diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index 17da83c7..40ee3087 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -54,16 +54,37 @@ LogicSnapshot::LogicSnapshot() : LogicSnapshot::~LogicSnapshot() { - boost::lock_guard lock(_mutex); - BOOST_FOREACH(MipMapLevel &l, _mip_map) - free(l.data); + free_mipmap(); +} + +void LogicSnapshot::free_mipmap() +{ + BOOST_FOREACH(MipMapLevel &l, _mip_map) { + if (l.data) + free(l.data); + } + memset(_mip_map, 0, sizeof(_mip_map)); +} + +void LogicSnapshot::init() +{ + boost::lock_guard lock(_mutex); + _sample_count = 0; + _ring_sample_count = 0; + _memory_failed = false; + _last_ended = true; + for (unsigned int level = 0; level < ScaleStepCount; level++) { + _mip_map[level].length = 0; + _mip_map[level].data_length = 0; + } } void LogicSnapshot::clear() { - _sample_count = 0; - _ring_sample_count = 0; - memset(_mip_map, 0, sizeof(_mip_map)); + boost::lock_guard lock(_mutex); + free_data(); + free_mipmap(); + init(); } void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total_sample_count, unsigned int channel_num) @@ -71,10 +92,40 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total _total_sample_count = total_sample_count; _channel_num = channel_num; _unit_size = logic.unitsize; - boost::lock_guard lock(_mutex); - if (init(_total_sample_count * _channel_num) == SR_OK) { + + bool isOk = true; + uint64_t size = _total_sample_count * _unit_size + sizeof(uint64_t); + if (size != _capacity) { + free_data(); + _data = malloc(size); + if (_data) { + free_mipmap(); + uint64_t mipmap_count = _total_sample_count / MipMapScaleFactor; + for (unsigned int level = 0; level < ScaleStepCount; level++) { + mipmap_count = ((mipmap_count + MipMapDataUnit - 1) / + MipMapDataUnit) * MipMapDataUnit; + _mip_map[level].data = malloc(mipmap_count * _unit_size + sizeof(uint64_t)); + if (!_mip_map[level].data) { + isOk = false; + break; + } + mipmap_count = mipmap_count / MipMapScaleFactor; + } + } else { + isOk = false; + } + } + + if (isOk) { + _capacity = size; + _memory_failed = false; append_payload(logic); _last_ended = false; + } else { + free_data(); + free_mipmap(); + _capacity = 0; + _memory_failed = true; } } @@ -84,7 +135,7 @@ void LogicSnapshot::append_payload( assert(_unit_size == logic.unitsize); assert((logic.length % _unit_size) == 0); - boost::lock_guard lock(_mutex); + boost::lock_guard lock(_mutex); append_data(logic.data, logic.length / _unit_size); @@ -96,17 +147,16 @@ uint8_t * LogicSnapshot::get_samples(int64_t start_sample, int64_t end_sample) c { //assert(data); assert(start_sample >= 0); - assert(start_sample <= (int64_t)_sample_count); + assert(start_sample <= (int64_t)get_sample_count()); assert(end_sample >= 0); - assert(end_sample <= (int64_t)_sample_count); + assert(end_sample <= (int64_t)get_sample_count()); assert(start_sample <= end_sample); (void)end_sample; - //lock_guard lock(_mutex); //const size_t size = (end_sample - start_sample) * _unit_size; //memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size); - return (uint8_t*)_data.data() + start_sample * _unit_size; + return (uint8_t*)_data + start_sample * _unit_size; } void LogicSnapshot::reallocate_mipmap_level(MipMapLevel &m) @@ -118,8 +168,8 @@ void LogicSnapshot::reallocate_mipmap_level(MipMapLevel &m) m.data_length = new_data_length; // Padding is added to allow for the uint64_t write word - m.data = realloc(m.data, new_data_length * _unit_size + - sizeof(uint64_t)); +// m.data = realloc(m.data, new_data_length * _unit_size + +// sizeof(uint64_t)); } } @@ -145,9 +195,9 @@ void LogicSnapshot::append_payload_to_mipmap() dest_ptr = (uint8_t*)m0.data + prev_length * _unit_size; // Iterate through the samples to populate the first level mipmap - const uint8_t *const end_src_ptr = (uint8_t*)_data.data() + + const uint8_t *const end_src_ptr = (uint8_t*)_data + m0.length * _unit_size * MipMapScaleFactor; - for (src_ptr = (uint8_t*)_data.data() + + for (src_ptr = (uint8_t*)_data + prev_length * _unit_size * MipMapScaleFactor; src_ptr < end_src_ptr;) { @@ -213,16 +263,15 @@ void LogicSnapshot::get_subsampled_edges( if (!edges.empty()) edges.clear(); - if (_sample_count == 0) + if (get_sample_count() == 0) return; - assert(end < _sample_count); + assert(end < get_sample_count()); assert(start <= end); assert(min_length > 0); assert(sig_index >= 0); assert(sig_index < 64); - boost::lock_guard lock(_mutex); uint64_t index = start; bool last_sample; const uint64_t block_length = (uint64_t)max(min_length, 1.0f); @@ -573,7 +622,7 @@ uint64_t LogicSnapshot::get_subsample(int level, uint64_t offset) const { assert(level >= 0); assert(_mip_map[level].data); - return *(uint64_t*)((uint8_t*)_mip_map[level].data + + return *(uint64_t*)((uint8_t*)_mip_map[level].data + _unit_size * offset); } diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 475d8bf0..d1f70635 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -66,6 +66,7 @@ public: virtual ~LogicSnapshot(); void clear(); + void init(); void first_payload(const sr_datafeed_logic &logic, uint64_t total_sample_count, unsigned int channel_num); @@ -74,8 +75,8 @@ public: uint8_t * get_samples(int64_t start_sample, int64_t end_sample) const; private: + void free_mipmap(); void reallocate_mipmap_level(MipMapLevel &m); - void append_payload_to_mipmap(); public: diff --git a/DSView/pv/data/mathstack.cpp b/DSView/pv/data/mathstack.cpp index 13aa18d6..69f33e2c 100644 --- a/DSView/pv/data/mathstack.cpp +++ b/DSView/pv/data/mathstack.cpp @@ -72,7 +72,10 @@ MathStack::~MathStack() void MathStack::clear() { +} +void MathStack::init() +{ } int MathStack::get_index() const diff --git a/DSView/pv/data/mathstack.h b/DSView/pv/data/mathstack.h index 6616ac44..d9e32423 100644 --- a/DSView/pv/data/mathstack.h +++ b/DSView/pv/data/mathstack.h @@ -66,6 +66,7 @@ public: MathStack(pv::SigSession &_session, int index); virtual ~MathStack(); void clear(); + void init(); int get_index() const; diff --git a/DSView/pv/data/signaldata.cpp b/DSView/pv/data/signaldata.cpp index afb7f240..00c7e5ef 100644 --- a/DSView/pv/data/signaldata.cpp +++ b/DSView/pv/data/signaldata.cpp @@ -42,7 +42,6 @@ void SignalData::set_samplerate(double samplerate) { assert(samplerate > 0); _samplerate = samplerate; - clear(); } double SignalData::get_start_time() const diff --git a/DSView/pv/data/signaldata.h b/DSView/pv/data/signaldata.h index 464215da..7f96312e 100644 --- a/DSView/pv/data/signaldata.h +++ b/DSView/pv/data/signaldata.h @@ -40,6 +40,8 @@ public: virtual void clear() = 0; + virtual void init() = 0; + double get_start_time() const; protected: diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp index 37eb9acf..df2c8011 100644 --- a/DSView/pv/data/snapshot.cpp +++ b/DSView/pv/data/snapshot.cpp @@ -35,45 +35,31 @@ namespace pv { namespace data { Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int channel_num) : + _data(NULL), + _capacity(0), _channel_num(channel_num), _sample_count(0), _total_sample_count(total_sample_count), _ring_sample_count(0), _unit_size(unit_size), - _memory_failed(true), + _memory_failed(false), _last_ended(true) { - boost::lock_guard lock(_mutex); - assert(_unit_size > 0); + assert(_unit_size > 0); } Snapshot::~Snapshot() { - boost::lock_guard lock(_mutex); - _data.clear(); + free_data(); } -int Snapshot::init(uint64_t _total_sample_len) +void Snapshot::free_data() { -// boost::lock_guard lock(_mutex); -// _data = malloc(_total_sample_len * _unit_size + -// sizeof(uint64_t)); - -// if (_data == NULL) -// return SR_ERR_MALLOC; -// else -// return SR_OK; - - boost::lock_guard lock(_mutex); - uint64_t size = _total_sample_len * _unit_size + sizeof(uint64_t); - try{ - _data.resize(size); - } catch(...) { - _memory_failed = true; - return SR_ERR_MALLOC; + if (_data) { + free(_data); + _data = NULL; + _capacity = 0; } - _memory_failed = false; - return SR_OK; } bool Snapshot::memory_failed() const @@ -83,7 +69,7 @@ bool Snapshot::memory_failed() const bool Snapshot::empty() const { - if (_sample_count == 0 || _memory_failed) + if (get_sample_count() == 0 || _memory_failed || !_data) return true; else return false; @@ -101,41 +87,35 @@ void Snapshot::set_last_ended(bool ended) uint64_t Snapshot::get_sample_count() const { - boost::lock_guard lock(_mutex); + boost::lock_guard lock(_mutex); return _sample_count; } const void* Snapshot::get_data() const { - boost::lock_guard lock(_mutex); - return _data.data(); + return _data; } int Snapshot::unit_size() const { - boost::lock_guard lock(_mutex); return _unit_size; } unsigned int Snapshot::get_channel_num() const { - boost::lock_guard lock(_mutex); return _channel_num; } uint64_t Snapshot::get_sample(uint64_t index) const { - boost::lock_guard lock(_mutex); + assert(_data); + assert(index < get_sample_count()); - assert(_data.data()); - assert(index < _sample_count); - - return *(uint64_t*)((uint8_t*)_data.data() + index * _unit_size); + return *(uint64_t*)((uint8_t*)_data + index * _unit_size); } void Snapshot::append_data(void *data, uint64_t samples) { - boost::lock_guard lock(_mutex); // _data = realloc(_data, (_sample_count + samples) * _unit_size + // sizeof(uint64_t)); if (_sample_count + samples < _total_sample_count) @@ -144,13 +124,13 @@ void Snapshot::append_data(void *data, uint64_t samples) _sample_count = _total_sample_count; if (_ring_sample_count + samples > _total_sample_count) { - memcpy((uint8_t*)_data.data() + _ring_sample_count * _unit_size, + memcpy((uint8_t*)_data + _ring_sample_count * _unit_size, data, (_total_sample_count - _ring_sample_count) * _unit_size); _ring_sample_count = (samples + _ring_sample_count - _total_sample_count) % _total_sample_count; - memcpy((uint8_t*)_data.data(), + memcpy((uint8_t*)_data, data, _ring_sample_count * _unit_size); } else { - memcpy((uint8_t*)_data.data() + _ring_sample_count * _unit_size, + memcpy((uint8_t*)_data + _ring_sample_count * _unit_size, data, samples * _unit_size); _ring_sample_count += samples; } @@ -158,13 +138,11 @@ void Snapshot::append_data(void *data, uint64_t samples) void Snapshot::refill_data(void *data, uint64_t samples, bool instant) { - boost::lock_guard lock(_mutex); - if (instant) { - memcpy((uint8_t*)_data.data() + _sample_count * _channel_num, data, samples*_channel_num); + memcpy((uint8_t*)_data + _sample_count * _channel_num, data, samples*_channel_num); _sample_count = (_sample_count + samples) % (_total_sample_count + 1); } else { - memcpy((uint8_t*)_data.data(), data, samples*_channel_num); + memcpy((uint8_t*)_data, data, samples*_channel_num); _sample_count = samples; } diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h index ca0e8831..5fa3e440 100644 --- a/DSView/pv/data/snapshot.h +++ b/DSView/pv/data/snapshot.h @@ -38,7 +38,8 @@ public: virtual ~Snapshot(); - int init(uint64_t _total_sample_len); + virtual void clear() = 0; + virtual void init() = 0; uint64_t get_sample_count() const; @@ -59,10 +60,13 @@ public: protected: void append_data(void *data, uint64_t samples); void refill_data(void *data, uint64_t samples, bool instant); + void free_data(); protected: - mutable boost::recursive_mutex _mutex; - std::vector _data; + mutable boost::recursive_mutex _mutex; + //std::vector _data; + void* _data; + uint64_t _capacity; unsigned int _channel_num; uint64_t _sample_count; uint64_t _total_sample_count; diff --git a/DSView/pv/dialogs/fftoptions.cpp b/DSView/pv/dialogs/fftoptions.cpp index ed7280b8..d2344ca3 100644 --- a/DSView/pv/dialogs/fftoptions.cpp +++ b/DSView/pv/dialogs/fftoptions.cpp @@ -118,6 +118,8 @@ FftOptions::FftOptions(QWidget *parent, SigSession &session) : _view_combobox->addItem(view_modes[i], qVariantFromValue(i)); } + assert(_view_combobox->count() > 0); + _view_combobox->setCurrentIndex(_view_combobox->count()-1); for (int i = 0; i < dbv_ranges.size(); i++) { _dbv_combobox->addItem(QString::number(dbv_ranges[i]), diff --git a/DSView/pv/dialogs/protocolexp.cpp b/DSView/pv/dialogs/protocolexp.cpp index ab79796b..af0ef69c 100644 --- a/DSView/pv/dialogs/protocolexp.cpp +++ b/DSView/pv/dialogs/protocolexp.cpp @@ -65,7 +65,7 @@ ProtocolExp::ProtocolExp(QWidget *parent, SigSession &session) : const boost::shared_ptr& decoder_stack = decoder_model->getDecoderStack(); if (decoder_stack) { int row_index = 0; - const std::map& rows(decoder_stack->get_rows_lshow()); + const std::map rows = decoder_stack->get_rows_lshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if ((*i).second) { @@ -149,7 +149,7 @@ void ProtocolExp::accept() const boost::shared_ptr& decoder_stack = decoder_model->getDecoderStack(); int row_index = 0; Row row; - const std::map& rows_lshow(decoder_stack->get_rows_lshow()); + const std::map rows_lshow = decoder_stack->get_rows_lshow(); for (std::map::const_iterator i = rows_lshow.begin(); i != rows_lshow.end(); i++) { if ((*i).second) { diff --git a/DSView/pv/dialogs/protocollist.cpp b/DSView/pv/dialogs/protocollist.cpp index eb605476..da2451a0 100644 --- a/DSView/pv/dialogs/protocollist.cpp +++ b/DSView/pv/dialogs/protocollist.cpp @@ -128,7 +128,7 @@ void ProtocolList::set_protocol(int index) _session.get_decoder_model()->setDecoderStack(decoder_stack); int row_index = 0; - const std::map& rows(decoder_stack->get_rows_lshow()); + const std::map rows = decoder_stack->get_rows_lshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { QLabel *row_label = new QLabel((*i).first.title(), this); @@ -166,7 +166,7 @@ void ProtocolList::on_row_check(bool show) if (!decoder_stack) return; - std::map& rows(decoder_stack->get_rows_lshow()); + std::map rows = decoder_stack->get_rows_lshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if (index-- == 0) { diff --git a/DSView/pv/dialogs/waitingdialog.cpp b/DSView/pv/dialogs/waitingdialog.cpp index cb0c742d..1bd53daa 100644 --- a/DSView/pv/dialogs/waitingdialog.cpp +++ b/DSView/pv/dialogs/waitingdialog.cpp @@ -48,15 +48,15 @@ WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptrsetFixedSize((GIF_SIZE+TIP_WIDTH)*2, (GIF_SIZE+TIP_HEIGHT)*2); + this->setFixedSize((GIF_WIDTH+TIP_WIDTH)*1.2, (GIF_HEIGHT+TIP_HEIGHT)*4); int midx = this->width() / 2; int midy = this->height() / 2; - this->setWindowOpacity(0.7); + this->setWindowOpacity(0.5); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); label = new QLabel(this); label->setStyleSheet("background-color: transparent;"); - label->setGeometry(midx-GIF_SIZE/2, midy-GIF_SIZE/2, GIF_SIZE, GIF_SIZE); + label->setGeometry(midx-GIF_WIDTH/2, midy-GIF_HEIGHT/2, GIF_WIDTH, GIF_HEIGHT); movie = new QMovie(":/icons/wait.gif"); label->setMovie(movie); @@ -66,7 +66,7 @@ WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptrsetFont(font); - tips->setGeometry(midx-TIP_WIDTH/2, midy+GIF_SIZE/2, TIP_WIDTH, TIP_HEIGHT); + tips->setGeometry(midx-TIP_WIDTH/2, midy+GIF_HEIGHT/2, TIP_WIDTH, TIP_HEIGHT); index = 0; timer = new QTimer(); diff --git a/DSView/pv/dialogs/waitingdialog.h b/DSView/pv/dialogs/waitingdialog.h index 4b3480f6..7693dd78 100644 --- a/DSView/pv/dialogs/waitingdialog.h +++ b/DSView/pv/dialogs/waitingdialog.h @@ -42,6 +42,8 @@ class WaitingDialog : public QDialog private: static const int GIF_SIZE = 80; + static const int GIF_WIDTH = 220; + static const int GIF_HEIGHT = 20; static const int TIP_WIDTH = 100; static const int TIP_HEIGHT = 40; static const int WPOINTS_NUM = 6; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index fccd54af..7dd2e349 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -543,6 +543,7 @@ void MainWindow::on_trigger(bool visible) _trigger_dock->setVisible(false); _dso_trigger_dock->setVisible(visible); } + _trig_bar->update_trig_btn(visible); } void MainWindow::commit_trigger(bool instant) @@ -689,7 +690,8 @@ bool MainWindow::load_session(QString name) if (!isEnabled) probe->enabled = false; } - _session.init_signals(); + //_session.init_signals(); + _session.reload(); // load signal setting BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { @@ -698,6 +700,7 @@ bool MainWindow::load_session(QString name) if ((s->get_index() == obj["index"].toDouble()) && (s->get_type() == obj["type"].toDouble())) { s->set_colour(QColor(obj["colour"].toString())); + s->set_name(g_strdup(obj["name"].toString().toStdString().c_str())); boost::shared_ptr logicSig; if (logicSig = dynamic_pointer_cast(s)) { diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 6584c09b..53eca6cd 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -98,13 +98,26 @@ SigSession::SigSession(DeviceManager &device_manager) : _group_cnt = 0; register_hotplug_callback(); _view_timer.stop(); - _view_timer.setSingleShot(true); _refresh_timer.stop(); _refresh_timer.setSingleShot(true); _data_lock = false; + _data_updated = false; _decoder_model = new pv::data::DecoderModel(this); - connect(this, SIGNAL(start_timer(int)), &_view_timer, SLOT(start(int))); - //connect(&_view_timer, SIGNAL(timeout()), this, SLOT(refresh())); + + // Create snapshots & data containers + _cur_logic_snapshot.reset(new data::LogicSnapshot()); + _logic_data.reset(new data::Logic()); + _logic_data->push_snapshot(_cur_logic_snapshot); + _cur_dso_snapshot.reset(new data::DsoSnapshot()); + _dso_data.reset(new data::Dso()); + _dso_data->push_snapshot(_cur_dso_snapshot); + _cur_analog_snapshot.reset(new data::AnalogSnapshot()); + _analog_data.reset(new data::Analog()); + _analog_data->push_snapshot(_cur_analog_snapshot); + _group_data.reset(new data::Group()); + _group_cnt = 0; + + connect(&_view_timer, SIGNAL(timeout()), this, SLOT(check_update())); connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(data_unlock())); } @@ -135,7 +148,7 @@ void SigSession::set_device(boost::shared_ptr dev_inst) throw(Q using pv::device::Device; // Ensure we are not capturing before setting the device - stop_capture(); + //stop_capture(); if (_dev_inst) { sr_session_datafeed_callback_remove_all(); @@ -414,14 +427,14 @@ void SigSession::release_device(device::DevInst *dev_inst) (void)dev_inst; assert(_dev_inst.get() == dev_inst); - assert(_capture_state != Running); + assert(get_capture_state() != Running); _dev_inst = boost::shared_ptr(); //_dev_inst.reset(); } SigSession::capture_state SigSession::get_capture_state() const { - boost::lock_guard lock(_sampling_mutex); + boost::lock_guard lock(_sampling_mutex); return _capture_state; } @@ -443,10 +456,55 @@ double SigSession::cur_sampletime() const return _cur_samplelimits * 1.0 / _cur_samplerate; } +void SigSession::capture_init() +{ + _cur_samplerate = _dev_inst->get_sample_rate(); + _cur_samplelimits = _dev_inst->get_sample_limit(); + _data_updated = false; + _view_timer.start(ViewTime); + + // Init and Set sample rate for all SignalData + // Logic/Analog/Dso + if (_logic_data) { + _logic_data->init(); + _logic_data->set_samplerate(_cur_samplerate); + } + if (_analog_data) { + _analog_data->init(); + _analog_data->set_samplerate(_cur_samplerate); + } + if (_dso_data) { + _dso_data->init(); + _dso_data->set_samplerate(_cur_samplerate); + } + // Group + if (_group_data) { + _group_data->init(); + _group_data->set_samplerate(_cur_samplerate); + } +#ifdef ENABLE_DECODE + // DecoderStack + BOOST_FOREACH(const boost::shared_ptr d, _decode_traces) + { + assert(d); + d->decoder()->init(); + d->decoder()->set_samplerate(_cur_samplerate); + } +#endif + // MathStack + BOOST_FOREACH(const boost::shared_ptr m, _math_traces) + { + assert(m); + m->get_math_stack()->init(); + m->get_math_stack()->set_samplerate(_cur_samplerate); + } +} + void SigSession::start_capture(bool instant, boost::function error_handler) { stop_capture(); + capture_init(); // Check that a device instance has been selected. if (!_dev_inst) { @@ -466,7 +524,8 @@ void SigSession::start_capture(bool instant, } if (!l) { error_handler(tr("No probes enabled.")); - capture_state_changed(_capture_state); + data_updated(); + capture_state_changed(SigSession::Stopped); return; } @@ -475,8 +534,6 @@ void SigSession::start_capture(bool instant, _instant = instant; else _instant = true; - if (~_instant) - _view_timer.blockSignals(false); // Begin the session _sampling_thread.reset(new boost::thread( @@ -487,6 +544,7 @@ void SigSession::start_capture(bool instant, void SigSession::stop_capture() { _instant = false; + _view_timer.stop(); #ifdef ENABLE_DECODE for (vector< boost::shared_ptr >::iterator i = _decode_traces.begin(); @@ -497,7 +555,6 @@ void SigSession::stop_capture() if (get_capture_state() != Running) return; sr_session_stop(); - _view_timer.blockSignals(true); // Check that sampling stopped if (_sampling_thread.get()) @@ -507,19 +564,19 @@ void SigSession::stop_capture() vector< boost::shared_ptr > SigSession::get_signals() { - boost::lock_guard lock(_signals_mutex); + //boost::lock_guard lock(_signals_mutex); return _signals; } vector< boost::shared_ptr > SigSession::get_group_signals() { - boost::lock_guard lock(_signals_mutex); + //boost::lock_guard lock(_signals_mutex); return _group_traces; } set< boost::shared_ptr > SigSession::get_data() const { - lock_guard lock(_signals_mutex); + //lock_guard lock(_signals_mutex); set< boost::shared_ptr > data; BOOST_FOREACH(const boost::shared_ptr sig, _signals) { assert(sig); @@ -577,7 +634,7 @@ const void* SigSession::get_buf(int& unit_size, uint64_t &length) void SigSession::set_capture_state(capture_state state) { - boost::lock_guard lock(_sampling_mutex); + boost::lock_guard lock(_sampling_mutex); _capture_state = state; data_updated(); capture_state_changed(state); @@ -601,65 +658,24 @@ void SigSession::sample_thread_proc(boost::shared_ptr dev_inst, set_capture_state(Running); dev_inst->run(); - set_capture_state(Stopped); // Confirm that SR_DF_END was received assert(_cur_logic_snapshot->last_ended()); assert(_cur_dso_snapshot->last_ended()); assert(_cur_analog_snapshot->last_ended()); + set_capture_state(Stopped); +} + +void SigSession::check_update() +{ + if (_data_updated) { + data_updated(); + _data_updated = false; + } } void SigSession::feed_in_header(const sr_dev_inst *sdi) { - GVariant *gvar; - int ret; - - // Read out the sample rate - if(sdi->driver) - { - ret = sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar); - if (ret != SR_OK) { - hardware_connect_failed(); - return; - } - - _cur_samplerate = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - - ret = sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_LIMIT_SAMPLES, &gvar); - if (ret != SR_OK) { - hardware_connect_failed(); - return; - } - - _cur_samplelimits = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - } - - // Set the sample rate of all SignalData - // Logic/Analog/Dso - if (_logic_data) - _logic_data->set_samplerate(_cur_samplerate); - if (_analog_data) - _analog_data->set_samplerate(_cur_samplerate); - if (_dso_data) - _dso_data->set_samplerate(_cur_samplerate); -#ifdef ENABLE_DECODE - // DecoderStack - BOOST_FOREACH(const boost::shared_ptr d, _decode_traces) - { - assert(d); - d->decoder()->set_samplerate(_cur_samplerate); - } -#endif - // MathStack - BOOST_FOREACH(const boost::shared_ptr m, _math_traces) - { - assert(m); - m->get_math_stack()->set_samplerate(_cur_samplerate); - } - // Group - _group_data->set_samplerate(_cur_samplerate); } void SigSession::add_group() @@ -677,6 +693,7 @@ void SigSession::add_group() //_group_data.reset(new data::Group(_last_sample_rate)); // if (_group_data->get_snapshots().empty()) // _group_data->set_samplerate(_dev_inst->get_sample_rate()); + _group_data->init(); _group_data->set_samplerate(_cur_samplerate); const boost::shared_ptr signal( new view::GroupSignal("New Group", @@ -747,6 +764,15 @@ void SigSession::init_signals() unsigned int dso_probe_count = 0; unsigned int analog_probe_count = 0; + if (_logic_data) + _logic_data->clear(); + if (_dso_data) + _dso_data->clear(); + if (_analog_data) + _analog_data->clear(); + if (_group_data) + _group_data->clear(); + #ifdef ENABLE_DECODE // Clear the decode traces _decode_traces.clear(); @@ -777,51 +803,14 @@ void SigSession::init_signals() } } - // Create snapshots - { - _cur_logic_snapshot.reset(new data::LogicSnapshot()); - assert(_cur_logic_snapshot); - - _cur_dso_snapshot.reset(new data::DsoSnapshot()); - assert(_cur_dso_snapshot); - - _cur_analog_snapshot.reset(new data::AnalogSnapshot()); - assert(_cur_analog_snapshot); - } - - // Create data containers for the coming data snapshots - { - if (logic_probe_count != 0) { - _logic_data.reset(new data::Logic()); - assert(_logic_data); - _logic_data->push_snapshot(_cur_logic_snapshot); - } - - if (dso_probe_count != 0) { - _dso_data.reset(new data::Dso()); - assert(_dso_data); - _dso_data->push_snapshot(_cur_dso_snapshot); - } - - if (analog_probe_count != 0) { - _analog_data.reset(new data::Analog()); - assert(_analog_data); - _analog_data->push_snapshot(_cur_analog_snapshot); - } - - _group_data.reset(new data::Group()); - assert(_group_data); - _group_cnt = 0; - } - // Make the logic probe list { _group_traces.clear(); vector< boost::shared_ptr >().swap(_group_traces); - for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { - const sr_channel *const probe = - (const sr_channel *)l->data; + for (GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { + sr_channel *probe = + ( sr_channel *)l->data; assert(probe); signal.reset(); switch(probe->type) { @@ -852,7 +841,7 @@ void SigSession::init_signals() } mathTraces_rebuild(); - data_updated(); + //data_updated(); } void SigSession::reload() @@ -868,9 +857,9 @@ void SigSession::reload() // Make the logic probe list { - for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { - const sr_channel *const probe = - (const sr_channel *)l->data; + for (GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { + sr_channel *probe = + (sr_channel *)l->data; assert(probe); signal.reset(); switch(probe->type) { @@ -918,37 +907,38 @@ void SigSession::reload() void SigSession::refresh(int holdtime) { + boost::lock_guard lock(_data_mutex); + + if (strncmp(_dev_inst->dev_inst()->driver->name, "virtual", 7)) { + _data_lock = true; + _refresh_timer.start(holdtime); + } if (_logic_data) { - _logic_data->clear(); + _logic_data->init(); //_cur_logic_snapshot.reset(); #ifdef ENABLE_DECODE BOOST_FOREACH(const boost::shared_ptr d, _decode_traces) { assert(d); - d->decoder()->clear(); + d->decoder()->init(); } #endif } if (_dso_data) { - _dso_data->clear(); - //_cur_dso_snapshot.reset(); - _cur_dso_snapshot->set_last_ended(true); + _dso_data->init(); // MathStack BOOST_FOREACH(const boost::shared_ptr m, _math_traces) { assert(m); - m->get_math_stack()->clear(); + m->get_math_stack()->init(); } } if (_analog_data) { - _analog_data->clear(); + _analog_data->init(); //_cur_analog_snapshot.reset(); } - if (strncmp(_dev_inst->dev_inst()->driver->name, "virtual", 7)) { - _data_lock = true; - _refresh_timer.start(holdtime); - } - data_updated(); + //data_updated(); + _data_updated = true; } void SigSession::data_unlock() @@ -1002,9 +992,8 @@ void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) void SigSession::feed_in_logic(const sr_datafeed_logic &logic) { - boost::lock_guard lock(_data_mutex); - - if (!_logic_data || !_cur_logic_snapshot) { + //boost::lock_guard lock(_data_mutex); + if (!_logic_data || _cur_logic_snapshot->memory_failed()) { qDebug() << "Unexpected logic packet"; return; } @@ -1036,9 +1025,9 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic) void SigSession::feed_in_dso(const sr_datafeed_dso &dso) { - boost::lock_guard lock(_data_mutex); + //boost::lock_guard lock(_data_mutex); - if(!_dso_data || !_cur_dso_snapshot) + if(!_dso_data || _cur_dso_snapshot->memory_failed()) { qDebug() << "Unexpected dso packet"; return; // This dso packet was not expected. @@ -1074,14 +1063,15 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso) } receive_data(dso.num_samples); - data_updated(); + //data_updated(); + _data_updated = true; } void SigSession::feed_in_analog(const sr_datafeed_analog &analog) { - boost::lock_guard lock(_data_mutex); + //boost::lock_guard lock(_data_mutex); - if(!_analog_data || !_cur_analog_snapshot) + if(!_analog_data || _cur_analog_snapshot->memory_failed()) { qDebug() << "Unexpected analog packet"; return; // This analog packet was not expected. @@ -1101,7 +1091,8 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog) } receive_data(analog.num_samples); - data_updated(); + //data_updated(); + _data_updated = true; } void SigSession::data_feed_in(const struct sr_dev_inst *sdi, @@ -1110,6 +1101,8 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, assert(sdi); assert(packet); + boost::lock_guard lock(_data_mutex); + if (_data_lock) return; @@ -1147,7 +1140,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, case SR_DF_END: { { - boost::lock_guard lock(_data_mutex); + //boost::lock_guard lock(_data_mutex); if (!_cur_logic_snapshot->empty()) { BOOST_FOREACH(const boost::shared_ptr g, _group_traces) { @@ -1167,7 +1160,6 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, d->frame_ended(); #endif } - frame_ended(); break; } @@ -1378,7 +1370,7 @@ bool SigSession::add_decoder(srd_decoder *const dec) vector< boost::shared_ptr > SigSession::get_decode_signals() const { - lock_guard lock(_signals_mutex); + //lock_guard lock(_signals_mutex); return _decode_traces; } @@ -1491,7 +1483,7 @@ void SigSession::mathTraces_rebuild() vector< boost::shared_ptr > SigSession::get_math_signals() { - lock_guard lock(_signals_mutex); + //lock_guard lock(_signals_mutex); return _math_traces; } diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 95769fe6..8ff3e0d9 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -92,7 +92,7 @@ class SigSession : public QObject private: static constexpr float Oversampling = 2.0f; - static const int ViewTime = 800; + static const int ViewTime = 50; static const int RefreshTime = 500; bool saveFileThreadRunning = false; @@ -134,7 +134,7 @@ public: void start_capture(bool instant, boost::function error_handler); - + void capture_init(); void stop_capture(); std::set< boost::shared_ptr > get_data() const; @@ -236,13 +236,13 @@ private: */ boost::shared_ptr _dev_inst; - mutable boost::mutex _sampling_mutex; + mutable boost::mutex _sampling_mutex; capture_state _capture_state; bool _instant; uint64_t _cur_samplerate; uint64_t _cur_samplelimits; - mutable boost::mutex _signals_mutex; + //mutable boost::mutex _signals_mutex; std::vector< boost::shared_ptr > _signals; std::vector< boost::shared_ptr > _group_traces; #ifdef ENABLE_DECODE @@ -272,6 +272,7 @@ private: QTimer _view_timer; QTimer _refresh_timer; bool _data_lock; + bool _data_updated; signals: void capture_state_changed(int state); @@ -319,6 +320,7 @@ public slots: private slots: void cancelSaveFile(); void data_unlock(); + void check_update(); private: // TODO: This should not be necessary. Multiple concurrent diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 14fe7cd1..baac25c4 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -60,13 +60,13 @@ StoreSession::~StoreSession() pair StoreSession::progress() const { - lock_guard lock(_mutex); + //lock_guard lock(_mutex); return make_pair(_units_stored, _unit_count); } const QString& StoreSession::error() const { - lock_guard lock(_mutex); + //lock_guard lock(_mutex); return _error; } @@ -163,7 +163,7 @@ void StoreSession::store_proc(shared_ptr snapshot) assert(unit_size != 0); { - lock_guard lock(_mutex); + //lock_guard lock(_mutex); _unit_count = snapshot->get_sample_count(); } @@ -188,7 +188,7 @@ void StoreSession::store_proc(shared_ptr snapshot) start_sample = end_sample; { - lock_guard lock(_mutex); + //lock_guard lock(_mutex); _units_stored = start_sample; } } diff --git a/DSView/pv/storesession.h b/DSView/pv/storesession.h index 63f8003e..0493ff84 100644 --- a/DSView/pv/storesession.h +++ b/DSView/pv/storesession.h @@ -72,7 +72,7 @@ private: boost::thread _thread; - mutable boost::mutex _mutex; + //mutable boost::mutex _mutex; uint64_t _units_stored; uint64_t _unit_count; QString _error; diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index fd3c3129..c3bfd339 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -470,12 +470,12 @@ void SamplingBar::commit_sample_rate() // Get last samplerate last_sample_rate = get_selected_device()->get_sample_rate(); - if (last_sample_rate != sample_rate) { + //if (last_sample_rate != sample_rate) { // Set the samplerate get_selected_device()->set_config(NULL, NULL, SR_CONF_SAMPLERATE, g_variant_new_uint64(sample_rate)); - } + //} _updating_sample_rate = false; } @@ -731,6 +731,8 @@ void SamplingBar::on_device_selected() if (_updating_device_selector) return; + _session.stop_capture(); + const shared_ptr dev_inst = get_selected_device(); if (!dev_inst) return; diff --git a/DSView/pv/toolbars/trigbar.cpp b/DSView/pv/toolbars/trigbar.cpp index 50207684..509b28fc 100644 --- a/DSView/pv/toolbars/trigbar.cpp +++ b/DSView/pv/toolbars/trigbar.cpp @@ -119,6 +119,11 @@ void TrigBar::trigger_clicked() on_trigger(_trig_button.isChecked()); } +void TrigBar::update_trig_btn(bool checked) +{ + _trig_button.setChecked(checked); +} + void TrigBar::measure_clicked() { on_measure(_measure_button.isChecked()); diff --git a/DSView/pv/toolbars/trigbar.h b/DSView/pv/toolbars/trigbar.h index 53faf1d3..6c2048b7 100644 --- a/DSView/pv/toolbars/trigbar.h +++ b/DSView/pv/toolbars/trigbar.h @@ -57,6 +57,8 @@ public slots: void measure_clicked(); void search_clicked(); + void update_trig_btn(bool checked); + void on_actionFft_triggered(); private: diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index d9726117..e026b33e 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -53,7 +53,7 @@ const float AnalogSignal::EnvelopeThreshold = 256.0f; AnalogSignal::AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe) : + sr_channel *probe) : Signal(dev_inst, probe), _data(data) { diff --git a/DSView/pv/view/analogsignal.h b/DSView/pv/view/analogsignal.h index b8810fdb..12523de7 100644 --- a/DSView/pv/view/analogsignal.h +++ b/DSView/pv/view/analogsignal.h @@ -48,7 +48,7 @@ private: public: AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe); + sr_channel *probe); virtual ~AnalogSignal(); diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index 8d20ddca..2cce5a7e 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -256,8 +256,13 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) const uint64_t start_sample = (uint64_t)max((left + pixels_offset) * samples_per_pixel, 0.0); - const uint64_t end_sample = (uint64_t)max((right + pixels_offset) * + uint64_t end_sample = (uint64_t)max((right + pixels_offset) * samples_per_pixel, 0.0); + const uint64_t samples_decoded = _decoder_stack->samples_decoded(); + if (samples_decoded < start_sample) + return; + if (samples_decoded < end_sample) + end_sample = samples_decoded; const int annotation_height = _view->get_signalHeight(); @@ -281,18 +286,13 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) BOOST_FOREACH(boost::shared_ptr dec, _decoder_stack->stack()) { if (dec->shown()) { - const std::map& rows(_decoder_stack->get_rows_gshow()); + const std::map rows = _decoder_stack->get_rows_gshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if ((*i).first.decoder() == dec->decoder() && _decoder_stack->has_annotations((*i).first)) { if ((*i).second) { const Row &row = (*i).first; - size_t base_colour = 0x13579BDF; - boost::hash_combine(base_colour, this); - boost::hash_combine(base_colour, row.decoder()); - boost::hash_combine(base_colour, row.row()); - base_colour >>= 16; const uint64_t min_annotation = _decoder_stack->get_min_annotation(row); @@ -310,10 +310,10 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) draw_annotation(a, p, get_text_colour(), annotation_height, left, right, samples_per_pixel, pixels_offset, y, - base_colour, min_annWidth); + 0, min_annWidth); } } else if (max_annWidth != 0){ - draw_nodetail(p, annotation_height, left, right, y, base_colour); + draw_nodetail(p, annotation_height, left, right, y, 0); } if (max_annWidth != 0) { y += annotation_height; @@ -397,6 +397,9 @@ bool DecodeTrace::create_popup() } } + if (_popup_form) + QWidget().setLayout(_popup_form); + delete _popup; _popup = NULL; _popup_form = NULL; @@ -522,7 +525,7 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, const double end = min(a.end_sample() / samples_per_pixel - pixels_offset, (double)right); - const size_t colour = (base_colour + a.format()) % countof(Colours); + const size_t colour = ((base_colour + a.type()) % MaxAnnType) % countof(Colours); const QColor &fill = Colours[colour]; const QColor &outline = OutlineColours[colour]; @@ -699,11 +702,11 @@ void DecodeTrace::create_decoder_form( assert(decoder); pv::widgets::DecoderGroupBox *const group = - new pv::widgets::DecoderGroupBox(decoder_stack, dec); + new pv::widgets::DecoderGroupBox(decoder_stack, dec, parent); connect(group, SIGNAL(del_stack(boost::shared_ptr&)), this, SLOT(on_del_stack(boost::shared_ptr&))); - QFormLayout *const decoder_form = new QFormLayout; + QFormLayout *const decoder_form = new QFormLayout(); group->add_layout(decoder_form); // Add the mandatory channels @@ -840,6 +843,8 @@ void DecodeTrace::on_new_decode_data() if (_view && _view->session().get_capture_state() == SigSession::Stopped) _view->data_updated(); + if (_totalHeight/_view->get_signalHeight() != rows_size()) + _view->signals_changed(); } int DecodeTrace::get_progress() const @@ -895,7 +900,7 @@ int DecodeTrace::rows_size() BOOST_FOREACH(boost::shared_ptr dec, _decoder_stack->stack()) { if (dec->shown()) { - const std::map& rows(_decoder_stack->get_rows_gshow()); + const std::map rows = _decoder_stack->get_rows_gshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if ((*i).first.decoder() == dec->decoder() && diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index 12269b8c..ff65a1a8 100644 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -91,6 +91,7 @@ private: static const int DefaultFontSize = 8; static const int ControlRectWidth = 5; + static const int MaxAnnType = 100; static const QString RegionStart; static const QString RegionEnd; diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index b782a11c..b9283f2b 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -115,8 +115,8 @@ void DevMode::on_mode_change() dev_inst->set_config(NULL, NULL, SR_CONF_DEVICE_MODE, g_variant_new_int16((*i).second->mode)); - button->setChecked(true); mode_changed(); + button->setChecked(true); } } else { (*i).first->setChecked(false); diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 7ee1befd..24916a87 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -112,7 +112,7 @@ const int DsoSignal::RightMargin = 30; DsoSignal::DsoSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe): + sr_channel *probe): Signal(dev_inst, probe), _data(data), _scale(0), diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h index 67c67da7..69ebcd4b 100644 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -100,7 +100,7 @@ private: public: DsoSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe); + sr_channel *probe); virtual ~DsoSignal(); diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index cff3801c..e5d543b8 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -53,7 +53,7 @@ const int LogicSignal::StateRound = 5; LogicSignal::LogicSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe) : + sr_channel *probe) : Signal(dev_inst, probe), _data(data), _trig(NONTRIG) @@ -64,7 +64,7 @@ LogicSignal::LogicSignal(boost::shared_ptr dev_inst, LogicSignal::LogicSignal(boost::shared_ptr s, boost::shared_ptr data, - const sr_channel * const probe) : + sr_channel *probe) : Signal(*s.get(), probe), _data(data), _trig(s->get_trig()) diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index ac64b1b8..32f00683 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -65,11 +65,11 @@ private: public: LogicSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, - const sr_channel * const probe); + sr_channel *probe); LogicSignal(boost::shared_ptr s, boost::shared_ptr data, - const sr_channel * const probe); + sr_channel *probe); virtual ~LogicSignal(); diff --git a/DSView/pv/view/mathtrace.cpp b/DSView/pv/view/mathtrace.cpp index 0abafb18..b19ea97e 100644 --- a/DSView/pv/view/mathtrace.cpp +++ b/DSView/pv/view/mathtrace.cpp @@ -359,8 +359,8 @@ void MathTrace::paint_fore(QPainter &p, int left, int right) double blank_right = width; // horizontal ruler - const double NyFreq = _session.cur_samplerate() / (2.0 * _math_stack->get_sample_interval()); - const double deltaFreq = _session.cur_samplerate() * 1.0 / + const double NyFreq = _session.get_device()->get_sample_rate() / (2.0 * _math_stack->get_sample_interval()); + const double deltaFreq = _session.get_device()->get_sample_rate() * 1.0 / (_math_stack->get_sample_num() * _math_stack->get_sample_interval()); const double FreqRange = NyFreq * _scale; const double FreqOffset = NyFreq * _offset; diff --git a/DSView/pv/view/signal.cpp b/DSView/pv/view/signal.cpp index 9abd0ce9..40c66101 100644 --- a/DSView/pv/view/signal.cpp +++ b/DSView/pv/view/signal.cpp @@ -35,14 +35,14 @@ namespace pv { namespace view { Signal::Signal(boost::shared_ptr dev_inst, - const sr_channel *const probe) : + sr_channel *probe) : Trace(probe->name, probe->index, probe->type), _dev_inst(dev_inst), _probe(probe) { } -Signal::Signal(const Signal &s, const sr_channel * const probe) : +Signal::Signal(const Signal &s, sr_channel *probe) : Trace((const Trace &)s), _dev_inst(s._dev_inst), _probe(probe) @@ -54,6 +54,13 @@ bool Signal::enabled() const return _probe->enabled; } +void Signal::set_name(QString name) +{ + Trace::set_name(name); + g_free(_probe->name); + _probe->name = g_strdup(name.toLocal8Bit().data()); +} + void Signal::paint_axis(QPainter &p, int y, int left, int right) { p.setPen(SignalAxisPen); diff --git a/DSView/pv/view/signal.h b/DSView/pv/view/signal.h index 01fabb25..4a18ad24 100644 --- a/DSView/pv/view/signal.h +++ b/DSView/pv/view/signal.h @@ -57,12 +57,12 @@ private: protected: Signal(boost::shared_ptr dev_inst, - const sr_channel * const probe); + sr_channel * const probe); /** * Copy constructor */ - Signal(const Signal &s, const sr_channel * const probe); + Signal(const Signal &s, sr_channel * const probe); public: virtual boost::shared_ptr data() const = 0; @@ -74,6 +74,11 @@ public: */ bool enabled() const; + /** + * Sets the name of the signal. + */ + void set_name(QString name); + /** * Paints the signal label into a QGLWidget. * @param p the QPainter to paint into. @@ -97,7 +102,7 @@ protected: protected: boost::shared_ptr _dev_inst; - const sr_channel *const _probe; + sr_channel *const _probe; }; } // namespace view diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index c3e2193d..a85eb321 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -149,7 +149,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget connect(&_session, SIGNAL(device_setted()), _devmode, SLOT(set_device())); connect(&_session, SIGNAL(signals_changed()), - this, SLOT(signals_changed())); + this, SLOT(signals_changed()), Qt::DirectConnection); connect(&_session, SIGNAL(data_updated()), this, SLOT(data_updated())); connect(&_session, SIGNAL(receive_trigger(quint64)), @@ -157,8 +157,10 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget connect(&_session, SIGNAL(show_region(uint64_t,uint64_t)), this, SLOT(show_region(uint64_t, uint64_t))); +// connect(_devmode, SIGNAL(mode_changed()), +// this, SIGNAL(mode_changed())); connect(_devmode, SIGNAL(mode_changed()), - this, SIGNAL(mode_changed())); + parent, SLOT(update_device_list()), Qt::DirectConnection); connect(_header, SIGNAL(traces_moved()), this, SLOT(on_traces_moved())); @@ -431,7 +433,7 @@ void View::set_trig_pos(quint64 trig_pos) } _trigger_time = QDateTime::currentDateTime(); - const int64_t secs = time - _session.cur_sampletime(); + const int64_t secs = time - _session.get_device()->get_sample_time(); _trigger_time = _trigger_time.addSecs(secs); _ruler->update(); @@ -498,7 +500,7 @@ void View::get_scroll_layout(double &length, double &offset) const if (data_set.empty()) return; - length = _session.cur_sampletime() / _scale; + length = _session.get_device()->get_sample_time() / _scale; offset = _offset / _scale; } @@ -645,6 +647,7 @@ void View::signals_changed() header_updated(); normalize_layout(); + update_scale_offset(); data_updated(); } @@ -972,7 +975,7 @@ double View::get_min_offset() double View::get_max_offset() { - return _session.cur_sampletime() + return _session.get_device()->get_sample_time() - _scale * (get_view_width() * MaxViewRate); } diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 07f0dee8..199d35cb 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -179,6 +179,8 @@ void Viewport::paintEvent(QPaintEvent *event) void Viewport::paintSignals(QPainter &p) { + if (_view.session().get_data_lock()) + return; const vector< boost::shared_ptr > traces(_view.get_traces(_type)); if (_view.scale() != _curScale || _view.offset() != _curOffset || @@ -791,6 +793,8 @@ void Viewport::clear_measure() void Viewport::measure() { + if (_view.session().get_data_lock()) + return; _measure_type = NO_MEASURE; if (_type == TIME_VIEW) { const uint64_t sample_rate = _view.session().cur_samplerate(); diff --git a/DSView/pv/widgets/decodergroupbox.cpp b/DSView/pv/widgets/decodergroupbox.cpp index 4be51822..ab028284 100644 --- a/DSView/pv/widgets/decodergroupbox.cpp +++ b/DSView/pv/widgets/decodergroupbox.cpp @@ -46,12 +46,12 @@ DecoderGroupBox::DecoderGroupBox(boost::shared_ptr &decoder_ QWidget(parent), _decoder_stack(decoder_stack), _dec(dec), - _layout(new QGridLayout) + _layout(new QGridLayout(this)) { _layout->setContentsMargins(0, 0, 0, 0); setLayout(_layout); - _layout->addWidget(new QLabel(QString("

%1

").arg(_dec->decoder()->name)), + _layout->addWidget(new QLabel(QString("

%1

").arg(_dec->decoder()->name), this), 0, 0); _layout->setColumnStretch(0, 1); @@ -82,7 +82,7 @@ DecoderGroupBox::DecoderGroupBox(boost::shared_ptr &decoder_ // add row show/hide int index = 0; - const std::map& rows(_decoder_stack->get_rows_gshow()); + const std::map rows = _decoder_stack->get_rows_gshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if ((*i).first.decoder() == _dec->decoder()) { @@ -99,6 +99,10 @@ DecoderGroupBox::DecoderGroupBox(boost::shared_ptr &decoder_ } } +DecoderGroupBox::~DecoderGroupBox() +{ +} + void DecoderGroupBox::add_layout(QLayout *layout) { assert(layout); @@ -122,14 +126,14 @@ void DecoderGroupBox::tog_icon() } } } else { - std::map& rows(_decoder_stack->get_rows_gshow()); + std::map rows = _decoder_stack->get_rows_gshow(); for (std::map::const_iterator i = rows.begin(); i != rows.end(); i++) { if (index-- == 0) { _decoder_stack->set_rows_gshow((*i).first, !(*i).second); //rows[(*i).first] = !(*i).second; - sc->setIcon(QIcon(rows[(*i).first] ? ":/icons/shown.png" : - ":/icons/hidden.png")); + sc->setIcon(QIcon(rows[(*i).first] ? ":/icons/hidden.png" : + ":/icons/shown.png")); break; } } diff --git a/DSView/pv/widgets/decodergroupbox.h b/DSView/pv/widgets/decodergroupbox.h index d780241b..b83eef1c 100644 --- a/DSView/pv/widgets/decodergroupbox.h +++ b/DSView/pv/widgets/decodergroupbox.h @@ -46,7 +46,7 @@ public: DecoderGroupBox(boost::shared_ptr &decoder_stack, boost::shared_ptr &dec, QWidget *parent = NULL); - + ~DecoderGroupBox(); void add_layout(QLayout *layout); signals: diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index ef4f8dd8..30c0549d 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -436,6 +436,7 @@ static int fpga_config(struct libusb_device_handle *hdl, const char *filename) offset += chunksize; } fclose(fw); + g_free(buf); if (result == SR_OK) sr_info("FPGA configure done"); @@ -861,6 +862,7 @@ static GSList *scan(GSList *options) else sr_err("Firmware upload failed for " "device %d.", devcnt); + g_free(firmware); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(devlist[i]), 0xff, NULL); @@ -2109,6 +2111,7 @@ static int dev_open(struct sr_dev_inst *sdi) if (ret != SR_OK) { sr_err("Configure FPGA failed!"); } + g_free(fpga_bit); } if (sdi->mode == DSO) diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index 1b3f3c4e..6fd59f00 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -233,6 +233,7 @@ struct DSL_context { gboolean data_lock; int num_samples; + uint64_t sent_samples; int submitted_transfers; int empty_transfer_count; diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index b08feda5..e99f92ce 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -1013,142 +1013,6 @@ static uint64_t dso_cmd_gen(struct sr_dev_inst *sdi, struct sr_channel* ch, int return cmd; } -static int dev_open(struct sr_dev_inst *sdi) -{ - struct sr_usb_dev_inst *usb; - struct DSL_context *devc; - GSList *l; - int ret; - int64_t timediff_us, timediff_ms; - - devc = sdi->priv; - usb = sdi->conn; - - /* - * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS - * milliseconds for the FX2 to renumerate. - */ - ret = SR_ERR; - if (devc->fw_updated > 0) { - sr_info("Waiting for device to reset."); - /* Takes >= 300ms for the FX2 to be gone from the USB bus. */ - g_usleep(300 * 1000); - timediff_ms = 0; - while (timediff_ms < MAX_RENUM_DELAY_MS) { - if ((ret = DSLogic_dev_open(sdi)) == SR_OK) - break; - g_usleep(100 * 1000); - - timediff_us = g_get_monotonic_time() - devc->fw_updated; - timediff_ms = timediff_us / 1000; - sr_spew("Waited %" PRIi64 "ms.", timediff_ms); - } - if (ret != SR_OK) { - sr_err("Device failed to renumerate."); - return SR_ERR; - } - sr_info("Device came back after %" PRIi64 "ms.", timediff_ms); - } else { - sr_info("Firmware upload was not needed."); - ret = DSLogic_dev_open(sdi); - } - - if (ret != SR_OK) { - sr_err("Unable to open device."); - return SR_ERR; - } - - ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); - if (ret != 0) { - switch(ret) { - case LIBUSB_ERROR_BUSY: - sr_err("Unable to claim USB interface. Another " - "program or driver has already claimed it."); - break; - case LIBUSB_ERROR_NO_DEVICE: - sr_err("Device has been disconnected."); - break; - default: - sr_err("Unable to claim interface: %s.", - libusb_error_name(ret)); - break; - } - - return SR_ERR; - } - - if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { - sr_err("Send FPGA configure command failed!"); - } else { - /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ - g_usleep(10 * 1000); - char *fpga_bit; - if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { - sr_err("fpag_bit path malloc error!"); - return SR_ERR_MALLOC; - } - strcpy(fpga_bit, config_path); - switch(devc->th_level) { - case SR_TH_3V3: - strcat(fpga_bit, devc->profile->fpga_bit33);; - break; - case SR_TH_5V0: - strcat(fpga_bit, devc->profile->fpga_bit50);; - break; - default: - return SR_ERR; - } - ret = fpga_config(usb->devhdl, fpga_bit); - if (ret != SR_OK) { - sr_err("Configure FPGA failed!"); - } - g_free(fpga_bit); - } - - ret = command_wr_reg(usb->devhdl, (uint8_t)(devc->vth/5.0*255), VTH_ADDR); - if (ret == SR_OK) - sr_dbg("%s: setting threshold voltage to %d", - __func__, devc->vth); - else - sr_dbg("%s: setting threshold voltage to %d failed", - __func__, devc->vth); - - return SR_OK; -} - -static int dev_close(struct sr_dev_inst *sdi) -{ - struct sr_usb_dev_inst *usb; - - usb = sdi->conn; - if (usb->devhdl == NULL) - return SR_ERR; - - sr_info("DSLogic: Closing device %d on %d.%d interface %d.", - sdi->index, usb->bus, usb->address, USB_INTERFACE); - libusb_release_interface(usb->devhdl, USB_INTERFACE); - libusb_close(usb->devhdl); - usb->devhdl = NULL; - sdi->status = SR_ST_INACTIVE; - - return SR_OK; -} - -static int cleanup(void) -{ - int ret; - struct drv_context *drvc; - - if (!(drvc = di->priv)) - return SR_OK; - - ret = dev_clear(); - - g_free(drvc); - di->priv = NULL; - - return ret; -} static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel *ch, @@ -1904,13 +1768,176 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_HEIGHT: *data = g_variant_new_strv(maxHeights, ARRAY_SIZE(maxHeights)); break; - default: + default: return SR_ERR_NA; - } + } return SR_OK; } +static int dev_open(struct sr_dev_inst *sdi) +{ + struct sr_usb_dev_inst *usb; + struct DSL_context *devc; + GSList *l; + int ret; + int64_t timediff_us, timediff_ms; + + devc = sdi->priv; + usb = sdi->conn; + + /* + * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS + * milliseconds for the FX2 to renumerate. + */ + ret = SR_ERR; + if (devc->fw_updated > 0) { + sr_info("Waiting for device to reset."); + /* Takes >= 300ms for the FX2 to be gone from the USB bus. */ + g_usleep(300 * 1000); + timediff_ms = 0; + while (timediff_ms < MAX_RENUM_DELAY_MS) { + if ((ret = DSLogic_dev_open(sdi)) == SR_OK) + break; + g_usleep(100 * 1000); + + timediff_us = g_get_monotonic_time() - devc->fw_updated; + timediff_ms = timediff_us / 1000; + sr_spew("Waited %" PRIi64 "ms.", timediff_ms); + } + if (ret != SR_OK) { + sr_err("Device failed to renumerate."); + return SR_ERR; + } + sr_info("Device came back after %" PRIi64 "ms.", timediff_ms); + } else { + sr_info("Firmware upload was not needed."); + ret = DSLogic_dev_open(sdi); + } + + if (ret != SR_OK) { + sr_err("Unable to open device."); + return SR_ERR; + } + + ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); + if (ret != 0) { + switch(ret) { + case LIBUSB_ERROR_BUSY: + sr_err("Unable to claim USB interface. Another " + "program or driver has already claimed it."); + break; + case LIBUSB_ERROR_NO_DEVICE: + sr_err("Device has been disconnected."); + break; + default: + sr_err("Unable to claim interface: %s.", + libusb_error_name(ret)); + break; + } + + return SR_ERR; + } + + if (devc->fw_updated > 0) { + if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { + sr_err("Send FPGA configure command failed!"); + } else { + /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ + g_usleep(10 * 1000); + char *fpga_bit; + if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { + sr_err("fpag_bit path malloc error!"); + return SR_ERR_MALLOC; + } + strcpy(fpga_bit, config_path); + switch(devc->th_level) { + case SR_TH_3V3: + strcat(fpga_bit, devc->profile->fpga_bit33);; + break; + case SR_TH_5V0: + strcat(fpga_bit, devc->profile->fpga_bit50);; + break; + default: + return SR_ERR; + } + ret = fpga_config(usb->devhdl, fpga_bit); + if (ret != SR_OK) { + sr_err("Configure FPGA failed!"); + } + g_free(fpga_bit); + } + } + + ret = command_wr_reg(usb->devhdl, (uint8_t)(devc->vth/5.0*255), VTH_ADDR); + if (ret == SR_OK) + sr_dbg("%s: setting threshold voltage to %d", + __func__, devc->vth); + else + sr_dbg("%s: setting threshold voltage to %d failed", + __func__, devc->vth); + + #ifdef _WIN32 + if (pipe(devc->pipe_fds)) { + /* TODO: Better error message. */ + sr_err("%s: pipe() failed", __func__); + return SR_ERR; + } + devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]); + g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL); + /* Set channel encoding to binary (default is UTF-8). */ + g_io_channel_set_encoding(devc->channel, NULL, NULL); + /* Make channels to unbuffered. */ + g_io_channel_set_buffered(devc->channel, FALSE); + #endif + + return SR_OK; +} + +static int dev_close(struct sr_dev_inst *sdi) +{ + struct sr_usb_dev_inst *usb; + struct DSL_context *devc; + + usb = sdi->conn; + if (usb->devhdl == NULL) + return SR_ERR; + devc = sdi->priv; + + #ifdef _WIN32 + if (sdi->status == SR_ST_ACTIVE && devc->channel) { + g_io_channel_shutdown(devc->channel, FALSE, NULL); + g_io_channel_unref(devc->channel); + devc->channel = NULL; + } + #endif + + sr_info("DSLogic: Closing device %d on %d.%d interface %d.", + sdi->index, usb->bus, usb->address, USB_INTERFACE); + libusb_release_interface(usb->devhdl, USB_INTERFACE); + libusb_close(usb->devhdl); + usb->devhdl = NULL; + sdi->status = SR_ST_INACTIVE; + + return SR_OK; +} + +static int cleanup(void) +{ + int ret; + struct drv_context *drvc; + + if (!(drvc = di->priv)) + return SR_OK; + + ret = dev_clear(); + + g_free(drvc); + di->priv = NULL; + + return ret; +} + static void abort_acquisition(struct DSL_context *devc) { int i; @@ -2246,12 +2273,13 @@ static void receive_transfer(struct libusb_transfer *transfer) /* send data to session bus */ sr_session_send(devc->cb_data, &packet); + devc->sent_samples += cur_sample_count; } devc->num_samples += cur_sample_count; - if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && - devc->limit_samples && - (unsigned int)devc->num_samples >= devc->actual_samples) { + if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && + devc->limit_samples && + (unsigned int)devc->num_samples >= devc->actual_samples) { //abort_acquisition(devc); free_transfer(transfer); devc->status = DSL_STOP; @@ -2391,6 +2419,8 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) if (devc->num_samples != -1 && (devc->status == DSL_STOP || devc->status == DSL_ERROR)) { + if (devc->sent_samples < devc->actual_samples) + devc->sent_samples = 0; sr_info("%s: Stopping", __func__); abort_acquisition(devc); } @@ -2503,6 +2533,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) //devc->cb_data = cb_data; devc->cb_data = sdi; devc->num_samples = 0; + devc->sent_samples = 0; devc->empty_transfer_count = 0; devc->status = DSL_INIT; devc->num_transfers = 0; diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index e9536f4d..e26036c6 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -48,7 +48,8 @@ /* The size of chunks to send through the session bus. */ /* TODO: Should be configurable. */ -#define BUFSIZE 1024*1024 +#define BUFSIZE 512*1024 +#define DSO_BUFSIZE 10*1024 #define PERIOD 4000 @@ -319,7 +320,7 @@ static GSList *hw_scan(GSList *options) devices = NULL; - sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, DEMONAME, NULL, NULL); + sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_INITIALIZING, DEMONAME, NULL, NULL); if (!sdi) { sr_err("Device instance creation failed."); return NULL; @@ -391,20 +392,39 @@ static GSList *hw_dev_mode_list(const struct sr_dev_inst *sdi) static int hw_dev_open(struct sr_dev_inst *sdi) { - (void)sdi; + //(void)sdi; + struct dev_context *const devc = sdi->priv; - sdi->status = SR_ST_ACTIVE; + sdi->status = SR_ST_ACTIVE; + + if (pipe(devc->pipe_fds)) { + /* TODO: Better error message. */ + sr_err("%s: pipe() failed", __func__); + return SR_ERR; + } + devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]); + g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL); + /* Set channel encoding to binary (default is UTF-8). */ + g_io_channel_set_encoding(devc->channel, NULL, NULL); + /* Make channels to unbuffered. */ + g_io_channel_set_buffered(devc->channel, FALSE); return SR_OK; } static int hw_dev_close(struct sr_dev_inst *sdi) { - (void)sdi; + //(void)sdi; + struct dev_context *const devc = sdi->priv; + if (sdi->status == SR_ST_ACTIVE && devc->channel) { + g_io_channel_shutdown(devc->channel, FALSE, NULL); + g_io_channel_unref(devc->channel); + devc->channel = NULL; + } sdi->status = SR_ST_INACTIVE; - return SR_OK; + return SR_OK; } static int hw_cleanup(void) @@ -484,6 +504,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_COUPLING: *data = g_variant_new_byte(ch->coupling); break; + case SR_CONF_TRIGGER_VALUE: + *data = g_variant_new_byte(ch->trig_value); + break; case SR_CONF_EN_CH: *data = g_variant_new_uint64(ch->enabled); break; @@ -667,6 +690,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting AC COUPLING of channel %d to %d", __func__, ch->index, ch->coupling); ret = SR_OK; + } else if (id == SR_CONF_TRIGGER_VALUE) { + ch->trig_value = g_variant_get_byte(data); + sr_dbg("%s: setting channel %d Trigger Value to %d", + __func__, ch->index, ch->trig_value); + ret = SR_OK; } else { ret = SR_ERR_NA; } @@ -843,7 +871,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) struct sr_datafeed_logic logic; struct sr_datafeed_dso dso; struct sr_datafeed_analog analog; - static uint64_t samples_to_send, expected_samplenum, sending_now; + static uint64_t samples_to_send = 0, expected_samplenum, sending_now; int64_t time, elapsed; static uint16_t last_sample = 0; uint16_t cur_sample; @@ -860,19 +888,22 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) /* Of those, how many do we still have to send? */ //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN; //samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN; - samples_to_send = ceil(elapsed / 1000000.0 * devc->cur_samplerate); + samples_to_send += ceil(elapsed / 1000000.0 * devc->cur_samplerate); if (devc->limit_samples) { - if ((sdi->mode == DSO && !devc->instant) || sdi->mode == ANALOG) + if (sdi->mode == DSO && !devc->instant) samples_to_send = MIN(samples_to_send, devc->limit_samples - devc->pre_index); + else if (sdi->mode == ANALOG) + samples_to_send = MIN(samples_to_send * g_slist_length(sdi->channels), + devc->limit_samples - devc->pre_index); else samples_to_send = MIN(samples_to_send, devc->limit_samples - devc->samples_counter); } - while (samples_to_send > 0) { - sending_now = MIN(samples_to_send, BUFSIZE); + if (samples_to_send > 0 && !devc->stop) { + sending_now = MIN(samples_to_send, (sdi->mode == DSO ) ? DSO_BUFSIZE : BUFSIZE); samples_generator(devc->buf, sending_now, sdi, devc); if (devc->trigger_stage != 0) { @@ -959,8 +990,6 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) devc->mstatus.captured_cnt1 = devc->samples_counter >> 8; devc->mstatus.captured_cnt2 = devc->samples_counter >> 16; devc->mstatus.captured_cnt3 = devc->samples_counter >> 32; - } else { - break; } } @@ -1015,30 +1044,15 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, * They are kept here because it provides a convenient way of setting * up a timeout-based polling mechanism. */ - if (pipe(devc->pipe_fds)) { - /* TODO: Better error message. */ - sr_err("%s: pipe() failed", __func__); - return SR_ERR; - } - - devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]); - - g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL); - - /* Set channel encoding to binary (default is UTF-8). */ - g_io_channel_set_encoding(devc->channel, NULL, NULL); - - /* Make channels to unbuffered. */ - g_io_channel_set_buffered(devc->channel, FALSE); sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR, - 100, receive_data, sdi); + (sdi->mode == DSO) ? 50 : 10, receive_data, sdi); /* Send header packet to the session bus. */ //std_session_send_df_header(cb_data, LOG_PREFIX); std_session_send_df_header(sdi, LOG_PREFIX); - if (!(devc->buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) { + if (!(devc->buf = g_try_malloc(((sdi->mode == DSO ) ? DSO_BUFSIZE : BUFSIZE)*sizeof(uint16_t)))) { sr_err("buf for receive_data malloc failed."); return FALSE; } @@ -1051,18 +1065,18 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) { - struct dev_context *const devc = sdi->priv; - struct sr_datafeed_packet packet; + (void)cb_data; - (void)cb_data; + struct dev_context *const devc = sdi->priv; + struct sr_datafeed_packet packet; + if (devc->stop) + return SR_OK; sr_dbg("Stopping aquisition."); devc->stop = TRUE; + sr_session_source_remove_channel(devc->channel); - g_io_channel_shutdown(devc->channel, FALSE, NULL); - g_io_channel_unref(devc->channel); - devc->channel = NULL; g_free(devc->buf); diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 12cf5eaa..319a35f5 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -1046,7 +1046,7 @@ struct sr_session { * an async fashion. We need to make sure the session is stopped from * within the session thread itself. */ -// GMutex stop_mutex; + GMutex stop_mutex; gboolean abort_session; }; diff --git a/libsigrok4DSL/session.c b/libsigrok4DSL/session.c index 7fb110d9..87746adb 100644 --- a/libsigrok4DSL/session.c +++ b/libsigrok4DSL/session.c @@ -86,7 +86,7 @@ SR_API struct sr_session *sr_session_new(void) session->source_timeout = -1; session->running = FALSE; session->abort_session = FALSE; -// g_mutex_init(&session->stop_mutex); + g_mutex_init(&session->stop_mutex); return session; } @@ -121,7 +121,7 @@ SR_API int sr_session_destroy(void) /* TODO: Error checks needed? */ -// g_mutex_clear(&session->stop_mutex); + g_mutex_clear(&session->stop_mutex); g_free(session); session = NULL; @@ -325,13 +325,13 @@ static int sr_session_iteration(gboolean block) * we check the flag after processing every source, not * just once per main event loop. */ - //g_mutex_lock(&session->stop_mutex); + g_mutex_lock(&session->stop_mutex); if (session->abort_session) { sr_session_stop_sync(); /* But once is enough. */ session->abort_session = FALSE; } - //g_mutex_unlock(&session->stop_mutex); + g_mutex_unlock(&session->stop_mutex); } return SR_OK; @@ -414,6 +414,10 @@ SR_API int sr_session_run(void) sr_session_iteration(TRUE); } + g_mutex_lock(&session->stop_mutex); + session->running = FALSE; + session->abort_session = FALSE; + g_mutex_unlock(&session->stop_mutex); return SR_OK; } @@ -447,7 +451,6 @@ SR_PRIV int sr_session_stop_sync(void) sdi->driver->dev_acquisition_stop(sdi, NULL); } } - session->running = FALSE; return SR_OK; } @@ -472,9 +475,10 @@ SR_API int sr_session_stop(void) return SR_ERR_BUG; } -// g_mutex_lock(&session->stop_mutex); - session->abort_session = TRUE; -// g_mutex_unlock(&session->stop_mutex); + g_mutex_lock(&session->stop_mutex); + if (session->running) + session->abort_session = TRUE; + g_mutex_unlock(&session->stop_mutex); return SR_OK; } @@ -722,29 +726,37 @@ static int _sr_session_source_remove(gintptr poll_object) if (old == session->num_sources) return SR_OK; - session->num_sources -= 1; + session->num_sources -= 1; - if (old != session->num_sources) { - memmove(&session->pollfds[old], &session->pollfds[old+1], - (session->num_sources - old) * sizeof(GPollFD)); - memmove(&session->sources[old], &session->sources[old+1], - (session->num_sources - old) * sizeof(struct source)); - } + if (session->num_sources == 0) { + session->source_timeout = -1; + g_free(session->pollfds); + g_free(session->sources); + session->pollfds = NULL; + session->sources = NULL; + } else { + if (old != session->num_sources) { + memmove(&session->pollfds[old], &session->pollfds[old+1], + (session->num_sources - old) * sizeof(GPollFD)); + memmove(&session->sources[old], &session->sources[old+1], + (session->num_sources - old) * sizeof(struct source)); + } - new_pollfds = g_try_realloc(session->pollfds, sizeof(GPollFD) * session->num_sources); - if (!new_pollfds && session->num_sources > 0) { - sr_err("%s: new_pollfds malloc failed", __func__); - return SR_ERR_MALLOC; - } + new_pollfds = g_try_realloc(session->pollfds, sizeof(GPollFD) * session->num_sources); + if (!new_pollfds && session->num_sources > 0) { + sr_err("%s: new_pollfds malloc failed", __func__); + return SR_ERR_MALLOC; + } - new_sources = g_try_realloc(session->sources, sizeof(struct source) * session->num_sources); - if (!new_sources && session->num_sources > 0) { - sr_err("%s: new_sources malloc failed", __func__); - return SR_ERR_MALLOC; - } + new_sources = g_try_realloc(session->sources, sizeof(struct source) * session->num_sources); + if (!new_sources && session->num_sources > 0) { + sr_err("%s: new_sources malloc failed", __func__); + return SR_ERR_MALLOC; + } - session->pollfds = new_pollfds; - session->sources = new_sources; + session->pollfds = new_pollfds; + session->sources = new_sources; + } return SR_OK; } diff --git a/libsigrok4DSL/trigger.c b/libsigrok4DSL/trigger.c index 6baf5d7e..0f572640 100644 --- a/libsigrok4DSL/trigger.c +++ b/libsigrok4DSL/trigger.c @@ -34,7 +34,7 @@ * @{ */ -struct ds_trigger *trigger; +struct ds_trigger *trigger = NULL; /** * recovery trigger to initial status. @@ -77,7 +77,7 @@ SR_API int ds_trigger_destroy(void) { if (trigger) g_free(trigger); - + trigger = NULL; return SR_OK; } @@ -214,7 +214,10 @@ SR_API int ds_trigger_set_en(uint16_t enable) */ SR_API uint16_t ds_trigger_get_en() { - return trigger->trigger_en; + if (trigger == NULL) + return 0; + else + return trigger->trigger_en; } /**