Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtconcurrentreducekernel.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QTCONCURRENT_REDUCEKERNEL_H
6#define QTCONCURRENT_REDUCEKERNEL_H
7
8#include <QtConcurrent/qtconcurrent_global.h>
9
10#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
11
12#include <QtCore/qatomic.h>
13#include <QtCore/qlist.h>
14#include <QtCore/qmap.h>
15#include <QtCore/qmutex.h>
16#include <QtCore/qthread.h>
17#include <QtCore/qthreadpool.h>
18
19#include <mutex>
20
21QT_BEGIN_NAMESPACE
22
23namespace QtPrivate {
24
25template<typename Sequence>
27{
28 SequenceHolder(const Sequence &s) : sequence(s) { }
29 SequenceHolder(Sequence &&s) : sequence(std::move(s)) { }
30 Sequence sequence;
31};
32
33}
34
35namespace QtConcurrent {
36
37/*
38 The ReduceQueueStartLimit and ReduceQueueThrottleLimit constants
39 limit the reduce queue size for MapReduce. When the number of
40 reduce blocks in the queue exceeds ReduceQueueStartLimit,
41 MapReduce won't start any new threads, and when it exceeds
42 ReduceQueueThrottleLimit running threads will be stopped.
43*/
44#ifdef Q_QDOC
48};
49#else
50enum {
53};
54#endif
55
56// IntermediateResults holds a block of intermediate results from a
57// map or filter functor. The begin/end offsets indicates the origin
58// and range of the block.
59template <typename T>
61{
62public:
63 int begin, end;
65};
66
71 // ParallelReduce = 0x8
72};
74#ifndef Q_QDOC
76#endif
77// supports both ordered and out-of-order reduction
78template <typename ReduceFunctor, typename ReduceResultType, typename T>
80{
81 typedef QMap<int, IntermediateResults<T> > ResultsMap;
82
84
87 const int threadCount;
89
90 bool canReduce(int begin) const
91 {
93 && progress == 0)
95 && progress == begin));
96 }
97
101 {
102 for (int i = 0; i < result.vector.size(); ++i) {
104 }
105 }
106
110 {
111 typename ResultsMap::iterator it = map.begin();
112 while (it != map.end()) {
114 ++it;
115 }
116 }
117
118public:
123
127 {
129 if (!canReduce(result.begin)) {
132 return;
133 }
134
136 // UnorderedReduce
137 progress = -1;
138
139 // reduce this result
140 locker.unlock();
142 locker.lock();
143
144 // reduce all stored results as well
145 while (!resultsMap.isEmpty()) {
148
149 locker.unlock();
151 locker.lock();
152
154 }
155
156 progress = 0;
157 } else {
158 // reduce this result
159 locker.unlock();
161 locker.lock();
162
163 // OrderedReduce
165
166 // reduce as many other results as possible
167 typename ResultsMap::iterator it = resultsMap.begin();
168 while (it != resultsMap.end()) {
169 if (it.value().begin != progress)
170 break;
171
172 locker.unlock();
174 locker.lock();
175
177 progress += it.value().end - it.value().begin;
179 }
180 }
181 }
182
183 // final reduction
188
194
195 inline bool shouldStartThread()
196 {
199 }
200};
201
202template <typename Sequence, typename Base, typename Functor1, typename Functor2>
203struct SequenceHolder2 : private QtPrivate::SequenceHolder<Sequence>, public Base
204{
205 template<typename S = Sequence, typename F1 = Functor1, typename F2 = Functor2>
206 SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
207 ReduceOptions reduceOptions)
208 : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
209 Base(pool, this->sequence.cbegin(), this->sequence.cend(),
210 std::forward<F1>(functor1), std::forward<F2>(functor2), reduceOptions)
211 { }
212
213 template<typename InitialValueType, typename S = Sequence,
214 typename F1 = Functor1, typename F2 = Functor2>
215 SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
216 InitialValueType &&initialValue, ReduceOptions reduceOptions)
217 : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
218 Base(pool, this->sequence.cbegin(), this->sequence.cend(),
219 std::forward<F1>(functor1), std::forward<F2>(functor2),
220 std::forward<InitialValueType>(initialValue), reduceOptions)
221 { }
222
223 void finish() override
224 {
225 Base::finish();
226 // Clear the sequence to make sure all temporaries are destroyed
227 // before finished is signaled.
228 this->sequence = Sequence();
229 }
230};
231
232} // namespace QtConcurrent
233
234QT_END_NAMESPACE
235
236#endif // QT_NO_CONCURRENT
237
238#endif
\inmodule QtConcurrent
ReduceOption
This enum specifies the order of which results from the map or filter function are passed to the redu...
SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2, ReduceOptions reduceOptions)
SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2, InitialValueType &&initialValue, ReduceOptions reduceOptions)