2 * Copyright (c) 2017 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.
21 #include <type_traits>
22 #include <dali-test-suite-utils.h>
23 #include <dali/devel-api/threading/thread-pool.h>
27 Dali::ThreadPool gThreadPool;
29 // Helper function dividing workload into N batches
30 // the loop lambda contains
31 Dali::UniqueFutureGroup ForEachMT( Dali::ThreadPool* pThreadPool,
34 std::function<void( uint32_t, uint32_t, uint32_t )> task )
38 const auto workerCount = uint32_t(pThreadPool->GetWorkerCount());
39 const auto step = size / workerCount;
40 j = workerCount + step;
42 std::vector<Dali::Task> tasks;
43 tasks.reserve( workerCount );
45 for( auto threadIndex = 0u; threadIndex < workerCount; ++threadIndex )
47 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 )
89 for( auto i = begin; i < end; ++i )
91 outputs[workerIndex] += inputs[i];
99 for( auto output : outputs )
104 printf("sum: %d, sum2: %d\n", checksum, checksum2);
107 DALI_TEST_EQUALS( checksum, checksum2, TEST_LOCATION );
112 int UtcDaliThreadPoolSingleTask(void)
114 // initialise global thread pool
115 if( !gThreadPool.GetWorkerCount() )
117 gThreadPool.Initialize( 0u );
120 // some long lasting task
122 auto task = [&counter]( int workerIndex ){
123 for( int i = 0; i < 10; ++i )
130 auto future = gThreadPool.SubmitTask( 0, task );
132 DALI_TEST_EQUALS( counter, 10, TEST_LOCATION );
137 int UtcDaliThreadPoolSubmitTasksCopyArray(void)
139 // initialise global thread pool
140 if( !gThreadPool.GetWorkerCount() )
142 gThreadPool.Initialize( 0u );
145 std::array<uint8_t, 1024*1024> dataSrc;
146 for( auto i = 0; i < decltype(i)(dataSrc.size()); ++i)
148 dataSrc[i] = (std::rand() % 0xff);
151 std::array<uint8_t, 1024*1024> dataDst;
153 // each task copies 1kb od data
154 std::vector<Dali::Task> tasks;
155 for( int i = 0; i < 1024; ++i )
157 auto task = [&dataSrc, &dataDst, i ]( int workerIndex )
159 for( int k = 0; k < 1024; ++k )
161 dataDst[i*1024+k] = dataSrc[i*1024+k];
164 tasks.push_back( task );
167 DALI_TEST_EQUALS( 1024, tasks.size(), TEST_LOCATION );
169 gThreadPool.SubmitTasks( tasks );
171 // wait for pool to finish
175 for( auto i = 0; i < decltype(i)(dataSrc.size()); ++i )
177 DALI_TEST_EQUALS( dataSrc[i], dataDst[i], TEST_LOCATION );
178 if( dataSrc[i] != dataDst[i] )