1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtCore/QCoreApplication>
31#include <QtCore/QElapsedTimer>
32#include <QtCore/QList>
33#include <QtCore/QThread>
34#include <private/qfreelist_p.h>
35#include <QtTest/QtTest>
36
37class tst_QFreeList : public QObject
38{
39 Q_OBJECT
40
41private slots:
42 void basicTest();
43 void customized();
44 void threadedTest();
45};
46
47void tst_QFreeList::basicTest()
48{
49 {
50 QFreeList<void> voidFreeList;
51 int zero = voidFreeList.next();
52 int one = voidFreeList.next();
53 int two = voidFreeList.next();
54 QCOMPARE(zero, 0);
55 QCOMPARE(one, 1);
56 QCOMPARE(two, 2);
57 voidFreeList[zero];
58 voidFreeList[one];
59 voidFreeList[two];
60 voidFreeList.at(x: zero);
61 voidFreeList.at(x: one);
62 voidFreeList.at(x: two);
63 voidFreeList.release(id: one);
64 int next = voidFreeList.next();
65 QCOMPARE(next, 1);
66 voidFreeList[next];
67 voidFreeList.at(x: next);
68 }
69
70 {
71 QFreeList<int> intFreeList;
72 int zero = intFreeList.next();
73 int one = intFreeList.next();
74 int two = intFreeList.next();
75 QCOMPARE(zero, 0);
76 QCOMPARE(one, 1);
77 QCOMPARE(two, 2);
78 intFreeList[zero] = zero;
79 intFreeList[one] = one;
80 intFreeList[two] = two;
81 QCOMPARE(intFreeList.at(zero), zero);
82 QCOMPARE(intFreeList.at(one), one);
83 QCOMPARE(intFreeList.at(two), two);
84 intFreeList.release(id: one);
85 int next = intFreeList.next();
86 QCOMPARE(next, 1);
87 QCOMPARE(intFreeList.at(next), one);
88 intFreeList[next] = -one;
89 QCOMPARE(intFreeList.at(next), -one);
90 }
91}
92
93struct CustomFreeListConstants : public QFreeListDefaultConstants
94{
95 enum {
96 InitialNextValue = 50,
97 BlockCount = 10
98 };
99
100 static const int Sizes[10];
101};
102
103const int CustomFreeListConstants::Sizes[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 16777216 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 };
104
105void tst_QFreeList::customized()
106{
107 QFreeList<void, CustomFreeListConstants> customFreeList;
108 int next = customFreeList.next();
109 QCOMPARE(next, int(CustomFreeListConstants::InitialNextValue));
110 customFreeList[next];
111 customFreeList.at(x: next);
112 customFreeList.release(id: next);
113}
114
115enum { TimeLimit = 3000 };
116
117class FreeListThread : public QThread
118{
119 static QFreeList<void> freelist;
120
121public:
122 inline FreeListThread() : QThread() { }
123 inline void run()
124 {
125 QElapsedTimer t;
126 t.start();
127 QList<int> needToRelease;
128 do {
129 int i = freelist.next();
130 int j = freelist.next();
131 int k = freelist.next();
132 int l = freelist.next();
133 freelist.release(id: k);
134 int n = freelist.next();
135 int m = freelist.next();
136 freelist.release(id: l);
137 freelist.release(id: m);
138 freelist.release(id: n);
139 freelist.release(id: j);
140 // freelist.release(i);
141 needToRelease << i;
142 } while (t.elapsed() < TimeLimit);
143
144 foreach (int x, needToRelease)
145 freelist.release(id: x);
146 }
147};
148
149QFreeList<void> FreeListThread::freelist;
150
151void tst_QFreeList::threadedTest()
152{
153 const int ThreadCount = QThread::idealThreadCount();
154 FreeListThread *threads = new FreeListThread[ThreadCount];
155 for (int i = 0; i < ThreadCount; ++i)
156 threads[i].start();
157 for (int i = 0; i < ThreadCount; ++i)
158 threads[i].wait();
159 delete [] threads;
160}
161
162QTEST_MAIN(tst_QFreeList)
163#include "tst_qfreelist.moc"
164

source code of qtbase/tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp