Commit b1446b78 authored by DreamSourceLab's avatar DreamSourceLab

Improve memory alloc and free for each capture

parent 57188cf7
......@@ -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{
......
......@@ -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;
}
DSView/icons/wait.gif

9.83 KB | W: | H:

DSView/icons/wait.gif

9.25 KB | W: | H:

DSView/icons/wait.gif
DSView/icons/wait.gif
DSView/icons/wait.gif
DSView/icons/wait.gif
  • 2-up
  • Swipe
  • Onion skin
......@@ -53,6 +53,12 @@ void Analog::clear()
BOOST_FOREACH(const boost::shared_ptr<AnalogSnapshot> s, _snapshots)
s->clear();
}
void Analog::init()
{
//_snapshots.clear();
BOOST_FOREACH(const boost::shared_ptr<AnalogSnapshot> s, _snapshots)
s->init();
}
} // namespace data
} // namespace pv
......@@ -46,6 +46,7 @@ public:
get_snapshots();
void clear();
void init();
private:
std::deque< boost::shared_ptr<AnalogSnapshot> > _snapshots;
......
......@@ -54,15 +54,41 @@ AnalogSnapshot::AnalogSnapshot() :
AnalogSnapshot::~AnalogSnapshot()
{
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
BOOST_FOREACH(Envelope &e, _envelope_levels[0])
free(e.samples);
free_envelop();
}
void AnalogSnapshot::clear()
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<boost::recursive_mutex> 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()
{
boost::lock_guard<boost::recursive_mutex> 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<boost::recursive_mutex> 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<boost::recursive_mutex> lock(_mutex);
boost::lock_guard<boost::recursive_mutex> 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<boost::recursive_mutex> 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<boost::recursive_mutex> 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)
{
......
......@@ -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:
......
......@@ -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<QString>& Annotation::annotations() const
{
return _annotations;
......
......@@ -42,12 +42,14 @@ public:
uint64_t start_sample() const;
uint64_t end_sample() const;
int format() const;
int type() const;
const std::vector<QString>& annotations() const;
private:
uint64_t _start_sample;
uint64_t _end_sample;
int _format;
int _type;
std::vector<QString> _annotations;
};
......
......@@ -35,7 +35,6 @@ class RowData
public:
RowData();
~RowData();
public:
uint64_t get_max_sample() const;
......
......@@ -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<mutex> decode_lock(_output_mutex);
lock_guard<boost::recursive_mutex> 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<mutex> lock(_output_mutex);
//lock_guard<mutex> lock(_output_mutex);
std::map<const Row, decode::RowData>::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<mutex> lock(_output_mutex);
//lock_guard<mutex> lock(_output_mutex);
std::map<const Row, decode::RowData>::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<mutex> lock(_output_mutex);
//lock_guard<mutex> lock(_output_mutex);
std::map<const Row, decode::RowData>::const_iterator iter =
_rows.find(row);
......@@ -232,14 +232,24 @@ uint64_t DecoderStack::get_min_annotation(const Row &row)
return 0;
}
std::map<const decode::Row, bool>& DecoderStack::get_rows_gshow()
std::map<const decode::Row, bool> DecoderStack::get_rows_gshow()
{
return _rows_gshow;
std::map<const decode::Row, bool> rows_gshow;
for (std::map<const decode::Row, bool>::const_iterator i = _rows_gshow.begin();
i != _rows_gshow.end(); i++) {
rows_gshow[(*i).first] = (*i).second;
}
return rows_gshow;
}
std::map<const decode::Row, bool>& DecoderStack::get_rows_lshow()
std::map<const decode::Row, bool> DecoderStack::get_rows_lshow()
{
return _rows_lshow;
std::map<const decode::Row, bool> rows_lshow;
for (std::map<const decode::Row, bool>::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<mutex> lock(_output_mutex);
//lock_guard<mutex> lock(_output_mutex);
std::map<const Row, decode::RowData>::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<boost::recursive_mutex> lock(_output_mutex);
uint64_t max_annotation_size = 0;
int row = 0;
for (map<const Row, RowData>::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<mutex> lock(_output_mutex);
int row = 0;
for (map<const Row, RowData>::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<mutex> lock(_output_mutex);
int index = 0;
for (map<const Row, RowData>::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<mutex> lock(_output_mutex);
//lock_guard<mutex> lock(_output_mutex);
return _error_message;
}
void DecoderStack::clear()
{
//lock_guard<boost::recursive_mutex> 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 Row, RowData>::const_iterator i = _rows.begin();
for (map<const Row, RowData>::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<uint64_t> DecoderStack::wait_for_data() const
{
unique_lock<mutex> input_lock(_input_mutex);
//unique_lock<mutex> 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<uint64_t> pos_vector;
......@@ -509,7 +537,7 @@ void DecoderStack::decode_data(
}
{
lock_guard<mutex> lock(_output_mutex);
lock_guard<boost::recursive_mutex> 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<mutex> decode_lock(_global_decode_mutex);
//lock_guard<mutex> decode_lock(_global_decode_mutex);
optional<uint64_t> sample_count;
srd_session *session;
......@@ -545,7 +574,7 @@ void DecoderStack::decode_proc()
// Get the intial sample count
{
unique_lock<mutex> input_lock(_input_mutex);
//unique_lock<mutex> 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<mutex> lock(d->_output_mutex);
//lock_guard<mutex> 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<boost::recursive_mutex> 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<mutex> lock(_output_mutex);
int rows_size = 0;
int row = 0;
for (map<const Row, RowData>::const_iterator i = _rows.begin();
......
......@@ -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<const decode::Row, bool> &get_rows_gshow();
std::map<const decode::Row, bool> &get_rows_lshow();
std::map<const decode::Row, bool> get_rows_gshow();
std::map<const decode::Row, bool> 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<decode::Decoder> > _stack;
boost::shared_ptr<pv::data::LogicSnapshot> _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<const decode::Row, decode::RowData> _rows;
......
......@@ -53,5 +53,12 @@ void Dso::clear()
s->clear();
}
void Dso::init()
{
//_snapshots.clear();
BOOST_FOREACH(const boost::shared_ptr<DsoSnapshot> s, _snapshots)
s->init();
}
} // namespace data
} // namespace pv
......@@ -45,6 +45,7 @@ public:
get_snapshots();
void clear();
void init();
private:
std::deque< boost::shared_ptr<DsoSnapshot> > _snapshots;
......
......@@ -58,15 +58,42 @@ DsoSnapshot::DsoSnapshot() :
DsoSnapshot::~DsoSnapshot()
{
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
BOOST_FOREACH(Envelope &e, _envelope_levels[0])
free(e.samples);
free_envelop();
}
void DsoSnapshot::clear()
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<boost::recursive_mutex> 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()
{
boost::lock_guard<boost::recursive_mutex> 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<boost::recursive_mutex> 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;