11#pragma once
22#include < thread>
3+ #include < future>
4+ #include < chrono>
35#include < iostream>
46#include < concepts>
57#include < utility>
@@ -142,4 +144,120 @@ T parallel_transform_reduce(int num_threads, ForwardIt first, ForwardIt last, T
142144{
143145 return parallel_transform_reduce (first, last, init, reduce, transform, num_threads);
144146}
145- }
147+
148+ // template<class ForwardIt, class WorkFn, class WorkFnResultOptional>
149+ // void parallel_search_first(ForwardIt begin, ForwardIt end, WorkFn work_fn, std::chrono::milliseconds busy_loop_sleep = 0)
150+ // {
151+ // std::promise<void> done_promise;
152+ // std::shared_future<void> done_future = done_promise.get_future();
153+
154+ // const auto worker = [done_future](ForwardIt begin, ForwardIt end, std::promise<WorkFnResultOptional> result_promise)
155+ // {
156+ // for (auto it = begin; it != end; ++it) {
157+ // if (done_future.wait_for(std::chrono::nanoseconds{0}) == std::future_status::ready) {
158+ // return;
159+ // }
160+ // WorkFnResultOptional result = work_fn(*begin);
161+ // if (result.has_value()) {
162+ // result_promise.set_value(result);
163+ // return;
164+ // }
165+ // }
166+ // result_promise.set_exception(WorkFnResultOptional{});
167+ // };
168+
169+ // if (num_threads > num_elems) {
170+ // num_threads = num_elems;
171+ // }
172+
173+ // const ptrdiff_t elems_per_thread = num_elems / num_threads;
174+ // ptrdiff_t remainder = num_elems % num_threads;
175+ // assert(elems_per_thread > 0 || remainder > 0);
176+ // assert((elems_per_thread * num_threads + remainder) == num_elems);
177+
178+ // std::vector<std::thread> workers;
179+ // std::vector<std::future<WorkFnResultOptional>> worker_futures;
180+ // std::vector<std::future<WorkFnResultOptional>> worker_results;
181+
182+ // for (auto start_it = first; start_it != last;) {
183+ // assert(std::ssize(workers) < num_threads);
184+ // ptrdiff_t increment = elems_per_thread;
185+ // if (remainder) {
186+ // ++increment;
187+ // --remainder;
188+ // }
189+ // assert(increment > 0);
190+
191+ // const auto end_it = std::next(start_it, increment);
192+
193+ // std::promise<WorkFnResultOptional> worker_promise;
194+ // worker_futures.push_back(worker_promise.get_future());
195+ // assert(worker_futures.back().valid());
196+ // workers.push_back(std::thread(worker, start_it, end_it, std::move(worker_promise)));
197+
198+ // start_it = end_it;
199+ // }
200+ // assert(std::ssize(workers) == num_threads);
201+ // assert(remainder == 0);
202+ // assert(worker_futures.size() == workers.size());
203+
204+ // const auto is_first_result = [&worker_futures, &worker_results](size_t idx)
205+ // {
206+ // const auto& future = worker_futures.at(i);
207+ // bool is_first_res = true;
208+ // for (int j = 0; j < i; ++j) {
209+ // if (worker_futures.at(j).valid() || worker_results.at(j).has_value()) {
210+ // is_first_res = false;
211+ // break;
212+ // }
213+ // }
214+ // return is_first_res;
215+ // }
216+
217+ // WorkFnResultOptional result = {};
218+ // for (;;) {
219+ // size_t not_found = 0;
220+ // for (size_t i = 0; i < worker_futures.size(); ++i) {
221+ // auto& wrk_future = worker_futures.at(i);
222+ // auto& wrk_result = worker_results.at(i);
223+
224+ // const bool is_first_res = is_first_result(i);
225+
226+ // const auto is_done = [is_first_res, &wrk_future, &result, &wrk_result, ¬_found, &done_promise]() -> bool {
227+ // if (!wrk_results.has_value() || !is_first_res) {
228+ // ++not_found;
229+ // return false;
230+ // } else {
231+ // result = wrk_result;
232+ // done_promise.set_value(); // Signal to all workers we found a solution.
233+ // return true;
234+ // }
235+ // };
236+
237+ // if (!future.valid() && is_done()) {
238+ // assert(result.has_value());
239+ // goto end;
240+ // } else if (future.valid() && future.wait_for(busy_loop_sleep) == std::future_status::ready) {
241+ // wrk_result = future.get();
242+ // assert(!future.valid());
243+ // if (is_done()) {
244+ // assert(result.has_value());
245+ // goto end;
246+ // }
247+ // }
248+ // }
249+
250+ // if (not_found == worker_futures.size()) {
251+ // assert(!result.has_value());
252+ // goto end;
253+ // }
254+ // }
255+
256+ // end:
257+ // for (auto& w: workers) {
258+ // w.join();
259+ // }
260+ // return result;
261+ // }
262+
263+ }
0 commit comments