-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy paththreadq.c
More file actions
147 lines (132 loc) · 3.43 KB
/
threadq.c
File metadata and controls
147 lines (132 loc) · 3.43 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
//
// Created by chris on 6/1/2016.
//
#include "threadq.h"
#include <stdlib.h>
/**
* A node for a {@code THREADQp} collection.
*/
typedef struct threadq_node *threadq_node_t;
/**
* A Linked List implementation of a FIFO queue
*/
struct threadq
{
/**
* The first node in the queue.
*/
threadq_node_t first;
/**
* Since the first item in a {@code threadq_node_t} is a pointer to another,
* it can be treated as a double pointer.
*/
union
{
threadq_node_t last;
threadq_node_t *follow;
};
/**
* The number of elements in the queue.
*/
uint32_t size;
};
/**
* A node for a {@code THREADQp} collection.
*/
struct threadq_node
{
/** the next node in the list. */
threadq_node_t next;
/** the value held in this node. */
thread_type value;
};
/**
* Constructs a new Linked List implemented FIFO queue for storing
* {@code thread_type} objects.
*
* @param ptr_error a memory location to store error messages.
* @return a new {@code THREADQp} object.
*/
THREADQp THREADQ_construct(uint64_t *ptr_error)
{
THREADQp this = malloc(sizeof(struct threadq));
this->first = NULL;
this->follow = &this->first;
this->size = 0;
return this;
}
/**
* Clears a {@code THREADQp} object and frees it.
*
* @param this the queue to be destroyed.
* @param ptr_error a memory location to store error messages.
*/
void THREADQ_destruct(THREADQp this, uint64_t *ptr_error)
{
while (this->first != NULL) {
threadq_node_t tmp = this->first;
this->first = this->first->next;
this->size--;
free(tmp);
}
free(this);
}
/**
* Dequeues the first element from {@code this}.
*
* @param this the queue from which you want the thread dequeued.
* @param ptr_error a memory location to store error messages.
*
* @return the thread previously stored at the front of the queue.
*/
thread_type THREADQ_dequeue(THREADQp this, uint64_t *ptr_error)
{
threadq_node_t second = this->first->next;
thread_type value = this->first->value;
free(this->first);
this->size--;
this->first = second;
return value;
}
/**
* Returns the first element from {@code this}, without removing it from the
* queue.
*
* @param this the queue at which you want to peek.
* @param ptr_error a memory location to store error messages.
*
* @return the thread stored at the front of the queue.
*/
thread_type THREADQ_peek(THREADQp this, uint64_t *ptr_error)
{
return this->size == 0 ? NULL : this->first->value;
}
/**
* Enqueues the first element from {@code this}.
*
* @param this the queue into which you want the thread value enqueued.
* @param value the {@code value} to add to be added to the queue.
* @param ptr_error a memory location to store error messages.
*
* @return the thread previously stored at the front of the queue.
*/
void THREADQ_enqueue(THREADQp this, thread_type value, uint64_t *ptr_error)
{
threadq_node_t new_node = malloc(sizeof(struct threadq_node));
*this->follow = new_node;
new_node->value = value;
this->size++;
}
/**
* Return a {@code bool} value depending on whether or not the queue is empty.
*
* @param this the queue to test.
* @param ptr_error a memory location to store error messages.
*
* @return {@code true} if {@code this} has no elements, {@code false}
* otherwise.
*/
bool THREADQ_is_empty(THREADQp this, uint64_t *ptr_error)
{
return (bool) (this->size == 0);
}