Re: [LAD] [LAU] Simple, easy multithreaded circular buffer library for Linux?

From: Pieter Palmers <pieterp@email-addr-hidden>
Date: Tue Oct 21 2008 - 00:13:16 EEST

Sean Bolton wrote:
> Hi Olivier,
>
> On Oct 20, 2008, at 6:13 AM, Olivier Guilyardi wrote:
>> Until now, I just couldn't write a test that fail because of the
>> lack of memory
>> barrier on x86. However, I think I found another bug in Jack
>> ringbuffer, by
>> writing another test.
>>
>> It's a bit of a weird test, I call it "bit circle": I start 16
>> "node" threads.
>> Each node :
>> - communicate with its adjacent node through 2 ring buffers
>> - is responsible for shifting an integer by one bit
>> - send the shifted result to the next node through a ring buffer
>> - checks that the value read from previous node is correct.
>>
>> On my Debian Quad Core and Mac OS X Core Duo boxes, this test fails
>> with Jack's
>> ringbuffer even with my patch applied. But it succeeds with
>> Portaudio (both with
>> and without memory barriers), and also with Fons' implementation.
>>
>> I wish someone could eventually run my test suite on a PowerPC,
>> especially SMP.
>>
>> The usage is unchanged:
>> svn co http://svn.samalyse.com/misc/rbtest
>> cd rbtest
>> make test
>>
>> The run time is now shorter, about 2 minutes. Below is the output.
>> You can see
>> that jack (test-bit-circle-jack) fails the bit circle test, even
>> when patched
>> (test-bit-circle-jack-fix1). "|" is printed when a node thread
>> starts, and "-"
>> when a node has read 1000 values, to ensure data is really flowing.
>>
>> The test-int-array-* tests are the same as my original test. All *-
>> lfq tests use
>> Fons's Lfq ringbuffer (modified to use char instead of uint32_t) as
>> backend.
>>
>> ./run-tests.sh bit-circle 512 jack jack-fix1 portaudio portaudio-
>> nobarrier lfq
>>
>> test-bit-circle-jack - starting (5s max) - buffer size: 512
>> || FAILURE: 2 != 514
>
> I thought it suspicious that 514 = 2 + 2 * 256, while on a PPC it
> returns
> FAILURE: 2 != 0. Endianness bug? No, but it's a clue...
>
> I don't think you're seeing a *bug* in the jack ringbuffer, just a
> difference in
> semantics between it and the PortAudio and lfq imlementations. Both PA
> and lfq mask the index after reading it, so they can completely fill
> the buffer.
> The jack implementation masks the stored index, which means it can't
> ever completely fill the buffer, or there would be an ambiguity as to
> whether
> it was full or empty. The most it can store is (size - 1) bytes.
>
> In the jack version of your code, at some point, the buffer almost
> fills, and
> jack_ringbuffer_write only writes a single byte to the buffer (low
> order on x86,
> high order on PPC). Next time around, it does this again. Then the
> following
> thread reads, not 0x0002 like it should, but either 0x0202 (x86) or
> 0x0000 (PPC).
>

I can confirm this, since the following will make the test 'succeed',
although it results in a very slow progress once the buffers are full.

Index: test-bit-circle.c
===================================================================
--- test-bit-circle.c (revision 314)
+++ test-bit-circle.c (working copy)
@@ -50,6 +50,9 @@

      if (value)
      {
+ while(jack_ringbuffer_write_space(rb[1]) < 2) {
+ usleep(1000);
+ }
        jack_ringbuffer_write (rb[1], (char *) &value, sizeof (uint16_t));
        value = 0;
      }

Pieter
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/mailman/listinfo/linux-audio-dev
Received on Tue Oct 21 04:15:03 2008

This archive was generated by hypermail 2.1.8 : Tue Oct 21 2008 - 04:15:03 EEST