1 | //===------------ TaskDispatch.cpp - ORC task dispatch utils --------------===// |
---|---|
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 | #include "llvm/ExecutionEngine/Orc/TaskDispatch.h" |
10 | #include "llvm/ExecutionEngine/Orc/Core.h" |
11 | |
12 | namespace llvm { |
13 | namespace orc { |
14 | |
15 | char Task::ID = 0; |
16 | char GenericNamedTask::ID = 0; |
17 | const char *GenericNamedTask::DefaultDescription = "Generic Task"; |
18 | |
19 | void Task::anchor() {} |
20 | TaskDispatcher::~TaskDispatcher() = default; |
21 | |
22 | void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); } |
23 | |
24 | void InPlaceTaskDispatcher::shutdown() {} |
25 | |
26 | #if LLVM_ENABLE_THREADS |
27 | void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) { |
28 | bool IsMaterializationTask = isa<MaterializationTask>(Val: *T); |
29 | |
30 | { |
31 | std::lock_guard<std::mutex> Lock(DispatchMutex); |
32 | |
33 | if (IsMaterializationTask) { |
34 | |
35 | // If this is a materialization task and there are too many running |
36 | // already then queue this one up and return early. |
37 | if (MaxMaterializationThreads && |
38 | NumMaterializationThreads == *MaxMaterializationThreads) { |
39 | MaterializationTaskQueue.push_back(x: std::move(T)); |
40 | return; |
41 | } |
42 | |
43 | // Otherwise record that we have a materialization task running. |
44 | ++NumMaterializationThreads; |
45 | } |
46 | |
47 | ++Outstanding; |
48 | } |
49 | |
50 | std::thread([this, T = std::move(T), IsMaterializationTask]() mutable { |
51 | while (true) { |
52 | |
53 | // Run the task. |
54 | T->run(); |
55 | |
56 | std::lock_guard<std::mutex> Lock(DispatchMutex); |
57 | if (!MaterializationTaskQueue.empty()) { |
58 | // If there are any materialization tasks running then steal that work. |
59 | T = std::move(MaterializationTaskQueue.front()); |
60 | MaterializationTaskQueue.pop_front(); |
61 | if (!IsMaterializationTask) { |
62 | ++NumMaterializationThreads; |
63 | IsMaterializationTask = true; |
64 | } |
65 | } else { |
66 | // Otherwise decrement work counters. |
67 | if (IsMaterializationTask) |
68 | --NumMaterializationThreads; |
69 | --Outstanding; |
70 | OutstandingCV.notify_all(); |
71 | return; |
72 | } |
73 | } |
74 | }).detach(); |
75 | } |
76 | |
77 | void DynamicThreadPoolTaskDispatcher::shutdown() { |
78 | std::unique_lock<std::mutex> Lock(DispatchMutex); |
79 | Running = false; |
80 | OutstandingCV.wait(lock&: Lock, p: [this]() { return Outstanding == 0; }); |
81 | } |
82 | #endif |
83 | |
84 | } // namespace orc |
85 | } // namespace llvm |
86 |