Preallocating memory for samples when a capture is started improves performance during the capture, as realloc() is called only once.
logf(EnvelopeScaleFactor);
const uint64_t AnalogSnapshot::EnvelopeDataUnit = 64*1024; // bytes
-AnalogSnapshot::AnalogSnapshot() :
+AnalogSnapshot::AnalogSnapshot(const uint64_t expected_num_samples) :
Snapshot(sizeof(float))
{
+ set_capacity(expected_num_samples);
+
lock_guard<recursive_mutex> lock(_mutex);
memset(_envelope_levels, 0, sizeof(_envelope_levels));
}
static const uint64_t EnvelopeDataUnit;
public:
- AnalogSnapshot();
+ AnalogSnapshot(uint64_t expected_num_samples = 0);
virtual ~AnalogSnapshot();
const float LogicSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor);
const uint64_t LogicSnapshot::MipMapDataUnit = 64*1024; // bytes
-LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic) :
+LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic,
+ const uint64_t expected_num_samples) :
Snapshot(logic.unitsize),
_last_append_sample(0)
{
+ set_capacity(expected_num_samples);
+
lock_guard<recursive_mutex> lock(_mutex);
memset(_mip_map, 0, sizeof(_mip_map));
append_payload(logic);
typedef std::pair<int64_t, bool> EdgePair;
public:
- LogicSnapshot(const sr_datafeed_logic &logic);
+ LogicSnapshot(const sr_datafeed_logic &logic,
+ uint64_t expected_num_samples = 0);
virtual ~LogicSnapshot();
Snapshot::Snapshot(int unit_size) :
_data(NULL),
_sample_count(0),
+ _capacity(0),
_unit_size(unit_size)
{
lock_guard<recursive_mutex> lock(_mutex);
return _unit_size;
}
+void Snapshot::set_capacity(const uint64_t new_capacity)
+{
+ lock_guard<recursive_mutex> lock(_mutex);
+
+ assert(_capacity >= _sample_count);
+ if (new_capacity > _capacity) {
+ _capacity = new_capacity;
+ _data = realloc(_data, (new_capacity * _unit_size) + sizeof(uint64_t));
+ }
+}
+
+uint64_t Snapshot::capacity() const
+{
+ lock_guard<recursive_mutex> lock(_mutex);
+ return _capacity;
+}
+
void Snapshot::append_data(void *data, uint64_t samples)
{
lock_guard<recursive_mutex> lock(_mutex);
- _data = realloc(_data, (_sample_count + samples) * _unit_size +
- sizeof(uint64_t));
+
+ assert(_capacity >= _sample_count);
+
+ // Ensure there's enough capacity to copy.
+ const uint64_t free_space = _capacity - _sample_count;
+ if (free_space < samples) {
+ set_capacity(_sample_count + samples);
+ }
+
memcpy((uint8_t*)_data + _sample_count * _unit_size,
data, samples * _unit_size);
_sample_count += samples;
int unit_size() const;
+ /**
+ * @brief Increase the capacity of the snapshot.
+ *
+ * Increasing the capacity allows samples to be appended without needing
+ * to reallocate memory.
+ *
+ * For the best efficiency @c set_capacity() should be called once before
+ * @c append_data() is called to set up the snapshot with the expected number
+ * of samples that will be appended in total.
+ *
+ * @note The capacity will automatically be increased when @c append_data()
+ * is called if there is not enough capacity in the buffer to store the samples.
+ *
+ * @param[in] new_capacity The new capacity of the snapshot. If this value is
+ * smaller or equal than the current capacity then the method has no effect.
+ */
+ void set_capacity(uint64_t new_capacity);
+
+ /**
+ * @brief Get the current capacity of the snapshot.
+ *
+ * The capacity can be increased by calling @c set_capacity().
+ *
+ * @return The current capacity of the snapshot.
+ */
+ uint64_t capacity() const;
+
protected:
void append_data(void *data, uint64_t samples);
mutable boost::recursive_mutex _mutex;
void *_data;
uint64_t _sample_count;
+ uint64_t _capacity;
int _unit_size;
};
assert(0);
}
+uint64_t DevInst::get_sample_limit()
+{
+ uint64_t sample_limit;
+ GVariant* gvar = get_config(NULL, SR_CONF_LIMIT_SAMPLES);
+ if (gvar != NULL) {
+ sample_limit = g_variant_get_uint64(gvar);
+ g_variant_unref(gvar);
+ } else {
+ sample_limit = 0U;
+ }
+ return sample_limit;
+}
+
} // pv
#include <glib.h>
+#include <stdint.h>
+
struct sr_dev_inst;
struct sr_probe;
struct sr_probe_group;
void enable_probe(const sr_probe *probe, bool enable = true);
+ /**
+ * @brief Gets the sample limit from the driver.
+ *
+ * @return The returned sample limit from the driver, or 0 if the
+ * sample limit could not be read.
+ */
+ uint64_t get_sample_limit();
+
signals:
void config_changed();
// Create a new data snapshot
_cur_logic_snapshot = shared_ptr<data::LogicSnapshot>(
- new data::LogicSnapshot(logic));
+ new data::LogicSnapshot(logic, _dev_inst->get_sample_limit()));
_logic_data->push_snapshot(_cur_logic_snapshot);
}
else
// Create a snapshot, keep it in the maps of probes
snapshot = shared_ptr<data::AnalogSnapshot>(
- new data::AnalogSnapshot());
+ new data::AnalogSnapshot(_dev_inst->get_sample_limit()));
_cur_analog_snapshots[probe] = snapshot;
// Find the annalog data associated with the probe