summaryrefslogtreecommitdiff
path: root/queue.c
blob: 18530f3a773d8dd475d09697045a7acdbce08266 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <semaphore.h>
#include <pthread.h>
#include <assert.h>

#include "debug.h"

#include "queue.h"

int init_queue(queue *q) {
    int i;
    sem_init(&q->size, 0, 0);
    pthread_mutex_init(&q->mtx, NULL);
    q->front = 0;
    q->back = 0;
    for (i = 0; i < 100; ++i) {
        q->elements[i] = NULL;
    }
    debug(("initialised queue %p\n", (void *) q));

    return 0;
}

int enqueue(queue *q, void *v) {
    pthread_mutex_lock(&q->mtx);

    q->elements[q->front] = v;
    q->front = (q->front + 1) % 100;

    debug(("%p enqueued in %p\n", v, (void *) q));

    sem_post(&q->size);
    pthread_mutex_unlock(&q->mtx);
    return 0;
}

int dequeue(queue *q, void **v) {
    int result;

    sem_wait(&q->size);
    pthread_mutex_lock(&q->mtx);

    if (q->back == q->front) {
        sem_post(&q->size);
        result = 1;

        debug(("found %p to be closed\n", (void *) q));
    } else {
        *v = q->elements[q->back];
        q->back = (q->back + 1) % 100;
        result = 0;

        debug(("%p dequeued from %p\n", *v, (void *) q));
    }

    pthread_mutex_unlock(&q->mtx);
    return result;
}

int pq_close(queue *q) {
    sem_post(&q->size);
    debug(("%p closed\n", (void *) q));
    return 0;
}