-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue.h
More file actions
102 lines (90 loc) · 5.7 KB
/
queue.h
File metadata and controls
102 lines (90 loc) · 5.7 KB
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
// From https://github.com/alxyng/queue/blob/master/src/queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
void *front;
void *back;
void *backqh;
unsigned int size;
} queue_core;
typedef struct queue_handle {
queue_core *qc;
void *next;
} queue_handle;
#define QUEUE_INIT(qt, q) \
do { \
queue_core *qc; \
(q) = malloc(sizeof(qt)); \
if (q) { \
(q)->qh.qc = malloc(sizeof(queue_core)); \
if ((q)->qh.qc) { \
qc = (q)->qh.qc; \
pthread_mutex_init(&qc->mutex, NULL); \
pthread_cond_init(&qc->cond, NULL); \
qc->front = qc->back = NULL; \
qc->backqh = NULL; \
qc->size = 0; \
(q)->qh.next = NULL; \
} else { \
free(q); \
(q) = NULL; \
} \
} \
} while (false)
#define QUEUE_PUSH(q, e) \
do { \
queue_core *qc; \
queue_handle *backqh; \
qc = (q)->qh.qc; \
pthread_mutex_lock(&qc->mutex); \
(e)->qh.qc = qc; \
(e)->qh.next = NULL; \
backqh = qc->backqh; \
if (!qc->front) { \
qc->front = qc->back = (e); \
} else { \
backqh->next = (e); \
qc->back = (e); \
} \
backqh = &((e)->qh); \
qc->backqh = backqh; \
qc->size++; \
pthread_mutex_unlock(&qc->mutex); \
pthread_cond_signal(&qc->cond); \
} while (false)
#define QUEUE_POP(q, e) \
do { \
queue_core *qc; \
(e) = NULL; \
qc = (q)->qh.qc; \
pthread_mutex_lock(&qc->mutex); \
while (QUEUE_SIZE(q) == 0) { \
pthread_cond_wait(&qc->cond, &qc->mutex); \
} \
if ((q)->qh.qc->front != NULL) { \
(e) = (q)->qh.qc->front; \
(q)->qh.qc->front = (e)->qh.next; \
(q)->qh.qc->size--; \
} \
pthread_mutex_unlock(&qc->mutex); \
} while (false)
#define QUEUE_LOCK(q) pthread_mutex_lock(&q->qh.qc->mutex);
#define QUEUE_SIZE(q) ((q)->qh.qc->size)
#define QUEUE_UNLOCK(q) pthread_mutex_unlock(&q->qh.qc->mutex);
#define QUEUE_FREE(q) \
do { \
queue_core *qc; \
if ((q) && (q)->qh.qc) { \
qc = (q)->qh.qc; \
pthread_cond_destroy(&qc->cond); \
pthread_mutex_destroy(&qc->mutex); \
free(qc); \
free(q); \
} \
} while (false)
#endif /* QUEUE_H */