-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.c
129 lines (107 loc) · 2.43 KB
/
queue.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* queue.c
*
* Created on: 17 Sep 2017
* Author: Bibl
*/
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "queue.h"
inline void queue_lock(queue_ptr qp) {
// printf("%p\n", queue->mutex);
#if SHOULD_SYNC
pthread_mutex_lock(qp->mutex);
#endif
}
inline void queue_unlock(queue_ptr p) {
#if SHOULD_SYNC
pthread_mutex_unlock(p->mutex);
#endif
}
queue_ptr new_fifo_queue() {
queue_ptr q = malloc(sizeof(struct queue));
memset(q, 0, sizeof(struct queue));
#if SHOULD_SYNC
q->mutex = malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(q->mutex, NULL);
#endif
return q;
}
void free_queue(queue_ptr q) {
#if SHOULD_SYNC
pthread_mutex_destroy(q->mutex);
free(q->mutex);
#endif
struct queue_node *cur = q->queue_head;
while(cur) {
struct queue_node *next = cur->next;
free(cur);
cur = next;
}
free(q);
}
/* return 0 for failure
* else returns a non zero value. */
int queue_push(queue_ptr q, generic_data_ptr data) {
struct queue_node *new_node = malloc(sizeof(struct queue_node));
if(!new_node) {
return 0;
}
queue_lock(q);
new_node->next = 0;
new_node->data = data;
if(q->queue_head) {
/* append to tail and set the new tail */
q->queue_tail->next = new_node;
q->queue_tail = new_node;
} else {
/* empty queue */
q->queue_head = q->queue_tail = new_node;
}
queue_unlock(q);
return 1;
}
/* return NULL if there are no pending
* items in the queue, else a pointer
* to the data. */
generic_data_ptr queue_pop(queue_ptr q) {
queue_lock(q);
if(q->queue_head) {
queue_node_ptr old_head = q->queue_head;
/* 1. store the old head.
* 2. store the data from the old head.
* 3. set the head to the next node.
* 4. return the data. */
generic_data_ptr data = old_head->data;
q->queue_head = old_head->next;
free(old_head);
queue_unlock(q);
return data;
} else {
/* empty queue */
queue_unlock(q);
return 0;
}
}
/* returns a non zero integer if there
* are any items in the queue, else
* returns 0. */
int queue_has_pending(queue_ptr queue) {
int ret;
queue_lock(queue);
ret = queue->queue_head ? 1 : 0;
queue_unlock(queue);
return ret;
}
int queue_get_size(queue_ptr queue) {
queue_lock(queue);
int len = 0;
queue_node_ptr cur = queue->queue_head;
while(cur) {
len++;
cur = cur->next;
}
queue_unlock(queue);
return len;
}