-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkqueues.cpp
More file actions
86 lines (75 loc) · 1.68 KB
/
workqueues.cpp
File metadata and controls
86 lines (75 loc) · 1.68 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
#include "wq/workqueues.h"
namespace wq {
unsigned work_queue_s::free_items(item_p p_list) {
unsigned n = 0;
while (p_list) {
item_p p = p_list;
p_list = p_list->p_next;
delete p;
++n;
}
return n;
}
work_queue_s::item_p work_queue_s::item_obtain() {
std::lock_guard<std::mutex> q_lock(m_free);
item_p p = p_free;
if (p) {
p_free = p->p_next;
p->p_next = 0;
} else {
p = new item_s();
}
return p;
}
void work_queue_s::item_release(item_p p) {
std::lock_guard<std::mutex> q_lock(m_free);
p->p_next = p_free;
p_free = p;
}
void work_queue_s::enqueue_work(function_t work) {
std::lock_guard<std::mutex> q_lock(m_used);
item_p p = item_obtain();
p->work = work;
if (p_tail) {
p_tail->p_next = p;
p_tail = p;
} else {
p_head = p_tail = p;
}
q_more.notify_one();
}
static const auto work_wait = std::chrono::milliseconds(100);
bool work_queue_s::dequeue_work(function_t& work) {
std::unique_lock<std::mutex> q_lock(m_used);
if (!p_head) {
q_more.wait_for(q_lock, work_wait);
}
if (p_head) {
item_p p = p_head;
if (p->p_next) {
p_head = p->p_next;
} else {
p_head = p_tail = 0;
}
work = p->work;
item_release(p);
return true;
}
return false;
}
void work_queue_s::queue_stop() {
// Unblock and terminate all worker threads.
q_live = false;
q_more.notify_all();
}
work_queue_s::work_queue_s() : q_live(true), p_free(0), p_head(0), p_tail(0) {
}
work_queue_s::~work_queue_s() {
std::unique_lock<std::mutex> l_used(m_used);
std::unique_lock<std::mutex> l_free(m_free);
unsigned n_used = free_items(p_head);
unsigned n_free = free_items(p_free);
p_head = p_tail = 0;
printf("Queue done - used: %u free: %u\n", n_used, n_free);
}
} /* namespace wq */