A major rethinking of a ring buffer---an inifinite buffer!

No, really!  Hear me out.

"Perspective is worth 80 IQ points."
	-- Alan Kay

Don't let the term "buffer" in "ringbuffer" cloud your mind.  If you are
going to be writing fixed-sized buffers, skip the time consuming memcpy()
and instead just save the pointers.  That's one write vs.
(buffersize/sizeof(ptr*)) writes (remember, for performance, every cycle is
sacred, every cycle is great!  If a cycle is wasted, God gets quite irate!)
You still have a "ringbuffer" but the "buffer" is now storing addresses, not
bytes.

Second, let's go back to first principles.  Assume we had a magical memory
space that just grows as we use it.  What would such an "infinitebuffer"
work?  Don't laught---it might very well be possible on a 64-bit system.  64
bits of address space is *huge*---approximately 2*10^19 bytes---which, if
you tried to read one byte per nanosecond, it would take around 570 years to
finish!  (Good god!  the POST times for PCs in the future are going to be
astronomical!)  So with a few tricks from the operating system, it might
very well be possible to just use memory without concern.

So anyway, what would the code for such an infinite buffer look like?  Quite
short really---less than a dozen instructions to write, perhaps two dozen to
read.  Only an address worth of bytes need be written, and that can be done
in a single instruction.  And it's fast.  How fast?  Well, how about
4,000,000 writes/reads per second (and that's with some overhead of filling
in a structure for "writing" and checking said structure when "reading")?
Not bad, eh?

Oh, and don't think that's theoretical.  Nope.  It's what I'm getting.

Now obviously, I don't have an infinite abount of memory, and certainly the
operating system I'm using doesn't support this mysterious, magically
growing region of memory, but I can simulate at least a small portion of
said space.

The idea here is to set aside a maximum number of buffers you want to use,
and a infbuffer (as I'm calling them) to hold pointers to all of them.
Assuming one buffer used every 10ms, that's 100 buffers per second.
4,000,000 buffers will give you 11 hours, 6 minutes, 40 seconds worth of
buffers.  I don't think we're really memory constrained, so that should be
fine.  And it does simplify the implementation.

And did I mention it's fast?

Also, the code works with any number of threads reading and writing to the
infbuffer.  I've found (at least on my system) that having one reader and
one writer per core gives the best throughput---more or less and the
performance isn't quite as good.

I've also found that serving out pre-allocated memory (vs. calling malloc()
leads to much better performance (at least 50% faster) but the code in
test-infbuffer.c can do either (compile time option) so you can test it.

So, seriously.  Give this some thought.