Repository navigation
Expand file tree
/
Copy pathqueue.c
More file actions
110 lines (87 loc) · 2.71 KB
/
Copy pathqueue.c
File metadata and controls
110 lines (87 loc) · 2.71 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
103
104
105
106
107
108
109
110
#include "queue.h"
#include <stdlib.h>
#include <string.h>
#define MIN_QUEUE_SIZE 8
struct Queue* queue_init(size_t data_size){
if (data_size == 0) return NULL;
struct Queue *queue = malloc(sizeof(struct Queue));
if (queue == NULL) return NULL;
queue->queue = malloc(MIN_QUEUE_SIZE * data_size);
if (queue->queue == NULL){
free(queue);
return NULL;
}
queue->capacity = MIN_QUEUE_SIZE;
queue->size = 0;
queue->data_size = data_size;
queue->head = 0;
queue->tail = 0;
if (pthread_mutex_init(&queue->lock, NULL) != 0){
free(queue->queue);
free(queue);
return NULL;
}
return queue;
}
void queue_destroy(struct Queue *queue){
if (queue == NULL) return;
pthread_mutex_destroy(&queue->lock);
free(queue->queue);
free(queue);
}
int queue_push(struct Queue *queue,const void *data){
if (queue == NULL || data == NULL) return 1;
pthread_mutex_lock(&queue->lock);
if (queue->size == queue->capacity){
size_t old_capacity = queue->capacity;
size_t new_capacity = old_capacity * 2;
size_t old_bytes = old_capacity * queue->data_size;
char *new_queue = malloc(new_capacity * queue->data_size);
if (new_queue == NULL){
pthread_mutex_unlock(&queue->lock);
return 1;
}
for (size_t i = 0; i < queue->size; i++){
size_t offset = (queue->head + i * queue->data_size) % old_bytes;
memcpy(
new_queue + i * queue->data_size,
queue->queue + offset,
queue->data_size
);
}
free(queue->queue);
queue->queue = new_queue;
queue->capacity = new_capacity;
queue->head = 0;
queue->tail = queue->size * queue->data_size;
}
memcpy(queue->queue + queue->tail, data, queue->data_size);
queue->tail =
(queue->tail + queue->data_size) %
(queue->capacity * queue->data_size);
queue->size++;
pthread_mutex_unlock(&queue->lock);
return 0;
}
int queue_pop(struct Queue *queue,void *out){
if (queue == NULL || out == NULL) return 1;
pthread_mutex_lock(&queue->lock);
if (queue->size == 0){
pthread_mutex_unlock(&queue->lock);
return 1;
}
memcpy(out, queue->queue + queue->head, queue->data_size);
queue->head =
(queue->head + queue->data_size) %
(queue->capacity * queue->data_size);
queue->size--;
pthread_mutex_unlock(&queue->lock);
return 0;
}
int queue_is_empty(struct Queue *queue){
if (queue == NULL) return 1;
pthread_mutex_lock(&queue->lock);
int empty = queue->size == 0;
pthread_mutex_unlock(&queue->lock);
return empty;
}