Skip to content

Instantly share code, notes, and snippets.

@wolfspider
Created November 29, 2024 05:10
Show Gist options
  • Save wolfspider/24811c15179706c72726f2af88441473 to your computer and use it in GitHub Desktop.
Save wolfspider/24811c15179706c72726f2af88441473 to your computer and use it in GitHub Desktop.
Formal RingBuffer 2: Synchronicity
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct t__int32_t_s
{
int32_t *b;
uint32_t *first;
uint32_t *length;
uint32_t total_length;
bool lock;
}
t__int32_t;
uint32_t next(uint32_t i, uint32_t total_length)
{
if (i == total_length - 1U)
return 0U;
else
return i + 1U;
}
uint32_t prev(uint32_t i, uint32_t total_length)
{
if (i > 0U)
return i - 1U;
else
return total_length - 1U;
}
uint32_t one_past_last(uint32_t i, uint32_t length, uint32_t total_length)
{
if (length == total_length)
return i;
else if (i >= total_length - length)
return length - (total_length - i);
else
return i + length;
}
void push__int32_t(t__int32_t *x, int32_t e)
{
uint32_t dest_slot = prev(*x->first, x->total_length);
x->b[dest_slot] = e;
*x->first = dest_slot;
*x->length = *x->length + 1U;
}
void push_end__int32_t(t__int32_t *x, int32_t e)
{
if(*x->first == 0) {
// Print buffer state when it wraps around
if(x->lock == true)
{
printf("Lock acquired overwriting init...\n");
x->lock = false;
}
else
{
printf("Buffer full. Current state before overwriting:\n");
for (uint32_t i = 0; i < x->total_length; ++i)
{
printf("%d ", x->b[i]);
}
printf("\n");
}
}
uint32_t o = one_past_last(*x->first, *x->length, x->total_length);
x->b[o] = e;
*x->first = next(*x->first, x->total_length);
}
void push_cont__int32_t(t__int32_t *x, int32_t e)
{
if (*x->length < x->total_length)
push__int32_t(x, e);
else
push_end__int32_t(x, e);
}
int32_t pop__int32_t(t__int32_t x)
{
int32_t e = x.b[*x.first];
*x.first = next(*x.first, x.total_length);
*x.length = *x.length - 1U;
return e;
}
int32_t main(void)
{
int32_t b[3U];
for (uint32_t _i = 0U; _i < 3U; ++_i)
b[_i] = (int32_t)1;
uint32_t buf0 = 0U;
uint32_t buf = 0U;
t__int32_t rb = { .b = b, .first = &buf0, .length = &buf, .total_length = 3U, .lock = true };
for (uint32_t _i = 0U; _i < rb.total_length; ++_i)
push_cont__int32_t(&rb, (int32_t)0);
for (uint32_t _i = 0U; _i < 14U; ++_i)
push_cont__int32_t(&rb, (int32_t)_i * 10 + 1);
printf("Buffer pushed 14 times. Current state:\n");
for (uint32_t i = 0; i < rb.total_length; ++i)
{
printf("%d ", rb.b[i]);
}
printf("\n");
printf("Pop back through elements:\n");
int32_t r = pop__int32_t(rb);
printf("pop: %d\n", r);
int32_t r1 = pop__int32_t(rb);
printf("pop: %d\n", r1);
int32_t r2 = pop__int32_t(rb);
printf("pop: %d\n", r2);
int32_t r3 = pop__int32_t(rb);
printf("pop: %d\n", r3);
return r3;
}
@wolfspider
Copy link
Author

For the next section its back to the drawing board to re-implement this for more speed and accuracy. We've got a rough sketch so far for what we want and this will help with the low level stuff. We also have found some interesting techniques to keep us out of the danger zone in C. Managing pointers will become all too relevant soon enough.

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