Skip to content
Snippets Groups Projects
Commit 849c5f6e authored by Dana-Maria CĂRUNTU's avatar Dana-Maria CĂRUNTU
Browse files

add error checking to rb

parent f6046419
No related branches found
No related tags found
No related merge requests found
Pipeline #92469 passed
......@@ -7,28 +7,7 @@
#include "ring_buffer.h"
#include "utils.h"
int ring_buffer_init(so_ring_buffer_t *ring, size_t cap)
{
/* TODO: implement ring_buffer_init */
// (void) ring;
// (void) cap;
ring->data = (char *) malloc(cap);
DIE(ring->data == NULL, "malloc failed");
ring->cap = cap;
ring->read_pos = 0;
ring->write_pos = 0;
ring->len = 0;
ring->stop = 0;
int res = pthread_mutex_init(&ring->mutex, NULL);
// to do error handling
res = pthread_cond_init(&ring->not_empty, NULL);
res = pthread_cond_init(&ring->not_full, NULL);
return 0;
}
static size_t get_free_space(so_ring_buffer_t *ring)
static size_t get_free_space(const so_ring_buffer_t *ring)
{
return ring->cap - ring->len;
}
......@@ -42,57 +21,126 @@ static size_t adjust_position(size_t pos, size_t offset, size_t cap)
return new_pos;
}
static void copy_data_to_ring(so_ring_buffer_t *ring, const void *data, size_t size)
{
size_t space_at_end = ring->cap - ring->write_pos;
size_t first_part = (size > space_at_end) ? space_at_end : size;
size_t second_part = size - first_part;
memcpy(ring->data + ring->write_pos, data, first_part);
if (second_part > 0) {
memcpy(ring->data, (const char *)data + first_part, second_part);
}
}
static void copy_data_from_ring(so_ring_buffer_t *ring, void *data, size_t size)
{
size_t space_at_end = ring->cap - ring->read_pos;
size_t first_part = (size > space_at_end) ? space_at_end : size;
size_t second_part = size - first_part;
memcpy(data, ring->data + ring->read_pos, first_part);
if (second_part > 0) {
memcpy((char *)data + first_part, ring->data, second_part);
}
}
int ring_buffer_init(so_ring_buffer_t *ring, size_t cap)
{
ring->data = malloc(cap);
if (ring->data == NULL) {
DIE(1, "Memory allocation failed");
}
ring->cap = cap;
ring->len = 0;
ring->read_pos = 0;
ring->write_pos = 0;
ring->stop = 0;
int result = pthread_mutex_init(&ring->mutex, NULL);
if (result != 0) {
DIE(1, "Failed to initialize mutex");
}
result = pthread_cond_init(&ring->not_empty, NULL);
if (result != 0) {
DIE(1, "Failed to initialize not_empty condition");
}
result = pthread_cond_init(&ring->not_full, NULL);
if (result != 0) {
DIE(1, "Failed to initialize not_full condition");
}
return 0;
}
ssize_t ring_buffer_enqueue(so_ring_buffer_t *ring, void *data, size_t size)
{
/* TODO: implement ring_buffer_enqueue */
// (void) ring;
// (void) data;
// (void) size;
pthread_mutex_lock(&ring->mutex);
if (data == NULL) {
ERR(1, "Invalid data pointer");
return -1;
}
int result = pthread_mutex_lock(&ring->mutex);
if (result != 0) {
ERR(result != 0, "Failed to lock mutex");
return -1;
}
while (get_free_space(ring) < size && !ring->stop) {
pthread_cond_wait(&ring->not_full, &ring->mutex);
result = pthread_cond_wait(&ring->not_full, &ring->mutex);
if (result != 0) {
pthread_mutex_unlock(&ring->mutex);
ERR(result != 0, "Failed to wait on not_full condition");
return -1;
}
}
if (ring->stop) {
pthread_mutex_unlock(&ring->mutex);
return -1;
}
size_t space_at_end = ring->cap - ring->write_pos;
const char *src = (const char *)data;
char *dest = ring->data + ring->write_pos;
if (size <= space_at_end) {
memcpy(dest, src, size);
} else {
size_t first_part = space_at_end;
size_t second_part = size - space_at_end;
memcpy(dest, src, first_part);
memcpy(ring->data, src + first_part, second_part);
}
copy_data_to_ring(ring, data, size);
ring->write_pos = adjust_position(ring->write_pos, size, ring->cap);
ring->len += size;
pthread_cond_signal(&ring->not_empty);
pthread_mutex_unlock(&ring->mutex);
result = pthread_cond_signal(&ring->not_empty);
if (result != 0) {
ERR(result != 0, "Failed to signal not_empty condition");
}
return size;
result = pthread_mutex_unlock(&ring->mutex);
if (result != 0) {
ERR(result != 0, "Failed to unlock mutex");
}
// return -1;
return size;
}
ssize_t ring_buffer_dequeue(so_ring_buffer_t *ring, void *data, size_t size)
{
/* TODO: Implement ring_buffer_dequeue */
// (void) ring;
// (void) data;
// (void) size;
if (data == NULL) {
ERR(1, "Invalid data pointer");
return -1;
}
pthread_mutex_lock(&ring->mutex);
int result = pthread_mutex_lock(&ring->mutex);
if (result != 0) {
ERR(result != 0, "Failed to lock mutex");
return -1;
}
while (ring->len < size && !ring->stop) {
pthread_cond_wait(&ring->not_empty, &ring->mutex);
result = pthread_cond_wait(&ring->not_empty, &ring->mutex);
if (result != 0) {
pthread_mutex_unlock(&ring->mutex);
ERR(result != 0, "Failed to wait on not_empty condition");
return -1;
}
}
if (ring->stop && ring->len == 0) {
......@@ -100,51 +148,72 @@ ssize_t ring_buffer_dequeue(so_ring_buffer_t *ring, void *data, size_t size)
return 0;
}
size_t space_at_end = ring->cap - ring->read_pos;
char *dest = (char *)data;
const char *src = ring->data + ring->read_pos;
if (size <= space_at_end) {
memcpy(dest, src, size);
} else {
size_t first_part = space_at_end;
size_t second_part = size - space_at_end;
memcpy(dest, src, first_part);
memcpy(dest + first_part, ring->data, second_part);
}
copy_data_from_ring(ring, data, size);
ring->read_pos = adjust_position(ring->read_pos, size, ring->cap);
ring->len -= size;
pthread_cond_signal(&ring->not_full);
pthread_mutex_unlock(&ring->mutex);
result = pthread_cond_signal(&ring->not_full);
if (result != 0) {
ERR(result != 0, "Failed to signal not_full condition");
}
return size;
result = pthread_mutex_unlock(&ring->mutex);
if (result != 0) {
ERR(result != 0, "Failed to unlock mutex");
}
// return -1;
return size;
}
void ring_buffer_destroy(so_ring_buffer_t *ring)
{
/* TODO: Implement ring_buffer_destroy */
//(void) ring;
if (ring == NULL || ring->data == NULL) {
DIE(1, "Attempting to destroy an uninitialized ring buffer");
}
free(ring->data);
pthread_mutex_destroy(&ring->mutex);
// to do error handling
pthread_cond_destroy(&ring->not_empty);
pthread_cond_destroy(&ring->not_full);
int result = pthread_mutex_destroy(&ring->mutex);
if (result != 0) {
DIE(1, "Failed to destroy mutex");
}
result = pthread_cond_destroy(&ring->not_empty);
if (result != 0) {
DIE(1, "Failed to destroy not_empty condition");
}
result = pthread_cond_destroy(&ring->not_full);
if (result != 0) {
DIE(1, "Failed to destroy not_full condition");
}
}
void ring_buffer_stop(so_ring_buffer_t *ring)
{
/* TODO: Implement ring_buffer_stop */
// (void) ring;
pthread_mutex_lock(&ring->mutex);
void ring_buffer_stop(so_ring_buffer_t *ring) {
if (ring == NULL) {
DIE(1, "Attempting to stop an uninitialized ring buffer");
}
int result = pthread_mutex_lock(&ring->mutex);
if (result != 0) {
DIE(1, "Failed to lock mutex");
}
ring->stop = 1;
pthread_cond_broadcast(&ring->not_empty);
// to do error handling
pthread_cond_broadcast(&ring->not_full);
pthread_mutex_unlock(&ring->mutex);
}
result = pthread_cond_broadcast(&ring->not_empty);
if (result != 0) {
DIE(1, "Failed to broadcast not_empty condition");
}
result = pthread_cond_broadcast(&ring->not_full);
if (result != 0) {
DIE(1, "Failed to broadcast not_full condition");
}
result = pthread_mutex_unlock(&ring->mutex);
if (result != 0) {
DIE(1, "Failed to unlock mutex");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment