9 static const char rcsid[] __attribute__((used)) =
"$Id: TaskQueue.cpp 1653 2016-02-28 19:54:59Z sella $";
11 #include "TaskQueue.h"
12 #include "CommonMacro.h"
23 using namespace sella::util;
27 bool operator()(
const Task::shared &t1,
const Task::shared &t2)
const {
28 if (UNLIKELY(t1 == NULL)) {
30 }
else if (UNLIKELY(t2 == NULL)) {
34 const timeval &tv1 = t1->getTimer();
35 const timeval &tv2 = t2->getTimer();
37 if (UNLIKELY(timercmp(&tv1, &tv2, ==))) {
38 return t1->getPriority() < t2->getPriority();
39 }
else if (!timerisset(&tv1)) {
41 }
else if (!timerisset(&tv2)) {
43 }
else if (timercmp(&tv1, &tv2, <)) {
50 TaskQueue::TaskQueue(
const size_t capacity) : libutilxx__log(::libutilxx__log) {
54 TaskQueue::TaskQueue(Log::shared log,
const size_t capacity) : libutilxx__log(log) {
58 TaskQueue::~TaskQueue() { }
60 size_t TaskQueue::size(
void)
const {
64 bool TaskQueue::empty(
void)
const {
68 void TaskQueue::clear(
void) {
72 Task::shared TaskQueue::top(
void)
const {
73 assert(!heap.empty());
78 Task::shared TaskQueue::next(
void)
const {
80 return Task::shared_ptr();
86 const timeval TaskQueue::getDelay(timeval fallback)
const {
91 return heap.front()->getDelay();
94 uint64_t TaskQueue::getDelayMsec(uint64_t fallback, uint64_t maximum)
const {
99 uint64_t delay = heap.front()->getDelayMsec();
101 if (maximum > 0 && delay > maximum) {
108 uint64_t TaskQueue::getDelayUsec(uint64_t fallback, uint64_t maximum)
const {
113 uint64_t delay = heap.front()->getDelayUsec();
115 if (maximum > 0 && delay > maximum) {
122 void TaskQueue::push(Task::shared &task) {
123 assert(task.get() != NULL);
125 heap.push_back(task);
126 push_heap(heap.begin(), heap.end(),
CompareTask());
129 void TaskQueue::push(Task::shared &task,
const std::chrono::system_clock::duration &delay,
int priority) {
130 assert(task.get() != NULL);
132 task->setDelay(delay);
133 if (priority) task->setPriority(priority);
138 void TaskQueue::push(Task::shared &task,
const std::chrono::system_clock::time_point &time,
int priority) {
139 assert(task.get() != NULL);
141 task->setTimer(time);
142 if (priority) task->setPriority(priority);
147 void TaskQueue::push(Task::shared &task, time_t sec, suseconds_t usec,
int priority) {
148 assert(task.get() != NULL);
150 task->setDelay(sec, usec);
151 if (priority) task->setPriority(priority);
156 void TaskQueue::push(Task::shared &task, timeval &tv,
int priority) {
157 assert(task.get() != NULL);
160 if (priority) task->setPriority(priority);
165 bool TaskQueue::repush(Task::shared &task,
const std::chrono::system_clock::duration &delay,
int priority,
bool strict) {
166 timeval tv = Time::chronototv(delay);
168 return repush(task, tv, priority, strict);
171 bool TaskQueue::repush(Task::shared &task,
const std::chrono::system_clock::time_point &time,
int priority,
bool strict) {
172 timeval tv = Time::chronototv(time);
174 return repush(task, tv, priority, strict);
177 bool TaskQueue::repush(Task::shared &task, time_t sec, suseconds_t usec,
int priority,
bool strict) {
178 assert(task.get() != NULL);
185 push(task, sec, usec, priority);
190 for (
auto it = heap.cbegin(); it != heap.cend(); ++it) {
192 (*it)->setDelay(sec, usec);
193 if (priority) (*it)->setPriority(priority);
194 make_heap(heap.begin(), heap.end(),
CompareTask());
204 push(task, sec, usec, priority);
209 bool TaskQueue::repush(Task::shared &task, timeval &tv,
int priority,
bool strict) {
210 assert(task.get() != NULL);
217 push(task, tv, priority);
222 for (
auto it = heap.cbegin(); it != heap.cend(); ++it) {
225 if (priority) (*it)->setPriority(priority);
226 make_heap(heap.begin(), heap.end(),
CompareTask());
236 push(task, tv, priority);
241 void TaskQueue::pop(
void) {
242 assert(!heap.empty());
248 bool TaskQueue::erase(Task::shared &task,
bool firstonly) {
255 auto it = heap.begin();
256 while (it != heap.end()) {
261 if (firstonly)
break;
267 make_heap(heap.begin(), heap.end(),
CompareTask());
272 bool TaskQueue::erase(
void *
object) {
275 auto it = heap.begin();
276 while (it != heap.end()) {
277 if ((*it)->getObject() == object) {
286 make_heap(heap.begin(), heap.end(),
CompareTask());
291 size_t TaskQueue::capacity(
void)
const {
292 return heap.capacity();
295 void TaskQueue::reserve(
size_t capacity) {
296 heap.reserve(capacity);
299 void TaskQueue::setLog(Log::shared log) {
300 this->libutilxx__log = log;
303 bool TaskQueue::isReady(
void)
const {
308 return heap.front()->isReady();
311 void TaskQueue::print(
void)
const {
313 timeval now, timer, delay;
315 if (libutilxx__log == NULL) {
319 gettimeofday(&now, NULL);
320 INFO(
"[TaskQueue Heap] - now %10lu.%06lu, %zd queued", now.tv_sec, now.tv_usec, heap.size());
323 INFO(
" heap => empty");
328 for (
auto it = heap.begin(); it != heap.end(); ++it) {
329 timer = (*it)->getTimer();
330 if (timerisset(&timer)) {
332 delay.tv_sec = timer.tv_sec - now.tv_sec;
333 delay.tv_usec = timer.tv_usec - now.tv_usec;
334 if (delay.tv_sec > 0 && delay.tv_usec < 0) {
336 delay.tv_usec += 1000000;
339 INFO(
" heap => task(%10p) obj: %10p pri: %3d timer: %10lu.%06lu delay: %4d.%d", (*it).get(), (*it)->getObject(), (*it)->getPriority(), timer.tv_sec, timer.tv_usec, (signed) delay.tv_sec, (
signed) delay.tv_usec);
341 INFO(
" heap => task(%10p) obj: %10p pri: %3d timer: %10lu.%06lu delay: -inf", (*it).get(), (*it)->getObject(), (*it)->getPriority(), timer.tv_sec, timer.tv_usec);