Consider this simplified ring buffer read function for UART data. What will be the returned value when ring_buffer_read() is called?
typedef struct {
unsigned char buffer[4];
unsigned int head;
unsigned int tail;
} RingBuffer;
RingBuffer rb = {{'A', 'B', 'C', 'D'}, 2, 0};
unsigned char ring_buffer_read(RingBuffer *rb) {
if (rb->head == rb->tail) {
return 0; // Buffer empty
}
unsigned char data = rb->buffer[rb->tail];
rb->tail = (rb->tail + 1) % 4;
return data;
}
int main() {
unsigned char c = ring_buffer_read(&rb);
printf("%c", c);
return 0;
}Remember that tail points to the next byte to read.
The tail is at 0, so the first byte read is buffer[0] which is 'A'.
Given the same ring buffer as before, what is the value of rb.tail after calling ring_buffer_read(&rb) once?
typedef struct {
unsigned char buffer[4];
unsigned int head;
unsigned int tail;
} RingBuffer;
RingBuffer rb = {{'A', 'B', 'C', 'D'}, 2, 0};
unsigned char ring_buffer_read(RingBuffer *rb) {
if (rb->head == rb->tail) {
return 0; // Buffer empty
}
unsigned char data = rb->buffer[rb->tail];
rb->tail = (rb->tail + 1) % 4;
return data;
}
int main() {
ring_buffer_read(&rb);
printf("%u", rb.tail);
return 0;
}Tail moves forward by one position modulo buffer size.
Tail was 0, after reading one byte it becomes (0 + 1) % 4 = 1.
What will ring_buffer_read() return if rb.head equals rb.tail?
typedef struct {
unsigned char buffer[4];
unsigned int head;
unsigned int tail;
} RingBuffer;
unsigned char ring_buffer_read(RingBuffer *rb) {
if (rb->head == rb->tail) {
return 0; // Buffer empty
}
unsigned char data = rb->buffer[rb->tail];
rb->tail = (rb->tail + 1) % 4;
return data;
}
int main() {
RingBuffer rb = {{'A', 'B', 'C', 'D'}, 1, 1};
unsigned char c = ring_buffer_read(&rb);
printf("%d", c);
return 0;
}When head equals tail, the buffer is empty.
The function returns 0 to indicate the buffer is empty.
Given this code that writes a byte then reads one, what is printed?
typedef struct {
unsigned char buffer[4];
unsigned int head;
unsigned int tail;
} RingBuffer;
void ring_buffer_write(RingBuffer *rb, unsigned char data) {
rb->buffer[rb->head] = data;
rb->head = (rb->head + 1) % 4;
}
unsigned char ring_buffer_read(RingBuffer *rb) {
if (rb->head == rb->tail) {
return 0;
}
unsigned char data = rb->buffer[rb->tail];
rb->tail = (rb->tail + 1) % 4;
return data;
}
int main() {
RingBuffer rb = {{0}, 0, 0};
ring_buffer_write(&rb, 'X');
unsigned char c = ring_buffer_read(&rb);
printf("%c", c);
return 0;
}Write adds 'X' at head, then read returns from tail.
Write puts 'X' at buffer[0], head moves to 1. Read returns buffer[0] which is 'X'.
Given a ring buffer of size 4, what is the maximum number of bytes it can hold before it appears full (head catches tail)?
typedef struct {
unsigned char buffer[4];
unsigned int head;
unsigned int tail;
} RingBuffer;One slot is left empty to distinguish full from empty.
To avoid confusion between full and empty, one slot remains unused, so max is size - 1 = 3.