-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue.c
More file actions
102 lines (81 loc) · 2.46 KB
/
Copy pathqueue.c
File metadata and controls
102 lines (81 loc) · 2.46 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
#include "queue.h" //quotes for own directory files
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct queue {
pthread_mutex_t mutex;
pthread_cond_t cond_notFull; // wait until queue is not full
pthread_cond_t cond_notEmpty;
void** buffer; // Array of void pointers
int front;
int rear;
int size; // size of array
int count; // Items existing in Array
};
// Queue Constructor
queue_t* queue_new(int size)
{
struct queue* q_pntr = malloc(sizeof(struct queue));
pthread_mutex_init(&q_pntr->mutex, NULL);
pthread_cond_init(&q_pntr->cond_notEmpty, NULL);
pthread_cond_init(&q_pntr->cond_notFull, NULL);
q_pntr->buffer = malloc(size * sizeof(void*));
q_pntr->front = 0;
q_pntr->rear = 0;
q_pntr->count = 0;
q_pntr->size = size;
return q_pntr;
}
// Queue Destructor
void queue_delete(queue_t** q)
{
if (q == NULL || *q == NULL) {
return;
}
pthread_mutex_destroy(&(*q)->mutex);
pthread_cond_destroy(&(*q)->cond_notEmpty);
pthread_cond_destroy(&(*q)->cond_notFull);
free((*q)->buffer);
free(*q);
*q = NULL;
return;
}
// Push item to queue FIFO
bool queue_push(queue_t* q, void* elem)
{
// check if rear == front
if (q == NULL) {
return false;
}
pthread_mutex_lock(&q->mutex); // aquire lock, only one thread at a time
while (q->count == q->size) { // wait while full
pthread_cond_wait(&q->cond_notFull, &q->mutex); // wait until queue is not full
}
//! crit section!
q->buffer[q->rear] = elem; // push item to next rear position
q->rear = ((q->rear) + 1) % (q->size); // Cycle around to beginning when full
q->count += 1; // increase count
pthread_cond_signal(&q->cond_notEmpty); // signal back
pthread_mutex_unlock(&q->mutex);
// block if the queue is full
return true;
}
// Push item out of queue
bool queue_pop(queue_t* q, void** elem)
{
if (q == NULL) {
return false;
}
pthread_mutex_lock(&q->mutex);
while (q->count == 0) { // wait while not full
pthread_cond_wait(&q->cond_notEmpty, &q->mutex); // Wait umtil queue is full
}
// crit section
*elem = q->buffer[q->front];
q->front = ((q->front) + 1) % (q->size); // Cycle around to beginning when full
q->count -= 1; // decrease count
pthread_cond_signal(&q->cond_notFull); // signal notFull to wait
pthread_mutex_unlock(&q->mutex);
// block if the queue is empty.
return true;
}