Age | Commit message (Collapse) | Author |
|
Silence printf(3) format warnings. Python's data types should be
considered opaque, size (and signedness) are usually unknown, as is
the relation to standard C language print format specs.
Unbreak long messages which were spread across several source code
text lines. This complies to Linux style guides. Being able to find
diagnostics messages that were reported by users in sources is more
important than sticking to an arbitrary text line length.
|
|
Break a rather long line for a Python method call at a different
location, to better reflect the parameter groups which organize for the
method to get called, and those which pass parameters to that called
method. This commit also splits the actual action and its check for
successful execution into separate C language statements.
|
|
When the protocol decoder's input data is exhausted, then the .wait()
method will raise the EOFError exception. Python decoders can catch this
exception and handle the condition. For proper annotation emission it is
essential that the self.samplenum value corresponds to the last position
in the input stream. Update it before returning from the .wait() call.
|
|
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.
|
|
Rephrase the 'names[]' array declaration in output_type_name() to avoid
the necessity of guessing what the maximum length of the literals might
be during future maintenance. Developers need not care when the compiler
can handle this detail.
|
|
Avoid the full listing of all-zero struct members in sentinel items of
object methods and class properties tables. Use the ALL_ZERO phrase
instead which better reflects what's intended, and reliably silences
warnings should structs' lengths differ across Python versions.
|
|
Some doc strings have become outdated, update them. Some doc strings
were terse, extend them. Ideally protocol decoder authors would be able
to use the builtin documentation to answer questions on data types and
arguments order. This implementation isn't there yet, needs more work.
|
|
Move Python doc strings to the location where methods and classes get
implemented. This improves awareness during maintenance, and allows for
longer text phrases without obfuscating the registration code path.
This commit does not alter the content of existing doc strings, only
moves their location. And keeps related items together when long decls
span multiple text lines (function name and arguments list, args and
kw args), to improve/keep readability.
|
|
This fixes bug #1671.
Reported-By: Ivan Wick
|
|
|
|
Protocol decoders can now declare an arbitrary number of logic output
channels with a fixed assumed samplerate each.
|
|
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.
|
|
type_decoder.c:1040:16: warning: cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]
1040 | { "register", (PyCFunction)Decoder_register, METH_VARARGS|METH_KEYWORDS,
| ^
|
|
A recent commit tightened the check for acceptable 'skip' sample counts.
This broke the onewire_link and usb_signalling decoders' test sequences,
which no longer pass with a minimum count of one. Relax the condition
and accept a count of zero. This breaks gpib again for low total sample
count option values, but this needs to get addressed differently.
|
|
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.
|
|
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).
|
|
This fixes bug #1374.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Handle the most common case of one session and one decoder first so
we can exit early. This has a small, but measurable performance benefit.
|
|
This has a small, but measurable performance benefit.
|
|
These functions are only used in type_decoder.c. Move them there and
make them static.
|
|
|
|
|
|
type_decoder.c: In function ‘get_term_type’:
type_decoder.c:486:2: warning: switch missing default case [-Wswitch-default]
switch (v[0]) {
^~~~~~
|
|
|
|
type_decoder.c:836:3: warning: Value stored to 'ret' is never read
ret = process_samples_until_condition_match(di, &found_match);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
type_decoder.c:206:2: warning: Potential leak of memory pointed to by 'pdb'
PyGILState_Release(gstate);
^~~~~~~~~~~~~~~~~~
|
|
type_decoder.c:197:10: warning: Potential leak of memory pointed to by 'pdb'
return SRD_ERR_MALLOC;
^~~~~~~~~~~~~~
|
|
For the converted calls there's no requirement for all struct fields
being memset()'d to zero, or all struct fields are explicitly set
later anyway.
|
|
|
|
|
|
This fixes parts of bug #329.
|
|
The text presentation of decoder annotations' payload data was allocated
but not freed. As were the byte strings of binary output. Fix it.
This fixes parts of bug #329.
|
|
|
|
Future implementations might call decoders' start() routine several
times, which makes them call register() again. It's desirable that the
common backend code copes with this condition, such that (the multitude
of) decoder implementations need not work around a specific constraint.
|
|
Have the Python C API check the argument type and do the type conversion
already. Raise an IndexError exception when the range check fails.
|
|
|
|
|
|
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.
|
|
The Decoder.wait() method expects a list of dicts, or as a special form
a single dict, to specify the conditions to wait for. An empty dict or
an empty list mean "unconditional wait", requesting the very next sample.
Accept None as well as no arguments at all in Decoder.wait() calls. This
shall better reflect the intent and slightly unobfuscate PD code, as well
as avoid creation of potentially expensive Python objects at the call site.
|
|
The Decoder.wait() method works as expected when non-empty conditions
are specified by the caller. For empty conditions the implementation was
incomplete, and ended up in an infinite loop because the sample number
got stuck in the current location. Code review revealed more issues like
not getting more input data chunks when needed.
Detect when empty wait() conditions were specified, and re-use existing
code paths for match handling as much as possible. This is achieved by
the manual creation of a SKIP term with the appropriate count value.
It's assumed that naive decoder implementations will run this kind of
condition-less query for every individual sample, which means that
efficiency is important.
Make sample number 0 available to condition-less calls, too. Don't skip
the first sample in the input stream.
|
|
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.
|
|
The ownership of the tuple reference is transferred to the caller, so
the refcount should not be increased.
|
|
PyList_SetItem steals a reference, so code calling that must either
transfer ownership or increase the refcount.
|
|
py_conditionlist is an owned reference (it gets passed to Py_DecRef()
at the end), so we need to increment the refcount when assigning it
from the borrowed reference py_conds.
|