mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-05 13:29:57 -05:00
memblockq-test: fix incorrect assumption of pa_memblockq_pop_missing() behaviour
The intuitive meaning of "missing" would be the difference between tlength and the current queue length, and that's how memblockq-test assumed pa_memblockq_pop_missing() to define the term "missing", but that was an incorrect assumption, causing the last pa_memblockq_pop_missing() return value assertion to fail. This patch fixes the failing assertion and adds some comments about how the "missing" and "requested" variables in memblockq work.
This commit is contained in:
parent
8e9f070747
commit
b6e6e78cc2
1 changed files with 75 additions and 20 deletions
|
|
@ -421,74 +421,129 @@ START_TEST (memblockq_test_pop_missing) {
|
||||||
bq = pa_memblockq_new("test memblockq", idx, maxlength, tlength, &ss, prebuf, minreq, maxrewind, &silence);
|
bq = pa_memblockq_new("test memblockq", idx, maxlength, tlength, &ss, prebuf, minreq, maxrewind, &silence);
|
||||||
fail_unless(bq != NULL);
|
fail_unless(bq != NULL);
|
||||||
|
|
||||||
/* initially, the whole target length of bytes is missing */
|
/* The following equation regarding the internal variables of a memblockq
|
||||||
|
* is always true:
|
||||||
|
*
|
||||||
|
* length + missing + requested = tlength
|
||||||
|
*
|
||||||
|
* "length" is the current memblockq length (write index minus read index)
|
||||||
|
* and "tlength" is the target length. The intuitive meaning of "missing"
|
||||||
|
* would be the difference between tlength and length, but actually
|
||||||
|
* "missing" and "requested" together constitute the amount that is missing
|
||||||
|
* from the queue. Writing to the queue decrements "requested" and reading
|
||||||
|
* from the queue increments "missing". pa_memblockq_pop_missing() resets
|
||||||
|
* "missing" to zero, returns the old "missing" value and adds the
|
||||||
|
* equivalent amount to "requested".
|
||||||
|
*
|
||||||
|
* This test has comments between each step documenting the assumed state
|
||||||
|
* of those internal variables. */
|
||||||
|
|
||||||
|
/* length + missing + requested = tlength
|
||||||
|
* 0 + 100 + 0 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), tlength);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), tlength);
|
||||||
|
|
||||||
/* add 20 bytes of data */
|
/* length + missing + requested = tlength
|
||||||
|
* 0 + 0 + 100 = 100 */
|
||||||
|
|
||||||
for (int i = 0; i != 2; ++i)
|
for (int i = 0; i != 2; ++i)
|
||||||
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* no new missing data is reported */
|
/* length + missing + requested = tlength
|
||||||
|
* 20 + 0 + 80 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* fill up to 100 bytes of data */
|
/* length + missing + requested = tlength
|
||||||
|
* 20 + 0 + 80 = 100 */
|
||||||
|
|
||||||
for (int i = 0; i != 8; ++i)
|
for (int i = 0; i != 8; ++i)
|
||||||
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is at target level now */
|
/* length + missing + requested = tlength
|
||||||
|
* 100 + 0 + 0 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* pop 40 bytes of data, down to 60 bytes fill level */
|
/* length + missing + requested = tlength
|
||||||
|
* 100 + 0 + 0 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 40, &chunk), 0);
|
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 40, &chunk), 0);
|
||||||
pa_memblockq_drop(bq, 40);
|
pa_memblockq_drop(bq, 40);
|
||||||
ck_assert_int_eq(chunk.length - chunk.index, 40);
|
ck_assert_int_eq(chunk.length - chunk.index, 40);
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is 40 bytes under target length
|
/* length + missing + requested = tlength
|
||||||
* This is less than minreq, so no missing data is reported */
|
* 60 + 40 + 0 = 100 */
|
||||||
|
|
||||||
|
/* 40 bytes are missing, but that's less than minreq, so 0 is reported */
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* add 30 bytes of data, up to 90 bytes fill level */
|
/* length + missing + requested = tlength
|
||||||
|
* 60 + 40 + 0 = 100 */
|
||||||
|
|
||||||
|
/* Now we push 30 bytes even though it was not requested, so the requested
|
||||||
|
* counter goes negative! */
|
||||||
for (int i = 0; i != 3; ++i)
|
for (int i = 0; i != 3; ++i)
|
||||||
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is 10 bytes under target length
|
/* length + missing + requested = tlength
|
||||||
* This is less than minreq, so no missing data is reported. */
|
* 90 + 40 + -30 = 100 */
|
||||||
|
|
||||||
|
/* missing < minreq, so nothing is reported missing. */
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* pop 20 bytes of data, down to 70 bytes of data */
|
/* length + missing + requested = tlength
|
||||||
|
* 90 + 40 + -30 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
|
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
|
||||||
pa_memblockq_drop(bq, 20);
|
pa_memblockq_drop(bq, 20);
|
||||||
ck_assert_int_eq(chunk.length - chunk.index, 20);
|
ck_assert_int_eq(chunk.length - chunk.index, 20);
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is 30 bytes under target length
|
/* length + missing + requested = tlength
|
||||||
* This is less than minreq, so no missing data is reported */
|
* 70 + 60 + -30 = 100 */
|
||||||
|
|
||||||
|
/* missing < minreq, so nothing is reported missing. */
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* add 50 bytes of data, up to 120 bytes fill level */
|
/* length + missing + requested = tlength
|
||||||
|
* 70 + 60 + -30 = 100 */
|
||||||
|
|
||||||
|
/* We push more data again even though it was not requested, so the
|
||||||
|
* requested counter goes further into the negative range. */
|
||||||
for (int i = 0; i != 5; ++i)
|
for (int i = 0; i != 5; ++i)
|
||||||
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is above target level, so no missing data is reported. */
|
/* length + missing + requested = tlength
|
||||||
|
* 120 + 60 + -80 = 100 */
|
||||||
|
|
||||||
|
/* missing < minreq, so nothing is reported missing. */
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
||||||
|
|
||||||
/* pop 20 bytes of data, down the target level */
|
/* length + missing + requested = tlength
|
||||||
|
* 120 + 60 + -80 = 100 */
|
||||||
|
|
||||||
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
|
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
|
||||||
pa_memblockq_drop(bq, 20);
|
pa_memblockq_drop(bq, 20);
|
||||||
ck_assert_int_eq(chunk.length - chunk.index, 20);
|
ck_assert_int_eq(chunk.length - chunk.index, 20);
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
check_queue_invariants(bq);
|
check_queue_invariants(bq);
|
||||||
|
|
||||||
/* queue fill level is at target level now
|
/* length + missing + requested = tlength
|
||||||
* No missing data should be reported. */
|
* 100 + 80 + -80 = 100 */
|
||||||
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
|
|
||||||
|
/* missing has now reached the minreq threshold */
|
||||||
|
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 80);
|
||||||
|
|
||||||
|
/* length + missing + requested = tlength
|
||||||
|
* 100 + 0 + 0 = 100 */
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
pa_memblockq_free(bq);
|
pa_memblockq_free(bq);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue