Age | Commit message (Collapse) | Author |
|
Introduce the public srd_session_send_eof() routine which is backed by
the internal srd_inst_send_eof() helper. Applications can tell decoders
when the input stream of sample data is exhausted, so that decoders can
optionally "flush" their previously accumulated information when
desired. Previous implementations just kept decoders in blocking .wait()
calls and somehow terminated them at arbitrary times afterwards.
When EOF is sent to the decoder session, then calls to the .wait()
method which typically are done from .decode() or its descendents will
end with an EOFError Python exception. Termination of .decode() with the
EOFError exception is non-fatal for backwards compatibility and to keep
the convenience for current decoder implementations. Decoders can either
catch the exception, or use context managers, or do nothing.
This API extension is motivated by research for bug #1581 and provides
the infrastructure to address bug #292. Decoders need to remain careful,
and should not claim that protocol activities would have completed when
their end condition was not even seen in the capture. Marking incomplete
activities with warnings is the most appropriate reaction.
|
|
|
|
There were a few places where PyLong_FromLong() was used for uint64_t
numbers. Properly use PyLong_FromUnsignedLongLong() there, and also
fix a few additional size/signedness issues while we're here.
Reported (and partial patch provided) by "The Count" on Bugzilla, thanks!
This fixes bug #1499.
|
|
Introduce an "always false" type for .wait() terms. Map invalid counts
of skip conditions (zero or negative numbers) as well as invalid channel
references for level/edge conditions to this type which never matches.
Keep this "always false" term type an internal detail of the common
support code.
This is most robust and least intrusive at the same time, it keeps the
existing API, and simplifies the implementation of Python decoders for
rare edge cases (optional input signals or optional features, handling
of initial samples at the very start of a capture).
This commit passes sample counts internally in a signed data type. This
is essential for proper operation, and the loss of one bit out of 64
shall not be considered a severe limitation.
This fixes bug #1444.
|
|
instance.c:62:2: runtime error: null pointer passed as argument 1, which is declared to never be null
instance.c:858:45: runtime error: shift exponent -1 is negative
instance.c:836:45: runtime error: shift exponent -1 is negative
|
|
We currently use a mix of Py_IncRef/Py_DecRef and Py_XINCREF/Py_XDECREF
or Py_INCREF/Py_DECREF in the code-base. Only use the latter variants
for the time being (for consistency).
|
|
These were reported when compiling with "-fsanitize=address" and running
"PYTHONMALLOC=malloc make check":
=================================================================
==42879==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 317 byte(s) in 6 object(s) allocated from:
#0 0x7f08e4809538 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f08e3f37622 in PyUnicode_New ../Objects/unicodeobject.c:1365
Direct leak of 28 byte(s) in 1 object(s) allocated from:
#0 0x7f08e4809538 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f08e3f7e1a5 in _PyLong_New ../Objects/longobject.c:275
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7f08e4809538 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f08e3f91521 in PyFloat_FromDouble ../Objects/floatobject.c:122
SUMMARY: AddressSanitizer: 369 byte(s) leaked in 8 allocation(s).
session
|
|
This fixes bug #1374.
|
|
|
|
Currently there must be at least one match of inputs/outputs for
decoders that are stacked. If not, we emit an informational warning
(but this is not a hard error for the time being).
|
|
|
|
|
|
|
|
|
|
These functions are only used in type_decoder.c. Move them there and
make them static.
|
|
|
|
A simple NULL check is sufficient here, max_session_id is being
properly handled by srd_init(), srd_exit(), srd_session_new().
This might also have a small performance benefit.
|
|
|
|
instance.c:266:11: warning: declaration of ‘l’ shadows a previous local [-Wshadow]
GSList *l = g_slist_nth(di->decoder->channels, i);
^
instance.c:206:9: note: shadowed declaration is here
GList *l;
^
|
|
instance.c:278:25: warning: The left operand of '!=' is a garbage value
if (new_channelmap[i] != -1)
~~~~~~~~~~~~~~~~~ ^
|
|
instance.c:280:10: warning: Potential leak of memory pointed to by 'new_channelmap'
pdch = g_slist_nth(di->decoder->channels, i)->data;
^~~~~~~~~~~
|
|
The previous implementation internally noticed the "want terminate"
request, and skipped decoder execution to faster get to the end of the
input stream. But an OK return code was provided in that code path, and
more input data was sent by applications (sometimes for many seconds or
few minutes).
Do return a new SRD_ERR_TERM_REQ error code, such that applications can
tell failed execution from requested termination.
|
|
It's uncertain why srd_inst_decode() which internally gets called by the
public srd_session_send() routine used to clear the want_wait_terminate
flag. This should be cleared upon decoder instance creation and state
reset, gets raised upon termination request, but shall not get cleared
in other spots, especially not upon the availability of new input data
while the stream shall be considered in the "about to terminate, skip
all subsequent execution" state.
|
|
Implement routines which terminate currently pending decoder operations
and reset internal state (on the C and Python sides) for instances as
well as sessions. This allows to re-use previously created stacks for
new input data.
|
|
Introduce an oldpins_array_seed() helper routine, to make sure that each
call site which checks previous pin state will find valid data. This was
not always the case after decoder reset, which released the old pin data
while applications would not call srd_inst_new() again.
Preset newly allocated arrays with the default initial pin state, allow
optional application calls to specify differing initial values (when
specified by users), and keep the current state after first data was
processed.
|
|
|
|
|
|
With these additions, frontends can now call libsigrokdecode API
functions from different threads without running into threading issues.
The backend releases the GIL when it is performing tasks that might take
a while and it doesn't need to run Python/C API calls during that time.
This allows frontends to run multiple PD stacks (in multiple frontend
threads) "at the same time" in a time-sharing, "interlocked" manner.
Whenever one of the decoders is inside e.g. self.wait() it releases the
GIL and thus allows other decoders to do some work in the mean time.
The user-visible effect is that for use-cases such as running 3 different
decoder stacks at the same time for an acquisition, the user will not
have to wait for PD 1 to finish decoding, then wait for PD 2 to finish
decoding, and only *then* being able to see annotations from PD 3.
Instead, all three PDs will decode some chunks of data from time to
time, thus the user is able to inspect annotations from all 3 PDs while
the acquisition and decoding is still going on.
|
|
All decoders must be of PD API version 3 now.
|
|
|
|
|
|
This allows frontends to set the assumed initial pins (i.e., the assumed
state of the pins before the first sample of a capture) to user-specified
values.
The assumed initial pins can be either low, or high, or "use same value
as the first sample of the capture".
The special self.initial_pins decoder attribute is now removed.
|
|
Add support to terminate blocking .wait() and .decode() method calls of
v3 decoder instances. This terminates the decoder thread's main routine
and allows to release associated resources. Cope with requested as well
as unexpected termination of decode() calls. Add debug messages to
thread related code paths.
Make sure to unblock the main thread which feeds the decoder thread.
This unbreaks situations where decoders e.g. throw "need samplerate to
decode" exceptions.
Drain Python errors which might remain from the most recent .decode()
execution, to not affect other code paths. This avoids an issue where
the creation of a new decoder instance fails in the presence of errors
from a previous run.
This fixes bug #902.
|
|
|
|
|
|
|
|
This validates the requirements that
* abs_start_samplenum continues where the previous decode ended
* abs_end_samplenum is not lower than abs_start_samplenum
Failure to meet these requirements will make v3 decoders crash.
|
|
The Decoder_wait() routine will populate the .matched attribute before
returning to the caller. The srd_inst_start() routine used to setup a
.matches attribute which is unexpected. Make both routines consistently
assign to 'matched' as that is what Python decoder implementations are
referencing.
|
|
|
|
../instance.c: In function ‘srd_inst_find_by_id’:
../instance.c:485:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if (di = srd_inst_find_by_id_stack(inst_id, tmp))
^~
|
|
srd_inst_find_by_id() previously only searched for instance IDs at the
bottom of any stacked decoders. Make it properly search all stacks,
just like srd_inst_find_by_obj() and more usefully when trying to
generate unique instance IDs.
No external API change, only the explicit behaviour of the API.
This fixes parts of bug #868.
Signed-off-by: Karl Palsson <karlp@etactica.com>
|
|
srd_inst_new() used the decoder ID as the instance ID, preventing the use
of multiple instances of the same decoder in the same session. Simply
append a numerical suffix to later instances to allow more.
Required changes to cleanup to reliably free all memory. Valgrind checked.
This fixes parts of bug #868.
Based on original work by: Soeren Apel <soeren@apelpie.net>
Signed-off-by: Karl Palsson <karlp@etactica.com>
|
|
For the time being, both APIs (2 and 3) will remain supported until all
decoders have been converted to API version 3. Then, support for API
version 2 will be dropped.
Decoders using PD v3 API can benefit from both readability improvements
as well as performance improvements. Up to 10x speedup has been measured
in some situations (depends a lot on the decoder, the amount of data,
the amount of edges in the signals, the amount of oversampling etc. etc.).
This is only the first set of (basic) performance improvements for
libsigrokdecode, there are various additional opportunities for further
changes to improve performance.
This changeset has been tested to survive a run of all the test-cases in
the sigrok-test repo without issues (for the converted PDs), however it is
not very well-tested yet, so there might be regressions that need to be
addressed.
|
|
Signed-off-by: Karl Palsson <karlp@etactica.com>
|
|
|
|
|
|
Also, drop @since tag (as the function is not public).
|
|
Limit usage of the Python C API to the stable ABI subset as defined
by PEP 384. This removes some type definitions and functions which
libsigrokdecode made use of. Convert all affected code to suitable
API alternatives. Also fix a few leaks that became apparent while
working on the code.
The most visible change is that PyTypeObject is now an opaque type.
Thus, the custom Decoder and srd_logic types are now created on the
heap via an alternative API. Unfortunately, since tp_name is now
inaccessible, type names had to be removed from the log output.
Stack traces after Python exceptions are now formatted by calling
into Python, since the trace object C API is no longer available.
|
|
Since Autoconf places some important feature flags only into the
configuration header, it is necessary to include it globally to
guarantee a consistent build.
|
|
|