proxygen
for_each_2.cpp File Reference
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#include <folly/experimental/pushmi/examples/for_each.h>
#include <folly/experimental/pushmi/examples/pool.h>

Go to the source code of this file.

Functions

template<class Executor , class Allocator = std::allocator<char>>
auto naive_executor_bulk_target (Executor e, Allocator a=Allocator{})
 
int main ()
 

Function Documentation

int main ( void  )

Definition at line 117 of file for_each_2.cpp.

References count, for_each(), max, naive_executor_bulk_target(), and x.

117  {
118  mi::pool p{std::max(1u, std::thread::hardware_concurrency())};
119 
120  std::vector<int> vec(10);
121 
122  mi::for_each(
123  naive_executor_bulk_target(p.executor()),
124  vec.begin(),
125  vec.end(),
126  [](int& x) { x = 42; });
127 
128  assert(
129  std::count(vec.begin(), vec.end(), 42) == static_cast<int>(vec.size()));
130 
131  std::cout << "OK" << std::endl;
132 
133  p.stop();
134  p.wait();
135 }
Definition: InvokeTest.cpp:58
LogLevel max
Definition: LogLevel.cpp:31
const int x
auto naive_executor_bulk_target(Executor e, Allocator a=Allocator{})
Definition: for_each_2.cpp:27
Definition: Traits.h:588
int * count
vector< string > vec
Definition: StringTest.cpp:35
void for_each(T const &range, Function< void(typename T::value_type const &) const > const &func)
template<class Executor , class Allocator = std::allocator<char>>
auto naive_executor_bulk_target ( Executor  e,
Allocator  a = Allocator{} 
)

Definition at line 27 of file for_each_2.cpp.

References a, folly::init(), folly::gen::move, folly::pushmi::set_error, folly::pushmi::set_value, submit, type, and value.

Referenced by main().

27  {}) {
28  return [e, a](
29  auto init,
30  auto selector,
31  auto input,
32  auto&& func,
33  auto sb,
34  auto se,
35  auto out) {
36  using RS = decltype(selector);
37  using F = std::conditional_t<
39  decltype(func),
41  using Out = decltype(out);
42  try {
43  typename std::allocator_traits<Allocator>::template rebind_alloc<char>
44  allocState(a);
45  auto shared_state = std::allocate_shared<std::tuple<
46  std::exception_ptr, // first exception
47  Out, // destination
48  RS, // selector
49  F, // func
50  std::atomic<decltype(init(input))>, // accumulation
51  std::atomic<std::size_t>, // pending
52  std::atomic<std::size_t> // exception count (protects assignment to
53  // first exception)
54  >>(
55  allocState,
56  std::exception_ptr{},
57  std::move(out),
58  std::move(selector),
59  (decltype(func)&&)func,
60  init(std::move(input)),
61  1,
62  0);
63  e | op::submit([e, sb, se, shared_state](auto) {
64  auto stepDone = [](auto shared_state) {
65  // pending
66  if (--std::get<5>(*shared_state) == 0) {
67  // first exception
68  if (std::get<0>(*shared_state)) {
70  std::get<1>(*shared_state), std::get<0>(*shared_state));
71  return;
72  }
73  try {
74  // selector(accumulation)
75  auto result = std::get<2>(*shared_state)(
76  std::move(std::get<4>(*shared_state).load()));
77  mi::set_value(std::get<1>(*shared_state), std::move(result));
78  } catch (...) {
80  std::get<1>(*shared_state), std::current_exception());
81  }
82  }
83  };
84  for (decltype(sb) idx{sb}; idx != se;
85  ++idx, ++std::get<5>(*shared_state)) {
86  e | op::submit([shared_state, idx, stepDone](auto ex) {
87  try {
88  // this indicates to me that bulk is not the right abstraction
89  auto old = std::get<4>(*shared_state).load();
90  auto step = old;
91  do {
92  step = old;
93  // func(accumulation, idx)
94  std::get<3> (*shared_state)(step, idx);
95  } while (!std::get<4>(*shared_state)
96  .compare_exchange_strong(old, step));
97  } catch (...) {
98  // exception count
99  if (std::get<6>(*shared_state)++ == 0) {
100  // store first exception
101  std::get<0>(*shared_state) = std::current_exception();
102  } // else eat the exception
103  }
104  stepDone(shared_state);
105  });
106  }
107  stepDone(shared_state);
108  });
109  } catch (...) {
110  e |
111  op::submit([out = std::move(out), ep = std::current_exception()](
112  auto) mutable { mi::set_error(out, ep); });
113  }
114  };
115 }
PskType type
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr __adl::set_error_fn set_error
void init()
char a
static const char *const value
Definition: Conv.cpp:50
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value