-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue.c
More file actions
234 lines (206 loc) · 5.76 KB
/
queue.c
File metadata and controls
234 lines (206 loc) · 5.76 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/***********************************************************************
* FILENAME: queue.c
*
* DESCRIPTION:
* This is the file that contains the structure of the queue and
* queue pointer. It also has all method the pertain to
* manipulating the queue.
*
* AUTHORS: Matthew Derzay, CS Login: derzay
* Ian Mark, CS Login: imark
*
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
/**
* This is the structure of queue. It contains mutex and condition varaibles for
* syncronization and various ints for stat keeping. It also keeps an array of
* string as the queue idea.
*/
typedef struct Queue {
//Number of strings enqueued.
int enqueueCount;
//Number of strings dequeued.
int dequeueCount;
//Number of times the thread was blocked from enqueuing.
int enqueueBlockCount;
//Number of times the thread was blocked from dequeuing.
int dequeueBlockCount;
//Front of the queue.
int front;
//Back of the queue.
int back;
//Total strings in the queue.
int curAmount;
//Max amount of string in the queue.
int capacity;
//Array of strings.
char** strings;
//Monitor lock for syncronization.
pthread_mutex_t lock;
//Condition variables for blocking.
pthread_cond_t empty;
pthread_cond_t full;
}Queue;
/**
* This is the constructor of a queue.
*
* Parameters: size - The size of the queue.
*
* Return: Queue - The newly created queue.
*/
Queue *CreateStringQueue(int size) {
//Error return value.
int r;
//New queue being created.
Queue *Q;
//Allocating memory for the queue.
Q = (Queue*)malloc(sizeof(Queue));
//Allocating memeory for the string array.
Q->strings = malloc(sizeof(char*) * size);
//Setting max size to parameter value.
Q->capacity = size;
//Initializing all values in queue to 0;
Q->front = 0;
Q->back = 0;
Q->curAmount = 0;
Q->enqueueCount = 0;
Q->dequeueCount = 0;
Q->enqueueBlockCount = 0;
Q->dequeueBlockCount = 0;
//Initialize the mutex lock.
r = pthread_mutex_init(&Q->lock, NULL);
if (r != 0) {
perror("Error: Mutex Initialization.");
exit(0);
}
//Initialize the two condition variables.
r = pthread_cond_init(&Q->empty, NULL);
if (r != 0) {
perror("Error: Condition Variable Initialization.");
exit(0);
}
r = pthread_cond_init(&Q->full, NULL);
if (r != 0) {
perror("Error: Condition Variable Initialization.");
exit(0);
}
return Q;
}
/**
* The structure of the queue pointer. This struct contains two
* pointers to queues.
*/
typedef struct QueuePointer {
Queue* q1;
Queue* q2;
}QueuePointer;
/**
* This is the constructor of a queue pointer.
*
* Parameters: cuQ, nextQ - The two queuees to be added to the pointer.
*
* Return: QueuePointer - The newly creatd queuePointer.
*/
QueuePointer *CreateStringQueuePointer(Queue* curQ, Queue* nextQ) {
//New queuepointer.
QueuePointer* QP;
//Allocate memory for the queue pointer.
QP = (QueuePointer*)malloc(sizeof(QueuePointer));
//Set the elements of the queue pointer to the two queues.
QP->q1 = curQ;
QP->q2 = nextQ;
return QP;
}
// function to print out a queue
void printQueue(Queue* q) {
for (int i =0; i < 10; i ++) {
if(q->strings[i] == NULL) { printf("%i: No string\n", i);}
else {
printf("%i: %s\n", i , q->strings[i]);
}
printf("\n");
}
}
/**
* This method takes a string and puts it into a queue in the next space
* that is open.
*
* Parameters: q - The queue for the enqueue.
* string - the string to be enqueued.
*/
void EnqueueString(Queue *q, char *string) {
//Lock the resouce of queue.
pthread_mutex_lock(&q->lock);
//If the queue is full, block until not full.
if(q->capacity == q->curAmount) {
//Block enqueue.
pthread_cond_wait(&q->full, &q->lock);
q->enqueueBlockCount++;
}
//Set string to the next open space.
q->strings[q->back] = string;
if(q->back + 1 == q->capacity) {
q->back = 0;
}else{
q->back++;
}
q->curAmount++;
//If the string is the final null pointer don't count as enqueue.
if(string != NULL) {
q->enqueueCount++;
}
//Unlock and signal dequeue.
pthread_cond_signal(&q->empty);
pthread_mutex_unlock(&q->lock);
}
/**
* This method takes a string off the queue given and returns it.
*
* Parameters: q - The queue being taken from.
*
* Return: char* - The string dequeued.
*/
char* DequeueString(Queue *q) {
//Lock resource
pthread_mutex_lock(&q->lock);
//String being dequeued.
char* string;
//If the queue is empty, block until not empty.
if(q->curAmount == 0) {
//Block dequeue.
pthread_cond_wait(&q->empty, &q->lock);
q->dequeueBlockCount++;
}
//Remove the string from the queue.
string = q->strings[q->front];
q->strings[q->front] = NULL;
if(q->front + 1 == q->capacity) {
q->front = 0;
}else{
q->front++;
}
q->curAmount--;
//Don't count the final null pointer as a dequeue.
if(string != NULL) {
q->dequeueCount++;
}
//Unlock mutex and signal enqueue.
pthread_cond_signal(&q->full);
pthread_mutex_unlock(&q->lock);
return string;
}
/**
* This method prints the stats of the queue given.
*
* Parameters: q - The queue of the stats being printed.
*/
void PrintQueueStats(Queue *q) {
//Lock so the stats can't be altered.
pthread_mutex_lock(&q->lock);
//Print all stat elements.
fprintf(stderr, "Queue Stats:\nEnqueue Count: %d\nDequeue Count: %d\nEnqueue Blocked Count: %d\nDequeue Blocked Count: %d\n", q->enqueueCount, q->dequeueCount, q->enqueueBlockCount, q->dequeueBlockCount);
pthread_mutex_unlock(&q->lock);
}