| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
| |
Drop the bool flag which indicates whether the buffer itself should also be
deallocated. The function can answer this itself by consulting the dont_free
flag of the buffer pointer.
|
| |
|
|
|
|
|
|
| |
Generated with
sed -i 's|Copyright.*Andre Noll.*|SPDX-License-Identifier: GPL-2.0 */|g' *.c *.h
followed by manually tweaking the result a bit. No license change intended.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Quite a massive leak indeed, albeit only triggered by para_play:
==25044== 423,420 bytes in 21,171 blocks are definitely lost in loss record 90 of 90
==25044== at 0x404ADDE: realloc (vg_replace_malloc.c:1804)
==25044== by 0x805AC34: arr_realloc (string.c:40)
==25044== by 0x805AC63: arr_alloc (string.c:61)
==25044== by 0x805AC7B: arr_zalloc (string.c:76)
==25044== by 0x805ACA2: zalloc (string.c:98)
==25044== by 0x8055445: new_btrb (buffer_tree.c:306)
==25044== by 0x8057070: btr_add_output_dont_free (buffer_tree.c:457)
==25044== by 0x805DC86: afh_recv_post_monitor (afh_recv.c:204)
==25044== by 0x805491C: call_post_monitor (sched.c:117)
==25044== by 0x805491C: sched_post_monitor (sched.c:143)
==25044== by 0x805491C: schedule (sched.c:183)
==25044== by 0x804F217: main (play.c:1228)
We leak one buffer reference (20 bytes on x86-32) per chunk when the buffer
can merged, which is true unless we reach the end of the buffer pool.
|
| |
|
|
|
| |
Minor improvements to the API description in buffer_tree.h, a lot of \a and
\p removal in buffer_tree.c, and the addition of some missing \ref statements.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The merge case of add_btrb_to_children() is rather broken. For one, if
the node has more than one child and we end up freeing the btr buffer in
the first iteration, we read stale contents when calling may_merge_btrb()
in the next iteration of the loop.
Secondly, not all callers of add_btrb_to_children() cope with btrb being
freed after merging occurred. In particular, the alsa writer triggers an
invalid read such as:
at 0x804C7AC: btr_drop_buffer_reference (buffer_tree.c:351)
by 0x804CD4A: btr_pushdown_br (buffer_tree.c:520)
by 0x804CD4A: btr_pushdown (buffer_tree.c:539)
by 0x804D948: check_wav_post_monitor (check_wav.c:194)
by 0x804C31B: call_post_monitor (sched.c:118)
by 0x804C31B: sched_post_monitor (sched.c:144)
by 0x804C31B: schedule (sched.c:184)
by 0x804A9CE: setup_and_schedule (write.c:97)
by 0x804A9CE: main (write.c:149)
The problem is that btr_pushdown_br() calls add_btrb_to_children(), followed
by btr_drop_buffer_reference(). The first function frees br->btrb in the
may-merge case and the second function reads from this pointer.
This patch addresses both issues. It renames may_merge_btrb() to
try_merge_btrb(), checks more carefully if a merge is possible, and performs
the merge. This function needs to return whether the buffer was merged because
the callers have to clean up in different ways depending on whether or not
buffers were merged.
This retains the nice speedup of f64cbcc03484 at the cost of even more
complicated buffer tree code.
Reproducer (must run on a slow machine or under valgrind to trigger):
para sender udp add 224.0.1.38:8000
para_recv -r udp > fec-encoded-data
./para_filter -f fecdec -f mp3dec < fec-encoded-data | ./para_write
Fixes: f64cbcc034844628b7e7817e27205cc6b48e9a18
|
| |
|
|
| |
No writer implements this method.
|
| |
|
|
|
|
| |
The buffer pointer cannot be NULL here because this only happens when the
buffer tree area is full, which is not the case thanks to the previous n <=
btr_pool_unused(btrp) check.
|
| |
|
|
| |
Every .c file includes it anyway.
|
| |
|
|
|
|
| |
A lot of functions of the buffer tree API don't modify the memory
referenced by the pointers passed. This patch marks these pointer
arguments as constant.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Currently add_btrb_to_children() simply adds the given buffer
reference to the input queue of all children of the given node even
if the newly added buffer reference points memory adjacent to the
previously added buffer.
Since several helpers iterate over all buffer references, performance
suffers, given enough buffer references. So merge buffers when
possible.
User time: 147s -> 83s, speedup: 44%.
|
| |
|
|
|
|
|
|
|
|
| |
Currently we sum up the sizes of all buffers in the input queue just to
determine if the total size exceeds a small threshold. That's silly
and expensive if there are many buffers. Fix that by introducing
a helper which breaks out of the loop as soon as know the answer
because the threshold is exceeded.
User time: 150s -> 147s, speedup: 2%
|
| |
|
|
|
|
| |
Currently we have ~15 error codes which indicate an EOF condition. One
should suffice, so drop all codes except the generic E_EOF and use
that everywhere.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This series implements a new memory allocation API which checks
for overflows. The first part of the series just renames the main
allocation functions. Later patches in the series implement allocators
which take two size_t arguments (like calloc(3)) and check whether the
multiplication overflows by employing the __builtin_mul_overflow()
primitive supported by gcc and clang. This requires us to bump the
lowest supported gcc and clang version.
* refs/heads/t/overflow:
build: Compile with -ftrapv.
string: Introduce arr_zalloc().
string: Introduce arr_alloc().
string: Introduce arr_realloc() and check for integer overflow.
string: Rename para_calloc() -> zalloc().
string: Rename para_malloc() -> alloc().
string: Overhaul para_strdup().
|
| | |
| |
| |
| |
| | |
Reword the documentation a bit since the function has never been a
wrapper for calloc(3). No code changes.
|
| | |
| |
| |
| |
| |
| |
| | |
Just because it's shorter and matches the naming of the new allocators
we are about to introduce. The bulk of this patch was created with
sed -i 's/para_malloc/alloc/g' *.c *.h yy/mp.y
|
| |/
|
|
|
|
|
| |
The word "monitor" is neutral and continues to be correct after the
switch from select(2) to poll(2).
Pure rename, nothing to see here.
|
| |
|
|
|
| |
Inline functions are easier to read and write, and we get type
safety.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The GPLv2 line does not add any additional information, so drop
it. This leaves a single line of legalese text for most files, which
is about the amount of screen real estate it deserves.
This patch was created with the following script (plus some manual
fixups):
awk '{
if (NR <= 5) {
gs = gensub(/.*Copyright.* ([0-9]+).*Andre Noll.*/, "\\1", "g")
if (gs != $0)
year = gs
next
}
if (NR == 6 && year != "")
printf("/* Copyright (C) %s Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */\n", year)
print
}'
|
| |
|
|
|
| |
This way doxygen issues a warning if the file/function/structure no
longer exists and a stale reference remains.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Done with
files=$(git grep -l 'Copyright (C) [0-9]\{4\}\(-2014\)* Andre Noll')
sed --in-place= -e 's/Copyright (C) \([0-9]\{4\}\)-2014 Andre Noll/Copyright (C) \1 Andre Noll/1' $files
In previous years we ran a similar script to set the second year in
the range to the current year. This is kind of silly, so let's get
rid of this useless information.
This commit replaces "Copyright (C) A-B" by "Copyright (C) A" in
all file headers, i.e. only the first year (A) is left in. Accurate
information including time stamps for each change can be obtained
from the git history.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The mail server on systemlinux.org was down for more than a week
lately, so let's use an alternative official address. This commit
changes all maan@systemlinux.org addresses to maan@tuebingen.mpg.de.
Most .c and .h files contain the email address in the copyright header,
so they must all be patched. Three other files contain the address
for a different reason:
* README lists email and git, gitweb and home page URLs
* configure.ac needs it for configure -h
* version.c contains it for the -V option of all commands
|
| |
|
|
|
|
|
|
| |
Commit 072391fc (Improve btr_splice_out_node(), 2013-03) modified this
function to take a pointer to a buffer tree node pointer so that the
node pointer can be invalidated after it is spliced out. However, this
also means the caller can no longer free its resources. Hence we must
free the btrn in btr_splice_out_node() in order to avoid memory leaks.
|
| |
|
|
|
|
|
|
|
| |
This year, we're really on time. The changes in this patch were
created by the following silly script:
files=$(git grep -l 'Copyright (C) [0-9]\{4\}\(-2013\)* Andre Noll')
sed --in-place= -e 's/Copyright (C) \([0-9]\{4\}\)-2013 Andre Noll/Copyright (C) \1-2014 Andre Noll/1' $files
sed --in-place= -e 's/Copyright (C) 2013 Andre Noll/Copyright (C) 2013-2014 Andre Noll/1' $files
|
| |
|
|
|
|
|
|
|
|
|
| |
This changes btr_node_status() to check for errors before looking
at queue sizes. In certain cases this avoids to call the possibly
expensive btr_get_output_queue_size().
If no more input is going to arrive for an internal node whose output
queue is full, btr_node_status() now returns EOF immediately, which
is better than the previous scheme where we waited for the output
queue to become empty before returning EOF.
|
| |
|
|
|
|
| |
This changes btr_splice_out_node() to take a pointer to a btrn, just
like btr_remove_node(). This allows to set the variable to NULL after
the node has been spliced out. The callers are updated accordingly.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Was cooking since 2013-08-04.
3f97ae buffer_tree: Improve documentation of btr_no_parent().
fb9209 Avoid gcc warning on FreeBSD.
778af7 command.c: Avoid declaration after statement.
61c957 extract_v4_addr(): Don't return a structure.
1d7937 command.c: Remove pointless initialization.
c17ede crypt.c: Remove condition which is always true.
a12ecb ipc: Close proc fd.
01d37b Make log functions static.
0ba631 score: Improve documentation of score_update().
d6cf71 GIT-VERSION-GEN: Don't include output of git update-index.
|
| | | |
|
| |/
|
|
|
|
|
|
|
|
|
|
|
| |
When splicing out a node we set the ->parent pointer of all child
nodes to the parent of the given node, and move each child to the
->children list of the parent.
Except when there is no parent. If the given node was a root node
(or an internal node whose parent vanished), we leave the ->children
list untouched. In this case the assertion a few lines later triggers
and aborts the program. Fix this by removing the nodes from the list.
Such nodes have become root nodes themselves, so they should not be
on any list of children.
|
| |
|
|
|
| |
This function was introduced in commit 37e0dfe7 (check_wav: Ask parent
nodes before falling back to defaults) without documentation.
|
| |\
| |
| |
| | |
Was cooking for over a month.
|
| | |
| |
| |
| |
| |
| | |
There is no need to abort on the attempt to add a zero sized buffer.
Let's be gentle and make this condition a noop rather than a fatal
error.
|
| |/
|
|
| |
Better late than never.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The resample filter allows to change the sample rate of a stream on the
fly. All the magic happens within libsamplerate, so the implementation
is quite simple.
However, one tricky thing to consider is how wav headers are treated:
Although the resample filter creates only a single task, it adds
two different nodes to the buffer tree, one for the wav detector and
another one for the resample filter itself.
At startup the generic code of para_filter or para_audiod adds only
the resample filter node, which in turn inserts the wav detector as
its own parent node. This requires to insert a new internal node to
the buffer tree which is currently not supported by the buffer tree
API. It is easy to implement this feature though, so this commit adds
the missing functionality to buffer_tree.c.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This instructs the ->execute handler of the check_wav task to ask its
parent nodes for the channel count, sample rate and sample format in
case no wav header was found and no value for the query was given at
the command line. Currently this can never succeed, since the only
parent node of the check_wav task is the stdin task, which has no
clue about these things. However, once check_wav is being used by
the resample filter, one parent might be a decoder which can tell.
This requires to add the new public btr_parent() to buffer_tree.c to
let the check_wav node obtain the node to start the search from.
|
| | |
|
| |
|
|
|
| |
It has always been OK to pass a NULL buffer pointer to this function,
but this was not documented yet.
|
| |
|
|
|
|
|
|
|
|
| |
At the moment, the buffer tree walk starts at the parent of the given
node. Users of the btr API can not execute a command for a node unless
it has at least one child.
This unnecessary restriction is removed in this commit by letting
the tree walk start at the given node rather than its parent.
This actually simplifies the code a bit.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
At the moment, all buffers which are fed to a buffer tree must be
allocated on the heap since the buffer tree code automatically frees
the buffer once its refcount dropped to zero.
The new afh receiver, however, mmaps the audio file and likes to feed
chunks of this memory map into the buffer tree. This is currently
impossible because such buffers must not be freed.
This patch adds the new public function btr_add_output_dont_free()
which works like btr_add_output() but sets the new dont_free bit
which prevents the buffer from being deallocated.
Also btr_inplace_ok() is changed to return "false" whenever there
exists a buffer in the input queue with the dont_free bit set.
|
| |
|
|
|
|
|
|
|
| |
This has turned out to be source for bugs. Deallocate everything
in btr_remove_node() hence making removing the node and freeing
its resources an atomic operation.
To avoid dangling pointers to freed btrn nodes, the argument of
btr_remove_node() is changed to to struct btr_node **btrnp.
|
| |
|
|
|
| |
Without this, a subsequent btr_remove_node() on the spliced
out node could segfault.
|
| |
|
|
| |
These two log messages got a bit too noisy. Degrade loglevel to info.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
This adds the #include statement for stdbool.h to para.h. This allows
to get rid of the individual includes in *.c.
More importantly, since all *.c files include para.h, booleans will
now be available everywhere so that we won't need to touch dozens of
files anymore whenever a boolean is added to a public structure.
|
| |
|
|
| |
This function is useful for the flac decoder.
|
| | |
|
| |
|
|
| |
s/buffer tree/buffer pool/.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
In case para_server dies unexpectedly, para_audiod may still have a partial status
item in the buffer tree node of the client task which can lead to a busy loop.
Fix this by flushing the input queue and invalidate the current audio format to prevent
recreating a buffer tree before the status task resumes.
There is already flush_input_queue() in buffer_tree.c but that can't be called by audiod.c
as it is a static function. Make it public and rename it to btr_drain() which is shorter and
more to the point and has the usual btr_ prefix.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Oops, we were using PARA_MAX() instead of PARA_MIN() to determine
the number of bytes to convert in the next run. This silly bug could
lead to a segfault in the aacdec filter. Moreover, the assertion in
buffer_tree.c that would have caught the bug was _also_ b0rken.
But it's not my fault. I blame Grover of the Sesame street for both
bugs. He did explain the difference between near and far, although
this knowledge is next to useless for a programmer. And he did not
say a single word about MIN and MAX, or true and false. No wonder
such bugs happen.
|