forked from tidalcycles/Dirt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jobqueue.c
112 lines (83 loc) · 1.9 KB
/
jobqueue.c
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "jobqueue.h"
typedef struct {
job_t job;
void* next;
} entry_t;
struct jobqueue {
entry_t* head;
entry_t* tail;
unsigned int size;
pthread_mutex_t lock;
};
jobqueue_t* jobqueue_init() {
jobqueue_t* q = malloc(sizeof(jobqueue_t));
if (!q) return NULL;
q->head = NULL;
q->tail = NULL;
q->size = 0;
pthread_mutex_init(&q->lock, NULL);
return q;
}
bool jobqueue_push(jobqueue_t* q, job_t j) {
entry_t* e = malloc(sizeof(entry_t));
if (!e) return false;
e->job = j;
e->next = NULL;
pthread_mutex_lock(&q->lock);
if (q->head == NULL) {
q->head = e;
q->tail = e;
} else {
q->tail->next = e;
q->tail = e;
}
q->size++;
pthread_mutex_unlock(&q->lock);
return true;
}
bool jobqueue_is_empty(const jobqueue_t* q) {
return q->head == NULL;
}
job_t* jobqueue_top(jobqueue_t* q) {
pthread_mutex_lock(&q->lock);
assert(q->head != NULL);
job_t* top = &q->head->job;
pthread_mutex_unlock(&q->lock);
return top;
};
bool jobqueue_pop (jobqueue_t* q, job_t* j) {
pthread_mutex_lock(&q->lock);
if (q->head == NULL) {
pthread_mutex_unlock(&q->lock);
return false;
}
entry_t* top = q->head;
if (j) *j = top->job;
if (q->head == q->tail) {
q->head = q->tail = NULL;
} else {
q->head = q->head->next;
}
q->size--;
pthread_mutex_unlock(&q->lock);
free(top);
return true;
}
unsigned int jobqueue_size(const jobqueue_t* q) {
return q->size;
}
void jobqueue_destroy(jobqueue_t* q) {
pthread_mutex_lock(&q->lock);
entry_t* cur = q->head;
while (cur != NULL) {
entry_t* next = cur->next;
free(cur);
cur = next;
};
pthread_mutex_unlock(&q->lock);
pthread_mutex_destroy(&q->lock);
free(q);
}