2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/threading/thread-pool.h>
24 #include <type_traits>
28 Dali::ThreadPool gThreadPool;
30 // Helper function dividing workload into N batches
31 // the loop lambda contains
32 Dali::UniqueFutureGroup ForEachMT(Dali::ThreadPool* pThreadPool,
35 std::function<void(uint32_t, uint32_t, uint32_t)> task)
39 const auto workerCount = uint32_t(pThreadPool->GetWorkerCount());
40 const auto step = size / workerCount;
41 j = workerCount + step;
43 std::vector<Dali::Task> tasks;
44 tasks.reserve(workerCount);
46 for(auto threadIndex = 0u; threadIndex < workerCount; ++threadIndex)
48 Dali::Task lambda = [task, i, j](int workerIndex) {
49 task(uint32_t(workerIndex), i, j);
51 tasks.emplace_back(lambda);
57 return pThreadPool->SubmitTasks(tasks, workerCount);
62 int UtcDaliThreadPoolMultipleTasks(void)
64 // initialise global thread pool
65 if(!gThreadPool.GetWorkerCount())
67 gThreadPool.Initialize(0u);
71 std::array<int, 8192> inputs;
73 for(auto i = 0; i < decltype(i)(inputs.size()); ++i)
79 // allocate outputs ( number of outputs equals number of worker threads
80 auto workerCount = gThreadPool.GetWorkerCount();
82 std::vector<int> outputs;
83 outputs.resize(workerCount);
84 std::fill(outputs.begin(), outputs.end(), 0);
87 auto future = ForEachMT(&gThreadPool, 0, inputs.size(), [&inputs, &outputs](uint32_t workerIndex, uint32_t begin, uint32_t end) {
88 for(auto i = begin; i < end; ++i)
90 outputs[workerIndex] += inputs[i];
98 for(auto output : outputs)
103 printf("sum: %d, sum2: %d\n", checksum, checksum2);
105 DALI_TEST_EQUALS(checksum, checksum2, TEST_LOCATION);
110 int UtcDaliThreadPoolSingleTask(void)
112 // initialise global thread pool
113 if(!gThreadPool.GetWorkerCount())
115 gThreadPool.Initialize(0u);
118 // some long lasting task
120 auto task = [&counter](int workerIndex) {
121 for(int i = 0; i < 10; ++i)
128 auto future = gThreadPool.SubmitTask(0, task);
130 DALI_TEST_EQUALS(counter, 10, TEST_LOCATION);
135 int UtcDaliThreadPoolSubmitTasksCopyArray(void)
137 // initialise global thread pool
138 if(!gThreadPool.GetWorkerCount())
140 gThreadPool.Initialize(0u);
143 std::array<uint8_t, 1024 * 1024> dataSrc;
144 for(auto i = 0; i < decltype(i)(dataSrc.size()); ++i)
146 dataSrc[i] = (std::rand() % 0xff);
149 std::array<uint8_t, 1024 * 1024> dataDst;
151 // each task copies 1kb od data
152 std::vector<Dali::Task> tasks;
153 for(int i = 0; i < 1024; ++i)
155 auto task = [&dataSrc, &dataDst, i](int workerIndex) {
156 for(int k = 0; k < 1024; ++k)
158 dataDst[i * 1024 + k] = dataSrc[i * 1024 + k];
161 tasks.push_back(task);
164 DALI_TEST_EQUALS(1024, tasks.size(), TEST_LOCATION);
166 gThreadPool.SubmitTasks(tasks);
168 // wait for pool to finish
172 for(auto i = 0; i < decltype(i)(dataSrc.size()); ++i)
174 DALI_TEST_EQUALS(dataSrc[i], dataDst[i], TEST_LOCATION);
175 if(dataSrc[i] != dataDst[i])