Skip to content

Instantly share code, notes, and snippets.

@mcejp
Created December 6, 2023 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcejp/719d3485b04cfcf82e8a8734957da06a to your computer and use it in GitHub Desktop.
Save mcejp/719d3485b04cfcf82e8a8734957da06a to your computer and use it in GitHub Desktop.
Ring buffer with Array + two indices mod 2N
// Background: https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
// Variant with indices modulo 2*capacity as suggested by dizzy57 and Aristotle Pagaltzis
size_t read;
size_t write;
mask(val) { return val % array.capacity; }
wrap(val) { return val % (array.capacity * 2); }
inc(index) { return wrap(index + 1); }
push(val) { assert(!full()); array[mask(write)] = val; write = inc(write); }
shift() { assert(!empty()); ret = array[mask(read)]; read = inc(read); return ret; }
empty() { return read == write; }
full() { return size() == array.capacity; }
size() { return wrap(write - read); }
free() { return array.capacity - size(); }
// Additional operations
read(data_out, count) {
count = min(count, size());
run = min(count, array.capacity - mask(read));
rem = count - run;
memcpy(data_out, array + mask(read), run);
memcpy(data_out + run, array, rem);
read = wrap(read + count);
return count;
}
write(data, count) {
count = min(count, array.capacity - size());
run = min(count, array.capacity - mask(write));
rem = count - run;
memcpy(array + mask(write), data, run);
memcpy(array, data + run, rem);
write = wrap(write + count);
return count;
}
@HiFiPhile
Copy link

I think size() should be { return mask(write - read); }

@mcejp
Copy link
Author

mcejp commented Mar 30, 2024

I think size() should be { return mask(write - read); }

@HiFiPhile nope, that's why you do mod 2N in the first place, this way you could never arrive to size() == capacity()

@HiFiPhile
Copy link

HiFiPhile commented Mar 30, 2024

Sorry I worked on an overwritable FIFO when the situation is more complicated, I must have mingled things....
https://github.com/hathach/tinyusb/blob/master/src/common/tusb_fifo.h

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment