Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f2be60c

Browse files
authored
[orc-rt] Add QueueingTaskDispatcher API. (#172401)
QueueingTaskDispatcher adds Tasks to a the back of a double ended queue that is accessible to clients via the `pop_back` and `pop_front` methods. Clients can manually take and run tasks, or call `runLIFOUntilEmpty` or `runFIFOUntilEmpty` to run tasks until the queue is empty. QueueingTaskDispatcher is intended for use in unit tests, and as a foundation for blocking convenience APIs in environments without threads. QueueingTaskDispatcher should generally be avoided, and ThreadPoolTaskDispatcher preferred, where threads are available.
1 parent 67d0e21 commit f2be60c

6 files changed

Lines changed: 472 additions & 0 deletions

File tree

orc-rt/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(ORC_RT_HEADERS
1212
orc-rt/IntervalSet.h
1313
orc-rt/Math.h
1414
orc-rt/MemoryFlags.h
15+
orc-rt/QueueingTaskDispatcher.h
1516
orc-rt/ResourceManager.h
1617
orc-rt/RTTI.h
1718
orc-rt/ScopeExit.h
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===------------------ QueueingTaskDispatcher.h ----------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// QueueingTaskDispatcher class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef ORC_RT_QUEUEINGTASKDISPATCHER_H
14+
#define ORC_RT_QUEUEINGTASKDISPATCHER_H
15+
16+
#include "orc-rt/TaskDispatcher.h"
17+
18+
#include <deque>
19+
#include <memory>
20+
#include <mutex>
21+
22+
namespace orc_rt {
23+
24+
/// A TaskDispatcher implementation that puts tasks in a queue to be run.
25+
/// QueueingTaskDispatcher provides direct access to the queue, allowing
26+
/// clients to decide how to run tasks. It is intended for use on systems
27+
/// where threads are not available, and for unit tests.
28+
/// For most uses of the ORC runtime, use of QueueingTaskDispatcher is strongly
29+
/// discouraged, and alternatives like ThreadPoolTaskDispatcher are preferred.
30+
class QueueingTaskDispatcher : public TaskDispatcher {
31+
public:
32+
void dispatch(std::unique_ptr<Task> T) override;
33+
void shutdown() override;
34+
35+
/// Take a task from the back of the queue. If there are no tasks, returns
36+
/// nullptr.
37+
std::unique_ptr<Task> pop_back();
38+
39+
/// Take a task from the front of the queue. If there are no tasks, returns
40+
/// nullptr.
41+
std::unique_ptr<Task> pop_front();
42+
43+
/// Run tasks in last-in-first-out order until the queue is empty.
44+
void runLIFOUntilEmpty();
45+
46+
/// Run tasks in first-in-first-out order until the queue is empty.
47+
void runFIFOUntilEmpty();
48+
49+
private:
50+
std::mutex M;
51+
enum { Running, Shutdown } State = Running;
52+
std::deque<std::unique_ptr<Task>> Tasks;
53+
};
54+
55+
} // namespace orc_rt
56+
57+
#endif // ORC_RT_QUEUEINGTASKDISPATCHER_H

orc-rt/lib/executor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(files
22
AllocAction.cpp
33
Error.cpp
4+
QueueingTaskDispatcher.cpp
45
ResourceManager.cpp
56
RTTI.cpp
67
Session.cpp
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===- QueueingTaskDispatcher.cpp -----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Contains the implementation of APIs in the orc-rt/QueueingTaskDispatcher.h
10+
// header.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "orc-rt/QueueingTaskDispatcher.h"
15+
16+
#include <cassert>
17+
18+
namespace orc_rt {
19+
20+
void QueueingTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
21+
std::scoped_lock<std::mutex> Lock(M);
22+
if (State == Running)
23+
Tasks.push_back(std::move(T));
24+
}
25+
26+
void QueueingTaskDispatcher::shutdown() {
27+
std::deque<std::unique_ptr<Task>> ResidualTasks;
28+
{
29+
std::scoped_lock<std::mutex> Lock(M);
30+
State = Shutdown;
31+
ResidualTasks = std::move(Tasks);
32+
}
33+
// ResidualTask destruction can run Task destructors outside the lock.
34+
}
35+
36+
std::unique_ptr<Task> QueueingTaskDispatcher::pop_back() {
37+
std::scoped_lock<std::mutex> Lock(M);
38+
if (Tasks.empty())
39+
return nullptr;
40+
auto T = std::move(Tasks.back());
41+
Tasks.pop_back();
42+
return T;
43+
}
44+
45+
std::unique_ptr<Task> QueueingTaskDispatcher::pop_front() {
46+
std::scoped_lock<std::mutex> Lock(M);
47+
if (Tasks.empty())
48+
return nullptr;
49+
auto T = std::move(Tasks.front());
50+
Tasks.pop_front();
51+
return T;
52+
}
53+
54+
void QueueingTaskDispatcher::runLIFOUntilEmpty() {
55+
while (auto T = pop_back())
56+
T->run();
57+
}
58+
59+
void QueueingTaskDispatcher::runFIFOUntilEmpty() {
60+
while (auto T = pop_front())
61+
T->run();
62+
}
63+
64+
} // namespace orc_rt

orc-rt/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_orc_rt_unittest(CoreTests
2323
IntervalSetTest.cpp
2424
MathTest.cpp
2525
MemoryFlagsTest.cpp
26+
QueueingTaskDispatcherTest.cpp
2627
RTTITest.cpp
2728
ScopeExitTest.cpp
2829
SessionTest.cpp

0 commit comments

Comments
 (0)