Skip to content

Commit

Permalink
Initial queue implementation ref #13
Browse files Browse the repository at this point in the history
  • Loading branch information
joexbayer committed Nov 24, 2024
1 parent b5f6d58 commit 6eb862b
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
33 changes: 33 additions & 0 deletions include/queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef QUEUE_H
#define QUEUE_H

#include <stdint.h>
#include <pthread.h>

typedef enum queue_status {
QUEUE_OK,
QUEUE_FULL,
QUEUE_EMPTY,
QUEUE_ERROR
} queue_status_t;

struct queue {
void **buffer;
size_t head;
size_t tail;
size_t max_size;
size_t current_size;
pthread_mutex_t lock;
pthread_cond_t not_full;
pthread_cond_t not_empty;
};

struct queue* queue_create(size_t max_size);
void queue_destroy(struct queue* q);
queue_status_t queue_enqueue(struct queue* q, void* item);
queue_status_t queue_dequeue(struct queue* q, void** item);
size_t queue_size(struct queue* q);



#endif // QUEUE_H
77 changes: 77 additions & 0 deletions src/queue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <queue.h>
#include <stdlib.h>
#include <stdio.h>

struct queue* queue_create(size_t max_size) {
struct queue* q = (struct queue*)malloc(sizeof(struct queue));
if (q == NULL) {
return NULL;
}

q->buffer = (void**)malloc(max_size * sizeof(void*));
if (q->buffer == NULL) {
free(q);
return NULL;
}

/* Initialize queue */
q->head = 0;
q->tail = 0;
q->max_size = max_size;
q->current_size = 0;

/* Initialize mutex and condition variables */
pthread_mutex_init(&q->lock, NULL);
pthread_cond_init(&q->not_full, NULL);
pthread_cond_init(&q->not_empty, NULL);
return q;
}

void queue_destroy(struct queue* q) {
pthread_mutex_destroy(&q->lock);
pthread_cond_destroy(&q->not_full);
pthread_cond_destroy(&q->not_empty);
free(q->buffer);
free(q);
}

queue_status_t queue_enqueue(struct queue* q, void* item) {
pthread_mutex_lock(&q->lock);

/* Wait until queue is not full */
while (q->current_size == q->max_size) {
pthread_cond_wait(&q->not_full, &q->lock);
}

/* Enqueue item at tail and move pointer */
q->buffer[q->tail] = item;
q->tail = (q->tail + 1) % q->max_size;
q->current_size++;

pthread_cond_signal(&q->not_empty);
pthread_mutex_unlock(&q->lock);
return QUEUE_OK;
}

queue_status_t queue_dequeue(struct queue* q, void** item) {
pthread_mutex_lock(&q->lock);
while (q->current_size == 0) {
pthread_cond_wait(&q->not_empty, &q->lock);
}

/* Dequeue item at head and move pointer */
*item = q->buffer[q->head];
q->head = (q->head + 1) % q->max_size;
q->current_size--;

pthread_cond_signal(&q->not_full);
pthread_mutex_unlock(&q->lock);
return QUEUE_OK;
}

size_t queue_size(struct queue* q) {
pthread_mutex_lock(&q->lock);
size_t size = q->current_size;
pthread_mutex_unlock(&q->lock);
return size;
}

0 comments on commit 6eb862b

Please sign in to comment.