Skip to content

Instantly share code, notes, and snippets.

@pcewing
Created June 18, 2020 01:19
Show Gist options
  • Select an option

  • Save pcewing/acc87f68c5352e3789aca1e3564ddc20 to your computer and use it in GitHub Desktop.

Select an option

Save pcewing/acc87f68c5352e3789aca1e3564ddc20 to your computer and use it in GitHub Desktop.

Revisions

  1. pcewing created this gist Jun 18, 2020.
    38 changes: 38 additions & 0 deletions main.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    #include "queue.h"
    #include <stdio.h>

    #define UNUSED(x) ((void)(x))

    void string_print_callback(void *item) {
    const char *str = item;
    printf("%s", str);
    }

    void int_print_callback(void *item) {
    int *i = item;
    printf("%i", *i);
    }

    int main(int argc, char *argv[]) {
    UNUSED(argc);
    UNUSED(argv);

    int a = 1;
    int b = 2;
    int c = 3;
    struct queue_t *queue = queue_new(sizeof(int));
    queue_enqueue(queue, &a);
    queue_enqueue(queue, &b);
    queue_enqueue(queue, &c);
    queue_print(queue, int_print_callback);

    int d;
    for (int i = 0; i < 4; ++i) {
    if (queue_dequeue(queue, &d))
    printf("Dequeued: %i\n", d);
    else
    printf("Nothing to dequeue\n");
    }

    return 0;
    }
    11 changes: 11 additions & 0 deletions meson.build
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    project('queue', 'c')

    executable(
    'queue_test',
    [
    'main.c',
    'queue.c',
    ],
    dependencies : [
    dependency('threads'),
    ])
    120 changes: 120 additions & 0 deletions queue.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,120 @@
    #include "queue.h"
    #include <pthread.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>

    struct queue_node_t {
    void *data;
    struct queue_node_t *next;
    };

    struct queue_t {
    struct queue_node_t *head;
    struct queue_node_t *tail;
    size_t item_size;
    size_t size;

    pthread_mutex_t lock;
    };

    struct queue_node_t *queue_node_new(size_t item_size, void *item) {
    struct queue_node_t *queue_node = malloc(sizeof(struct queue_node_t));
    if (!queue_node)
    return NULL;

    memset(queue_node, 0, sizeof(struct queue_node_t));

    queue_node->data = malloc(item_size);
    if (!queue_node->data) {
    free(queue_node);
    return NULL;
    }

    memcpy(queue_node->data, item, item_size);

    return queue_node;
    }

    void queue_node_free(struct queue_node_t *queue_node) {
    free(queue_node);
    }

    struct queue_t *queue_new(size_t item_size) {
    struct queue_t *queue = malloc(sizeof(struct queue_t));
    memset(queue, 0, sizeof(struct queue_t));

    if (queue) {
    queue->item_size = item_size;
    pthread_mutex_init(&queue->lock, NULL);
    }

    return queue;
    }

    void queue_free(struct queue_t *queue) {
    pthread_mutex_destroy(&queue->lock);
    free(queue);
    }

    bool queue_enqueue(struct queue_t *queue, void *item) {
    bool result = true;

    pthread_mutex_lock(&queue->lock);

    struct queue_node_t *new_node = queue_node_new(queue->item_size, item);
    if (new_node) {
    if (queue->size == 0)
    queue->head = queue->tail = new_node;
    else
    queue->tail = queue->tail->next = new_node;
    ++queue->size;
    } else {
    result = false;
    }

    pthread_mutex_unlock(&queue->lock);

    return result;
    }

    bool queue_dequeue(struct queue_t *queue, void *item) {
    bool result = true;

    pthread_mutex_lock(&queue->lock);

    if (queue->size == 0) {
    result = false;
    } else {
    memcpy(item, queue->head->data, queue->item_size);
    struct queue_node_t *temp = queue->head;
    queue->head = queue->head->next;
    queue_node_free(temp);
    --queue->size;
    }

    pthread_mutex_unlock(&queue->lock);

    return result;
    }

    void queue_print(struct queue_t *queue, print_callback p) {
    pthread_mutex_lock(&queue->lock);

    printf("[ ");
    struct queue_node_t *itr = queue->head;
    while (itr) {
    p(itr->data);

    if (itr->next)
    printf(", ");

    itr = itr->next;
    }
    printf(" ]\n");

    pthread_mutex_unlock(&queue->lock);
    }
    15 changes: 15 additions & 0 deletions queue.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    #pragma once

    #include <stdbool.h>
    #include <stddef.h>

    struct queue_t;

    struct queue_t *queue_new(size_t item_size);
    void queue_free(struct queue_t *queue);
    bool queue_enqueue(struct queue_t *queue, void *item);
    bool queue_dequeue(struct queue_t *queue, void *item);

    // For debugging purposes
    typedef void(*print_callback)(void *item);
    void queue_print(struct queue_t *queue, print_callback p);