static void sync1_action() { if (fetch_sub(relaxed, &sync_counter, 1) - 1 == 0) { mutex_lock(&sync_wait_lock); cond_signal(&sync_wait_cond); mutex_unlock(&sync_wait_lock); } }
static void sync2_action(struct sml_control *control) { if (control->thread_local_heap) sml_heap_mutator_sync2(control, control->thread_local_heap); /* all updates performed by this mutator happen before time that * collector checks sync_counter. */ if (fetch_sub(release, &sync_counter, 1) - 1 == 0) { mutex_lock(&sync_wait_lock); cond_signal(&sync_wait_cond); mutex_unlock(&sync_wait_lock); } }
void broadcast(Message&& message, channel_handler handle_channel, result_handler handle_complete) { // We cannot use a synchronizer here because handler closure in loop. auto counter = std::make_shared<std::atomic<size_t>>(channels_.size()); for (const auto channel: safe_copy()) { const auto handle_send = [=](code ec) { handle_channel(ec, channel); if (counter->fetch_sub(1) == 1) handle_complete(error::success); }; channel->send(std::forward<Message>(message), handle_send); } }
future<void> when_all_ready(ForwardIterator first, ForwardIterator last) { auto const diff = std::distance(first, last); if (diff <= 0) return make_ready_future(); typedef typename std::iterator_traits<ForwardIterator>::difference_type diff_t; auto counter = std::make_shared<std::atomic<diff_t>>(diff); auto prm = std::make_shared<promise<void>>(); auto dec = std::bind([=](){ if (counter->fetch_sub(1) == 1) prm->set_value(); }); // bind to ignore all arguments std::for_each(first, last, [=](typename std::iterator_traits<ForwardIterator>::reference f) mutable { if (!f.valid()) dec(); else f.get_state(detail::use_private_interface)->continue_with(dec); }); return prm->get_future(); }
__host__ __device__ int_type operator-=(int_type val) volatile { return fetch_sub(val) + val; }
__host__ __device__ int_type operator--(int) volatile { return fetch_sub(1); }
T operator -= (add_type value) { return fetch_sub(value) + value; }
T operator -- () { return fetch_sub(1) - 1; }
T operator -- (int) { return fetch_sub(1); }