source: trunk/src/corelib/concurrent/qtconcurrentiteratekernel.h@ 813

Last change on this file since 813 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 10.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QTCONCURRENT_ITERATEKERNEL_H
43#define QTCONCURRENT_ITERATEKERNEL_H
44
45#include <QtCore/qglobal.h>
46
47#ifndef QT_NO_CONCURRENT
48
49#include <QtCore/qatomic.h>
50#include <QtCore/qtconcurrentmedian.h>
51#include <QtCore/qtconcurrentthreadengine.h>
52
53#ifndef QT_NO_STL
54# include <iterator>
55#endif
56
57QT_BEGIN_HEADER
58QT_BEGIN_NAMESPACE
59
60QT_MODULE(Core)
61
62#ifndef qdoc
63
64namespace QtConcurrent {
65
66#ifndef QT_NO_STL
67 using std::advance;
68#else
69 template <typename It, typename T>
70 void advance(It &it, T value)
71 {
72 it+=value;
73 }
74#endif
75
76/*
77 The BlockSizeManager class manages how many iterations a thread should
78 reserve and process at a time. This is done by measuring the time spent
79 in the user code versus the control part code, and then increasing
80 the block size if the ratio between them is to small. The block size
81 management is done on the basis of the median of several timing measuremens,
82 and it is done induvidualy for each thread.
83*/
84class Q_CORE_EXPORT BlockSizeManager
85{
86public:
87 BlockSizeManager(int iterationCount);
88 void timeBeforeUser();
89 void timeAfterUser();
90 int blockSize();
91private:
92 inline bool blockSizeMaxed()
93 {
94 return (m_blockSize >= maxBlockSize);
95 }
96
97 const int maxBlockSize;
98 qint64 beforeUser;
99 qint64 afterUser;
100 Median<double> controlPartElapsed;
101 Median<double> userPartElapsed;
102 int m_blockSize;
103};
104
105template <typename T>
106class ResultReporter
107{
108public:
109 ResultReporter(ThreadEngine<T> *_threadEngine)
110 :threadEngine(_threadEngine)
111 {
112
113 }
114
115 void reserveSpace(int resultCount)
116 {
117 currentResultCount = resultCount;
118 vector.resize(qMax(resultCount, vector.count()));
119 }
120
121 void reportResults(int begin)
122 {
123 const int useVectorThreshold = 4; // Tunable parameter.
124 if (currentResultCount > useVectorThreshold) {
125 vector.resize(currentResultCount);
126 threadEngine->reportResults(vector, begin);
127 } else {
128 for (int i = 0; i < currentResultCount; ++i)
129 threadEngine->reportResult(&vector.at(i), begin + i);
130 }
131 }
132
133 inline T * getPointer()
134 {
135 return vector.data();
136 }
137
138 int currentResultCount;
139 ThreadEngine<T> *threadEngine;
140 QVector<T> vector;
141};
142
143template <>
144class ResultReporter<void>
145{
146public:
147 inline ResultReporter(ThreadEngine<void> *) { }
148 inline void reserveSpace(int) { };
149 inline void reportResults(int) { };
150 inline void * getPointer() { return 0; }
151};