Boost logo

Boost :

Subject: Re: [boost] [lockfree::fifo] Review
From: Chris M. Thomasson (cristom_at_[hidden])
Date: 2009-12-21 09:51:28


"Tim Blechmann" <tim_at_[hidden]> wrote in message
news:4B2F84D7.5090200_at_klingt.org...
> >> yes, i would guess, the performance characteristics differ depending on
> >> the number of elements in the buffer. also, the current implementation
> >> can easily be adapted to enqueue/dequeue multiple objects efficiently
> >> ...
> >
> > For the single-producer/consumer queue you can treat the access like a
> > transaction. For instance, the producer can read/write to the buffer up
> > to
> > the tail and commit the update just by incrementing the head. A consumer
> > can
> > read/write to the produced portion of the buffer and commit by bumping
> > the
> > tail. This is can good because you can avoid copying is come cases and
> > allow
> > the thread to use the data in the buffer directly. Here is an example of
> > such an algorithm:

> i just had a brief look at the algorithm, but it doesn't look too
> different from the kfifo ringbuffer from the linux kernel, does it?

You mean this one right?

http://www.gelato.unsw.edu.au/lxr/source/kernel/kfifo.c

I think it's different in that it allows for a producer or consumer to use
the buffer directly. For instance, you can do something like:

// producer

buffer_T buffer;

if (ringbuf_try_write_begin(..., &buffer))
{
    // the producer has sole access to the memory pointer
    // to by `buffer->ptr' the size of `buffer->size'.

    // just write a single character.
    buffer->ptr[0] = 'X';
    buffer->size = 1;

    // Okay, we can commit the write.
    ringbuf_write_commit(..., &buffer);
}

// consumer

buffer_T buffer;

if (ringbuf_try_read_begin(..., &buffer))
{
    // the consumer has sole access to the memory pointer
    // to by `buffer->ptr' the size of `buffer->size'.

    // print out all characters.
    char tmp = buffer->ptr[buffer->size - 1];
    buffer->ptr[buffer->size - 1] = '\0';
    puts(buffer->ptr);
    putchar(tmp);

    // commit our transaction
    ringbuf_read_commit(..., &buffer);
}

AFAICT, you cannot do this with the kfifo ringbuffer from the Linux Kernel
because it does not support the proper interface. The code does not need to
use external buffers and copy to/from the ringbuffer. Instead it just
accesses the ringbuffer memory directly. Notice how the consumer is
operating on the buffer instead of copying everything out?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk