-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSerialTaskQueue.cc
More file actions
112 lines (95 loc) · 2.27 KB
/
SerialTaskQueue.cc
File metadata and controls
112 lines (95 loc) · 2.27 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
// -*- C++ -*-
//
// Package: Concurrency
// Class : SerialTaskQueue
//
// Implementation:
// [Notes on implementation]
//
// Original Author: Chris Jones
// Created: Thu Feb 21 11:31:52 CST 2013
// $Id: SerialTaskQueue.cc,v 1.1 2013/02/21 22:14:11 chrjones Exp $
//
// system include files
// user include files
#include "SerialTaskQueue.h"
#include "Likely.h"
using namespace edm;
//
// member functions
//
bool
SerialTaskQueue::resume() {
if(0==--m_pauseCount) {
tbb::task* t = pickNextTask();
if(0 != t) {
tbb::task::spawn(*t);
}
return true;
}
return false;
}
void
SerialTaskQueue::pushTask(TaskBase* iTask) {
tbb::task* t = pushAndGetNextTask(iTask);
if(0!=t) {
tbb::task::spawn(*t);
}
}
tbb::task*
SerialTaskQueue::pushAndGetNextTask(TaskBase* iTask) {
tbb::task* returnValue{0};
if likely(0!=iTask) {
m_tasks.push(iTask);
returnValue = pickNextTask();
}
return returnValue;
}
tbb::task*
SerialTaskQueue::finishedTask() {
m_taskChosen.clear();
return pickNextTask();
}
SerialTaskQueue::TaskBase*
SerialTaskQueue::pickNextTask() {
if likely(0 == m_pauseCount and not m_taskChosen.test_and_set()) {
TaskBase* t=0;
if likely(m_tasks.try_pop(t)) {
return t;
}
//no task was actually pulled
m_taskChosen.clear();
//was a new entry added after we called 'try_pop' but before we did the clear?
if(not m_tasks.empty() and not m_taskChosen.test_and_set()) {
TaskBase* t=0;
if(m_tasks.try_pop(t)) {
return t;
}
//no task was still pulled since a different thread beat us to it
m_taskChosen.clear();
}
}
return 0;
}
void SerialTaskQueue::pushAndWait(tbb::empty_task* iWait, TaskBase* iTask) {
auto nextTask = pushAndGetNextTask(iTask);
if likely(nullptr != nextTask) {
if likely(nextTask == iTask) {
//spawn and wait for all requires the task to have its parent set
iWait->spawn_and_wait_for_all(*nextTask);
} else {
tbb::task::spawn(*nextTask);
iWait->wait_for_all();
}
} else {
//a task must already be running in this queue
iWait->wait_for_all();
}
tbb::task::destroy(*iWait);
}
//
// const member functions
//
//
// static member functions
//