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).
Paul said he prefers storing the masked pointer, but I think Fons & PA's
approach is better: it allows for full use of the buffer.
-Sean
_______________________________________________
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 00:15:05 2008
This archive was generated by hypermail 2.1.8 : Tue Oct 21 2008 - 00:15:06 EEST