473,396 Members | 1,866 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

need ring buffer source code


Anyone have some efficient source code for implementing a ring buffer?
Nov 13 '05 #1
11 28850
Ben Collingsworth wrote:
Anyone have some efficient source code for implementing a ring buffer?


No doubt. But that's not we do here.
Try Google[1].

....and see the FAQ, at:

http://www.eskimo.com/~scs/C-faq/top.html

--ag

[1] or the search engine of your choice
--
Artie Gold -- Austin, Texas

Nov 13 '05 #2
In article <nn********************************@4ax.com>,
bd*************@cfl.rr.com says...

Anyone have some efficient source code for implementing a ring buffer?


Yes, I do.
--
Randy Howard _o
2reply remove FOOBAR \<,
______________________()/ ()______________________________________________
SCO Spam-magnet: po********@sco.com
Nov 13 '05 #3
Ben Collingsworth wrote:
Anyone have some efficient source code for implementing a ring buffer?


Yes, but it's in the source for the PDP-8 in the heart of BetaCom's
microfiche machine. You might write to Gould and ask permission to copy
it, assuming they haven't sold it to someone else. And its in Macro-8
assembler.

--
Martin Ambuhl

Nov 13 '05 #4
In article <nn********************************@4ax.com>,
bd*************@cfl.rr.com says...

Anyone have some efficient source code for implementing a ring buffer?


Yes, I do.
--
Randy Howard _o
2reply remove FOOBAR \<,
______________________()/ ()______________________________________________
SCO Spam-magnet: po********@sco.com
Nov 13 '05 #5
Ben Collingsworth wrote:
Anyone have some efficient source code for implementing a ring buffer?


Yes, but it's in the source for the PDP-8 in the heart of BetaCom's
microfiche machine. You might write to Gould and ask permission to copy
it, assuming they haven't sold it to someone else. And its in Macro-8
assembler.

--
Martin Ambuhl

Nov 13 '05 #6
On Thu, 04 Sep 2003 19:34:06 -0400, Ben Collingsworth
<bd*************@cfl.rr.com> wrote:

Anyone have some efficient source code for implementing a ring buffer?


There are several ways to implement a ring-buffer, depending on
how easy you want to make the tests for buffer empty/full. The
usual way I do it (without optimisations) is:

static unsigned char ringbuffer[ 256 ];
static unsigned short getindex = 0;
static unsigned short putindex = 0;
static unsigned short buffersize = 0;

int putring( char c )
{
if ( buffersize >= sizeof ringbuffer )
return -1;

ringbuffer[ putindex ] = c;
putindex++;
if ( putindex >= sizeof ringbuffer )
putindex = 0;
buffersize++;
return 0;
}

int getring( void )
{
if ( !buffersize )
return -1;
{
char c;

buffersize--;
c = ringbuffer[ getindex ];
getindex++;
if ( getindex >= sizeof ringbuffer )
getindex = 0;
return c;
}
}

Now, to make it faster.

If the size of the ring buffer is always a power-of-two you can
use masking to make the index variables wrap-around. For example
the increment and test for wrap-around becomes:

putindex = ( putindex++ ) & 0xFF;

If you have suitable compiler-extensions then force the start
address of the ring buffer to an alignment that is the same
as its size. That is for a 256-byte buffer it should be
aligned on a 256-byte boundary.

The indexing can then be replaced by pointers:

static char *putpointer = ringbuffer;

*putpointer = c;
putpointer = ( putpointer++ ) & ~0xFF;

Also there are functional efficiencies to consider, for example
the put function could discard the existing buffer contents if
the buffer overflows, this saves a test.

However I find that in real life programming ring buffers
can be considerable more entertaining. For example:

You may be part of a multi-tasking system where the task that
gets is different from the task that puts. The shared index
variables and buffer need to be defined as volatile and there
most likely need to be some kind of semaphore protection.

You want to get/put from within an interrupt handler. Potential
barrel of laughs that one.

Finally you may want to 'block' (i.e. do a non-looping wait)
on buffer full (put) or buffer empty (get). This is non-trivial
to get right, especially when using interrupts.

Nick.
Nov 13 '05 #7
ipo
Well, that ain't cool enough... I did mine in HTML
ipo

"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:Ra*************@newsread1.news.atl.earthlink. net...
Ben Collingsworth wrote:
Anyone have some efficient source code for implementing a ring buffer?


Yes, but it's in the source for the PDP-8 in the heart of BetaCom's
microfiche machine. You might write to Gould and ask permission to copy
it, assuming they haven't sold it to someone else. And its in Macro-8
assembler.

--
Martin Ambuhl

Nov 13 '05 #8
On Thu, 04 Sep 2003 19:34:06 -0400, Ben Collingsworth
<bd*************@cfl.rr.com> wrote:

Anyone have some efficient source code for implementing a ring buffer?


There are several ways to implement a ring-buffer, depending on
how easy you want to make the tests for buffer empty/full. The
usual way I do it (without optimisations) is:

static unsigned char ringbuffer[ 256 ];
static unsigned short getindex = 0;
static unsigned short putindex = 0;
static unsigned short buffersize = 0;

int putring( char c )
{
if ( buffersize >= sizeof ringbuffer )
return -1;

ringbuffer[ putindex ] = c;
putindex++;
if ( putindex >= sizeof ringbuffer )
putindex = 0;
buffersize++;
return 0;
}

int getring( void )
{
if ( !buffersize )
return -1;
{
char c;

buffersize--;
c = ringbuffer[ getindex ];
getindex++;
if ( getindex >= sizeof ringbuffer )
getindex = 0;
return c;
}
}

Now, to make it faster.

If the size of the ring buffer is always a power-of-two you can
use masking to make the index variables wrap-around. For example
the increment and test for wrap-around becomes:

putindex = ( putindex++ ) & 0xFF;

If you have suitable compiler-extensions then force the start
address of the ring buffer to an alignment that is the same
as its size. That is for a 256-byte buffer it should be
aligned on a 256-byte boundary.

The indexing can then be replaced by pointers:

static char *putpointer = ringbuffer;

*putpointer = c;
putpointer = ( putpointer++ ) & ~0xFF;

Also there are functional efficiencies to consider, for example
the put function could discard the existing buffer contents if
the buffer overflows, this saves a test.

However I find that in real life programming ring buffers
can be considerable more entertaining. For example:

You may be part of a multi-tasking system where the task that
gets is different from the task that puts. The shared index
variables and buffer need to be defined as volatile and there
most likely need to be some kind of semaphore protection.

You want to get/put from within an interrupt handler. Potential
barrel of laughs that one.

Finally you may want to 'block' (i.e. do a non-looping wait)
on buffer full (put) or buffer empty (get). This is non-trivial
to get right, especially when using interrupts.

Nick.
Nov 13 '05 #9
ipo
Well, that ain't cool enough... I did mine in HTML
ipo

"Martin Ambuhl" <ma*****@earthlink.net> wrote in message
news:Ra*************@newsread1.news.atl.earthlink. net...
Ben Collingsworth wrote:
Anyone have some efficient source code for implementing a ring buffer?


Yes, but it's in the source for the PDP-8 in the heart of BetaCom's
microfiche machine. You might write to Gould and ask permission to copy
it, assuming they haven't sold it to someone else. And its in Macro-8
assembler.

--
Martin Ambuhl

Nov 13 '05 #10
Nick Austin <ni**********@nildram.co.uk> wrote:
On Thu, 04 Sep 2003 19:34:06 -0400, Ben Collingsworth
<bd*************@cfl.rr.com> wrote:

Anyone have some efficient source code for implementing a ring buffer?
There are several ways to implement a ring-buffer, depending on
how easy you want to make the tests for buffer empty/full. The
usual way I do it (without optimisations) is:

static unsigned char ringbuffer[ 256 ];
static unsigned short getindex = 0;
static unsigned short putindex = 0;
static unsigned short buffersize = 0;

int putring( char c )
{
if ( buffersize >= sizeof ringbuffer )
return -1;

ringbuffer[ putindex ] = c;
putindex++;
if ( putindex >= sizeof ringbuffer )
putindex = 0;


Another way to write those two lines is

putindex = (putindex + 1) % sizeof ringbuffer;

[...]
Now, to make it faster.

If the size of the ring buffer is always a power-of-two you can
use masking to make the index variables wrap-around. For example
the increment and test for wrap-around becomes:

putindex = ( putindex++ ) & 0xFF;
That line has undefined behaviour - it modifies putindex twice without
an intervening sequence point. The correct way to write it is:

putindex = (putindex + 1) & 0xFF;

But it's worth noting that since putindex is unsigned, most compiler
will optimise:

putindex = (putindex + 1) % 256;

to use the bitwise mask, if that's more efficient on the target
hardware.
If you have suitable compiler-extensions then force the start
address of the ring buffer to an alignment that is the same
as its size. That is for a 256-byte buffer it should be
aligned on a 256-byte boundary.

The indexing can then be replaced by pointers:

static char *putpointer = ringbuffer;

*putpointer = c;
putpointer = ( putpointer++ ) & ~0xFF;


If we correct for the above-mentioned problem:

putpointer = (putpointer + 1) & ~0xFF;

then we still have the problem that in C, the bitwise-& operator doesn't
operate on pointer values. Correcting that with the necessary casts:

putpointer = (char *)((unsigned long)(putpointer + 1) & ~0xFF);

....and we have something with implmentation-defined behaviour. If,
however, we assume the common implementation of integer to pointer
conversions, where a pointer converted to an integer becomes a number
representing the offset pointed-to within the addressed segment, then we
have something that *still* doesn't work. That bitmask always zeroes
out the lower 8 bits - which will mean that putpointer will never
change.

Perhaps you meant something like:

putpointer = (char *)((unsigned long)ringbuffer |
((unsigned long)(putpointer + 1) & ~0xFF));

Which despite being fantastically ugly and implementation-defined, and
requiring that ringbuffer be aligned on a 256-byte boundary, is unlikely
to be any faster than the naive implementation - given that most CPUs
have indexed addressing modes.

- Kevin.

Nov 13 '05 #11
Nick Austin <ni**********@nildram.co.uk> wrote:
On Thu, 04 Sep 2003 19:34:06 -0400, Ben Collingsworth
<bd*************@cfl.rr.com> wrote:

Anyone have some efficient source code for implementing a ring buffer?
There are several ways to implement a ring-buffer, depending on
how easy you want to make the tests for buffer empty/full. The
usual way I do it (without optimisations) is:

static unsigned char ringbuffer[ 256 ];
static unsigned short getindex = 0;
static unsigned short putindex = 0;
static unsigned short buffersize = 0;

int putring( char c )
{
if ( buffersize >= sizeof ringbuffer )
return -1;

ringbuffer[ putindex ] = c;
putindex++;
if ( putindex >= sizeof ringbuffer )
putindex = 0;


Another way to write those two lines is

putindex = (putindex + 1) % sizeof ringbuffer;

[...]
Now, to make it faster.

If the size of the ring buffer is always a power-of-two you can
use masking to make the index variables wrap-around. For example
the increment and test for wrap-around becomes:

putindex = ( putindex++ ) & 0xFF;
That line has undefined behaviour - it modifies putindex twice without
an intervening sequence point. The correct way to write it is:

putindex = (putindex + 1) & 0xFF;

But it's worth noting that since putindex is unsigned, most compiler
will optimise:

putindex = (putindex + 1) % 256;

to use the bitwise mask, if that's more efficient on the target
hardware.
If you have suitable compiler-extensions then force the start
address of the ring buffer to an alignment that is the same
as its size. That is for a 256-byte buffer it should be
aligned on a 256-byte boundary.

The indexing can then be replaced by pointers:

static char *putpointer = ringbuffer;

*putpointer = c;
putpointer = ( putpointer++ ) & ~0xFF;


If we correct for the above-mentioned problem:

putpointer = (putpointer + 1) & ~0xFF;

then we still have the problem that in C, the bitwise-& operator doesn't
operate on pointer values. Correcting that with the necessary casts:

putpointer = (char *)((unsigned long)(putpointer + 1) & ~0xFF);

....and we have something with implmentation-defined behaviour. If,
however, we assume the common implementation of integer to pointer
conversions, where a pointer converted to an integer becomes a number
representing the offset pointed-to within the addressed segment, then we
have something that *still* doesn't work. That bitmask always zeroes
out the lower 8 bits - which will mean that putpointer will never
change.

Perhaps you meant something like:

putpointer = (char *)((unsigned long)ringbuffer |
((unsigned long)(putpointer + 1) & ~0xFF));

Which despite being fantastically ugly and implementation-defined, and
requiring that ringbuffer be aligned on a 256-byte boundary, is unlikely
to be any faster than the naive implementation - given that most CPUs
have indexed addressing modes.

- Kevin.

Nov 13 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Tom Leylan | last post by:
Are we past the point when we need to print source code? I'm having two problems. The most important one is that opening a .vb file and simply printing it _does_ print the source but code...
3
by: Stefan Behnel | last post by:
Hi! I need to generate source code (mainly Java) from a domain specific XML language, preferably from within a Python environment (since that's where the XML is generated). I tried using...
1
by: shun | last post by:
Hello, I am going to design employee attendance regiter using ASP.NET, to track the employees login time, logout time with date, i.e user when access the site it asks for login details (user...
2
by: sant | last post by:
hi everybody i have a strong need of c source code of RSA. kindly give me link where i can get it with proper supporting tools/libraries. kindly mail me at yash_ju@hotmail.com regrads
1
by: Vinay Patel | last post by:
hi every one i need project with source code for virus scanner plz any one can help me in this case
9
by: indujana | last post by:
i want the source code in java to retrive a word from a file which has more than 50,000 words.The file is named as "english.0" which contains most of the words in english which i am using as a...
3
by: dolphin | last post by:
I am doing a homework about rsa.I need a rsa1024 source code.Where I can find it.
2
by: zahit | last post by:
hello everyone, i have to submit an assignment urgently. this experiment is about voronoi cells, program will take "input.txt" from command line and output to a JFrame, we shouldn't use applet class...
1
by: julienzz | last post by:
Hello, i surfed the net all day long, and i haven't found anythin that could help me, i'm making a program that sends data by e-mail, client side, i have found some shareware programs, but i need a...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.