21 template<
class PTT>
inline
23 steal(exit_requested_type &exit_r, signalled_work_queue_type &work_q)
noexcept(
true)
24 :
base_t(exit_r), batch(work_q) {
27 template<
class PTT>
inline
29 ~
steal()
noexcept(
false) {
30 base_t::wait_thread_exit();
31 assert(batch.batch.batch_empty());
34 template<
class PTT>
inline
38 return batch.batch.add_work_to_batch(
std::forward<
typename signalled_work_queue_type::value_type>(wk));
41 template<
class PTT>
inline
45 return batch.batch.process_a_batch_item();
48 template<
class PTT>
inline
51 process()
noexcept(
false) {
54 typename exit_requested_type::lock_result_type lkd;
56 const typename os_traits::thread_traits::cancellability set;
57 lkd=
this->exit_requested_.lock();
59 if (lkd.second!=
lock_traits::atom_set || lkd.first==exit_requested_type::states::exit_requested) {
61 this->exit_requested_.set(exit_requested_type::states::exit_requested);
63 }
else if (lkd.first==exit_requested_type::states::new_work_arrived) {
65 batch.batch.process_a_batch(batch.signalled_work_queue);
66 assert(batch.batch.batch_empty());
72 template<
class PTT>
inline
74 slave(exit_requested_type &exit_r,
typename signalled_work_queue_type::value_type &&wk)
noexcept(
true)
75 :
base_t(exit_r), some_work(
std::forward<
typename signalled_work_queue_type::value_type>(wk)), statistics_() {
78 template<
class PTT>
inline
80 ~
slave()
noexcept(
true) {
81 base_t::wait_thread_exit();
84 template<
class PTT>
inline
87 process()
noexcept(
false) {
88 some_work->process_nonjoinable(signalled_work_queue_type::value_ret_type::value_type::value_type::cfg_type::vertical_edge_annotation);
89 this->statistics_.processed_vertical_work();
93 template<
class PTT>
inline
95 steal(exit_requested_type &exit_r, signalled_work_queue_type &work_q)
noexcept(
true)
96 : base_t(exit_r), batch(work_q) {
99 template<
class PTT>
inline
101 ~
steal()
noexcept(
false) {
102 base_t::wait_thread_exit();
103 assert(batch.batch.batch_empty());
106 template<
class PTT>
inline
110 return batch.batch.add_work_to_batch(
std::forward<
typename signalled_work_queue_type::value_type>(wk));
113 template<
class PTT>
inline
117 return batch.batch.process_a_batch_item();
120 template<
class PTT>
inline
123 process()
noexcept(
false) {
126 typename exit_requested_type::lock_result_type lkd;
128 const typename os_traits::thread_traits::cancellability set;
129 lkd=
this->exit_requested_.lock();
131 assert(lkd.second==exit_requested_type::lock_result_type::second_type::atom_set);
132 if (lkd.first==exit_requested_type::states::exit_requested) {
134 this->exit_requested_.set(exit_requested_type::states::exit_requested);
136 }
else if (lkd.first==exit_requested_type::states::new_work_arrived) {
138 batch.batch.process_a_batch(batch.signalled_work_queue);
139 assert(batch.batch.batch_empty());
142 return thread_traits::api_params_type::no_kernel_thread;
145 template<
class PTT>
inline
147 steal(exit_requested_type &exit_r)
noexcept(
true)
148 :
base_t(exit_r), work() {
151 template<
class PTT>
inline
153 steal(steal &&s)
noexcept(
true)
154 :
base_t(s.exit_requested_), work(
std::move(s.work)) {
157 template<
class PTT>
inline
159 ~
steal()
noexcept(
false) {
160 base_t::wait_thread_exit();
163 template<
class PTT>
inline bool
165 push_front(
typename signalled_work_queue_type::value_type &&wk) {
166 work.batch.push_front(
std::forward<
typename signalled_work_queue_type::value_type>(wk));
170 template<
class PTT>
inline bool
176 template<
class PTT>
inline
179 process()
noexcept(
false) {
180 using cfg_type=
typename container_type::container_type::value_type::value_type::cfg_type;
184 while (work.batch.empty()) {
185 const typename exit_requested_type::lock_result_type lkd=
this->exit_requested_.try_lock();
186 assert(lkd.second==exit_requested_type::lock_result_type::second_type::atom_set);
187 if (lkd.first==exit_requested_type::states::exit_requested) {
189 this->exit_requested_.set(exit_requested_type::states::exit_requested);
193 typename container_type::container_type::value_type current_work(work.batch.pop_front_1_nochk_nosig());
195 wk.process_the_work(
std::bind(&statistics_type::processed_vertical_work, &work.statistics_), cfg_type::vertical_edge_annotation);
200 template<
class PTT>
inline
202 slave(exit_requested_type &exit_r,
typename signalled_work_queue_type::value_type &&wk)
noexcept(
true)
203 :
base_t(exit_r), some_work(
std::forward<
typename signalled_work_queue_type::value_type>(wk)), statistics_() {
206 template<
class PTT>
inline
208 ~
slave()
noexcept(
true) {
209 base_t::wait_thread_exit();
212 template<
class PTT>
inline
215 process()
noexcept(
false) {
216 class set_work_complete {
218 explicit set_work_complete(
typename signalled_work_queue_type::value_type::atomic_ptr_t &wc)
noexcept(
true)
221 ~set_work_complete()
noexcept(
true) {
222 work_ptr->work_complete()->set();
226 typename signalled_work_queue_type::value_type::atomic_ptr_t &work_ptr;
229 typename signalled_work_queue_type::value_type::atomic_ptr_t work_ptr(some_work.get());
230 if (
dynamic_cast<
typename signalled_work_queue_type::value_type::no_ref_counting *>(work_ptr.get())) {
231 some_work=
typename signalled_work_queue_type::value_type();
234 const set_work_complete setter(work_ptr);
235 work_ptr->process_joinable(signalled_work_queue_type::value_ret_type::value_type::value_type::cfg_type::vertical_edge_annotation);
237 work_ptr->process_nonjoinable(signalled_work_queue_type::value_ret_type::value_type::value_type::cfg_type::vertical_edge_annotation);
239 this->statistics_.processed_vertical_work();