summaryrefslogtreecommitdiff
path: root/buffer_tree.c (follow)
Commit message (Collapse)AuthorAge
* btr: Simplify btr_drop_buffer_reference().Andre Noll2026-05-08
| | | | | | 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.
* Switch to SPDX identifiers.Andre Noll2026-03-17
| | | | | | | | 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.
* btr: Fix memory leak in btr_add_output_dont_free().Andre Noll2026-03-17
| | | | | | | | | | | | | | | | | | | | | 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.
* Improve buffer tree documentation.Andre Noll2025-10-08
| | | | | 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.
* btr: Fix buffer tree merging.Andre Noll2025-07-13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Remove ->execute() of struct writer.Andre Noll2025-06-25
| | | | No writer implements this method.
* buffer_tree: Assert that we don't pass NULL to memcpy().Andre Noll2025-05-22
| | | | | | 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.
* Include regex.h from para.h.Andre Noll2025-05-19
| | | | Every .c file includes it anyway.
* Constify buffer tree API.Andre Noll2024-05-08
| | | | | | 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.
* btr: Merge buffers on insertion.Andre Noll2024-05-08
| | | | | | | | | | | | | 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%.
* btr: Speed up btr_node_status().Andre Noll2024-05-08
| | | | | | | | | | 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%
* Consolidate EOF error codes.Andre Noll2023-03-11
| | | | | | 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.
* Merge topic branch t/overflow into masterAndre Noll2022-10-03
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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().
| * string: Rename para_calloc() -> zalloc().Andre Noll2022-07-29
| | | | | | | | | | Reword the documentation a bit since the function has never been a wrapper for calloc(3). No code changes.
| * string: Rename para_malloc() -> alloc().Andre Noll2022-07-29
| | | | | | | | | | | | | | 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
* | Rename ->{pre,post}_select methods to ->{pre,post}_monitor.Andre Noll2022-08-25
|/ | | | | | | 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.
* list.h: Convert INIT_LIST_HEAD macro to inline function.Andre Noll2021-08-08
| | | | | Inline functions are easier to read and write, and we get type safety.
* Shorten copyright notice.Andre Noll2017-09-22
| | | | | | | | | | | | | | | | | | | | | 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 }'
* doxygen: Add \ref to references.Andre Noll2017-06-25
| | | | | This way doxygen issues a warning if the file/function/structure no longer exists and a stale reference remains.
* Update year in copyright headers.Andre Noll2015-01-12
| | | | | | | | | | | | | | | | 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.
* doc: Change email address to maan@tuebingen.mpg.deAndre Noll2014-08-18
| | | | | | | | | | | | | | 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
* Fix memory leak in btr_splice_out_node().Andre Noll2014-05-03
| | | | | | | | 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.
* Change copyright year to 2014.Andre Noll2014-02-22
| | | | | | | | | 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
* btr: Simplify btr_node_status().Andre Noll2013-09-29
| | | | | | | | | | | 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.
* buffer_tree: Improve btr_splice_out_node().Andre Noll2013-09-29
| | | | | | 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.
* Merge branch 't/misc_cleanups'Andre Noll2013-09-29
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * buffer_tree: Improve documentation of btr_no_parent().Andre Noll2013-09-04
| |
* | btr: splice-out fix.Andre Noll2013-09-22
|/ | | | | | | | | | | | | 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.
* buffer_tree.c: Add documentation of btr_parent().Andre Noll2013-07-13
| | | | | This function was introduced in commit 37e0dfe7 (check_wav: Ask parent nodes before falling back to defaults) without documentation.
* Merge branch 't/allow_zero_btr_add'Andre Noll2013-05-02
|\ | | | | | | Was cooking for over a month.
| * btr: Handle zero-sized buffers gracefully.Andre Noll2013-03-10
| | | | | | | | | | | | 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.
* | Change copyright year to 2013.Andre Noll2013-03-25
|/ | | | Better late than never.
* resample filter: Implementation.Andre Noll2012-11-25
| | | | | | | | | | | | | | | | | | 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.
* check_wav: Ask parent nodes before falling back to defaults.Andre Noll2012-11-25
| | | | | | | | | | | | | 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.
* buffer_tree.c: Fix a typo.Andre Noll2012-10-21
|
* btr_next_buffer_omit(): Add comment on passing NULL pointer.Andre Noll2012-10-15
| | | | | It has always been OK to pass a NULL buffer pointer to this function, but this was not documented yet.
* btr_exec_up(): Also ask given node.Andre Noll2012-07-08
| | | | | | | | | | 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.
* btr: Introduce btr_add_output_dont_free().Andre Noll2012-07-08
| | | | | | | | | | | | | | | | | 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.
* btr: Remove btr_free_node().Andre Noll2012-07-08
| | | | | | | | | 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.
* btr_slice_out_node(): Set parent to NULL.Andre Noll2012-04-09
| | | | | Without this, a subsequent btr_remove_node() on the spliced out node could segfault.
* btr_remove_node(): Loglevel adjustments.Andre Noll2012-04-06
| | | | These two log messages got a bit too noisy. Degrade loglevel to info.
* Change year in copyright message to 2012.Andre Noll2012-01-07
|
* Always include stdbool.h.Andre Noll2011-12-18
| | | | | | | | | 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.
* btr: Introduce btr_next_buffer_omit().Andre Noll2011-11-13
| | | | This function is useful for the flac decoder.
* doxygen: Add some missing documentation.Andre Noll2011-05-15
|
* btr: Fix documentation of btr_consume().Andre Noll2011-02-07
| | | | s/buffer tree/buffer pool/.
* Replace 2010 in copyright message by 2011.Andre Noll2011-01-17
|
* audiod: Handle crashes of para_server more robustly.Andre Noll2010-10-10
| | | | | | | | | | | | 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.
* Add missing documentation of moods_event_handler() and btr_free_node().Andre Noll2010-10-10
|
* aacdec: Fix a brown paper bag bug.Andre Noll2010-07-26
| | | | | | | | | | | | | 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.