| 150 | } |
| 151 | |
| 152 | void ThreadPoolExecutor::keep_execute() noexcept { |
| 153 | auto& local_queue = _local_task_queues.local(); |
| 154 | RunnerScope scope {*this}; |
| 155 | while (true) { |
| 156 | Task task; |
| 157 | if (!local_queue.try_pop<true, false>(task)) { |
| 158 | bool steal_success = false; |
| 159 | if (_enable_work_stealing) { |
| 160 | _local_task_queues.for_each([&](TaskQueue* iter, TaskQueue* end) { |
| 161 | if (steal_success) { |
| 162 | return; |
| 163 | } |
| 164 | while (iter != end) { |
| 165 | auto& queue = *iter++; |
| 166 | steal_success = queue.try_pop<true, false>(task); |
| 167 | if (steal_success) { |
| 168 | return; |
| 169 | } |
| 170 | } |
| 171 | }); |
| 172 | } |
| 173 | if (!steal_success) { |
| 174 | _global_task_queue.pop<true, true, false>(task); |
| 175 | } |
| 176 | } |
| 177 | switch (task.type) { |
| 178 | case TaskType::FUNCTION: { |
| 179 | task.function(); |
| 180 | } break; |
| 181 | case TaskType::STOP: { |
| 182 | return; |
| 183 | } |
| 184 | case TaskType::WAKEUP: { |
| 185 | } break; |
| 186 | default: |
| 187 | assert(false); |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | void ThreadPoolExecutor::keep_balance() noexcept { |
| 193 | while (_running.load(::std::memory_order_acquire)) { |