void plain_arguments(Executor& exec) { void_f4_count.store(0); int_f4_count.store(0); { future<void> f1 = dataflow(exec, &void_f4, 42); future<int> f2 = dataflow(exec, &int_f4, 42); f1.wait(); HPX_TEST_EQ(void_f4_count, 1u); HPX_TEST_EQ(f2.get(), 84); HPX_TEST_EQ(int_f4_count, 1u); } void_f5_count.store(0); int_f5_count.store(0); { future<void> f1 = dataflow(exec, &void_f5, 42, async(&int_f)); future<int> f2 = dataflow(exec, &int_f5, 42, async(&int_f)); f1.wait(); HPX_TEST_EQ(void_f5_count, 1u); HPX_TEST_EQ(f2.get(), 126); HPX_TEST_EQ(int_f5_count, 1u); } }
bool test_bitops(boost::atomic<value_type> & shared_value, size_t instance) { size_t shift = instance * 8; value_type mask = 0xff << shift; value_type expected = 0; for (size_t k = 0; k < 8; k++) { value_type mod = 1 << k; value_type tmp = shared_value.fetch_or(mod << shift, boost::memory_order_relaxed); if ( (tmp & mask) != (expected << shift)) return false; expected = expected | mod; } for (size_t k = 0; k < 8; k++) { value_type tmp = shared_value.fetch_and( ~ (1 << (shift + k)), boost::memory_order_relaxed); if ( (tmp & mask) != (expected << shift)) return false; expected = expected & ~(1<<k); } for (size_t k = 0; k < 8; k++) { value_type mod = 255 ^ (1 << k); value_type tmp = shared_value.fetch_xor(mod << shift, boost::memory_order_relaxed); if ( (tmp & mask) != (expected << shift)) return false; expected = expected ^ mod; } value_type tmp = shared_value.fetch_and( ~mask, boost::memory_order_relaxed); if ( (tmp & mask) != (expected << shift) ) return false; return true; }
namespace Common { UString generateIDRandomString() { std::stringstream ss; ss << boost::uuids::random_generator()(); return ss.str(); } static boost::atomic<uint32> idNumber(1); uint32 generateIDNumber() { return idNumber.fetch_add(1); } static UString uint64ToString(uint64 i) { std::string str; str.reserve(20); do { str += "0123456789"[i % 10]; i /= 10; } while (i); std::reverse(str.begin(), str.end()); return str; } static boost::atomic<uint64> idNumberString(1); UString generateIDNumberString() { return uint64ToString(idNumberString.fetch_add(1)); } } // End of namespace Common
inline T get_and_reset_value(boost::atomic<T>& value, bool reset) { T result = value.load(); if (reset) value.store(0); return result; }
void plain_deferred_arguments() { void_f4_count.store(0); int_f4_count.store(0); { future<void> f1 = dataflow(hpx::launch::deferred, &void_f4, 42); future<int> f2 = dataflow(hpx::launch::deferred, &int_f4, 42); f1.wait(); HPX_TEST_EQ(void_f4_count, 1u); HPX_TEST_EQ(f2.get(), 84); HPX_TEST_EQ(int_f4_count, 1u); } void_f5_count.store(0); int_f5_count.store(0); { future<void> f1 = dataflow(&void_f5, 42, async(hpx::launch::deferred, &int_f)); future<int> f2 = dataflow(&int_f5, 42, async(hpx::launch::deferred, &int_f)); f1.wait(); HPX_TEST_EQ(void_f5_count, 1u); HPX_TEST_EQ(f2.get(), 126); HPX_TEST_EQ(int_f5_count, 1u); } }
void LoggingStreamImpl::UpdateIsLogging() const { m_lastLoggingFilterChangeCount.store( g_LoggingFilterChangeCount.load() ); boost::log::record testRecord = m_logger.open_record( boost::log::keywords::severity = m_severityLevel ); m_isLogging.store( (bool)testRecord ); }
// run an inlet for some time (optionally with sporadic interruptions in between) void run_inlet(const double duration_=0.0, const string name_=string(), const string type_=string(), const int in_chunks_=-1, const int request_info_=-1, const int request_time_=-1, const double seconds_between_failures_=0.0) { num_inlets.fetch_add(1); std::ostringstream s; s << boost::this_thread::get_id(); srand((unsigned)boost::hash<string>()(s.str())); try { // choose random parameters if desired double duration = (duration_ == 0.0) ? 1.0+rand()%(max_outlet_duration-1) : duration_; string name = name_.empty() ? names[rand()%(sizeof(names)/sizeof(names[0]))] : name_; string type = type_.empty() ? types[rand()%(sizeof(types)/sizeof(types[0]))] : type_; int request_info = (request_info_==-1) ? rand()%3 == 0 : request_info_; int request_time = (request_time_==-1) ? rand()%3 == 0 : request_time_; double seconds_between_failures = (seconds_between_failures_ == 0.0) ? (inlet_min_failure_interval_ms+rand()%outlet_max_failure_interval_ms)/1000.0 : seconds_between_failures_; // resolve by type... vector<lsl::stream_info> results = lsl::resolve_stream("type",type,1,5); if (results.empty()) throw lsl::lost_error("No stream found."); lsl::stream_info result = results[rand()%results.size()]; vector<float> chunk; // and run... double t=0.0; for (double endtime = lsl::local_clock()+duration;lsl::local_clock()<endtime;) { // run a single execution of the inlet { cout << "new inlet(" << name << "," << type << ")..."; lsl::stream_inlet inlet(result,max_buffered); cout << "done." << endl; int numchans = inlet.info().channel_count(); init_sample(numchans*(int)ceil(max_chunk_len_ms*result.nominal_srate()/1000*max_chunk_oversize_factor),chunk); if (request_info) { cout << " info = " << inlet.info(1.0).name() << endl; } for (double fail_at = lsl::local_clock()+seconds_between_failures;lsl::local_clock()<fail_at;) { boost::this_thread::sleep(boost::posix_time::milliseconds(1+rand()%max_inlet_poll_interval_ms)); inlet.pull_chunk_multiplexed(&chunk[0],NULL,chunk.size(),0); if (request_time) t = inlet.time_correction(1.0); } } cout << "del inlet(" << name << "," << type << ")" << endl; if (request_time) cout << " tcorr = " << t << endl; // downtime boost::this_thread::sleep(boost::posix_time::millisec(100*(rand()%50))); } } catch(lsl::timeout_error &) { std::cerr << "Timeout exceeded; stopping inlet." << std::endl; } catch(lsl::lost_error &) { std::cerr << "Found no matching outlet; stopping inlet." << std::endl; } catch(std::exception &e) { std::cerr << "ERROR during run_inlet() Stress-test function: " << e.what() << std::endl; } num_inlets.fetch_sub(1); }
/** * The environment should be initialised exactly once during shared library initialisation. * Prior to that, all operations work in pass-through mode. * To overcome undefined global initialisation order, we use a local static variable. * This variable is accesd by a single writer (lib (de)initialisation), and multiple readers (exported operations). * Writer: toggle == true (toggles is_initialised) * Reader: toggle == false (returns the current value of is_initialised) * * NOTE: pthread_once initialisation for the overlay leads to a deadlock due to a re-entry situation: * - environment ctor is called the first time via pthread_once * - which leads a write somewhere (probably to a socket during client initialisation) * - which then enters the pthread_once initialisation mechanism again and blocks deadlocks */ bool overlay_initialized(bool toggle /* defaults to: false */) { static boost::atomic<bool> is_initilized(false); // writer if(toggle) { return is_initilized.exchange(!is_initilized.load()); } // reader return is_initilized.load(); }
void future_function_pointers() { future_void_f1_count.store(0); future_void_f2_count.store(0); future<void> f1 = dataflow( &future_void_f1, async(&future_void_sf1, shared_future<void>(make_ready_future())) ); f1.wait(); HPX_TEST_EQ(future_void_f1_count, 2u); future_void_f1_count.store(0); future<void> f2 = dataflow( &future_void_f2 , async(&future_void_sf1, shared_future<void>(make_ready_future())) , async(&future_void_sf1, shared_future<void>(make_ready_future())) ); f2.wait(); HPX_TEST_EQ(future_void_f1_count, 2u); HPX_TEST_EQ(future_void_f2_count, 1u); future_void_f1_count.store(0); future_void_f2_count.store(0); future<int> f3 = dataflow( &future_int_f1 , make_ready_future() ); HPX_TEST_EQ(f3.get(), 1); HPX_TEST_EQ(future_int_f1_count, 1u); future_int_f1_count.store(0); future<int> f4 = dataflow( &future_int_f2 , dataflow(&future_int_f1, make_ready_future()) , dataflow(&future_int_f1, make_ready_future()) ); HPX_TEST_EQ(f4.get(), 2); HPX_TEST_EQ(future_int_f1_count, 2u); HPX_TEST_EQ(future_int_f2_count, 1u); future_int_f1_count.store(0); future_int_f2_count.store(0); future_int_f_vector_count.store(0); std::vector<future<int> > vf; for(std::size_t i = 0; i < 10; ++i) { vf.push_back(dataflow(&future_int_f1, make_ready_future())); } future<int> f5 = dataflow(&future_int_f_vector, boost::ref(vf)); HPX_TEST_EQ(f5.get(), 10); }
void call_void() { ++count_call_void; // make sure this function is not concurrently invoked HPX_TEST_EQ(count_active_call_void.fetch_add(1) + 1, 1); hpx::this_thread::suspend(boost::chrono::microseconds(100)); --count_active_call_void; HPX_TEST_EQ(count_active_call_void.load(), 0); }
void init_globals() { // Retrieve command line using the Boost.ProgramOptions library. boost::program_options::variables_map vm; if (!hpx::util::retrieve_commandline_arguments(get_commandline_options(), vm)) { HPX_THROW_EXCEPTION(hpx::commandline_option_error, "fibonacci_futures_distributed", "failed to handle command line options"); return; } boost::uint64_t n = vm["n-value"].as<boost::uint64_t>(); threshold = vm["threshold"].as<unsigned int>(); if (threshold < 2 || threshold > n) { HPX_THROW_EXCEPTION(hpx::commandline_option_error, "fibonacci_futures_distributed", "wrong command line argument value for option 'threshold', " "should be in between 2 and n-value, value specified: " + std::to_string(threshold)); return; } distribute_at = vm["distribute-at"].as<unsigned int>(); if (distribute_at < 2 || distribute_at > n) { HPX_THROW_EXCEPTION(hpx::commandline_option_error, "fibonacci_futures_distributed", "wrong command line argument value for option 'distribute-at', " "should be in between 2 and n-value, value specified: " + std::to_string(distribute_at)); return; } here = hpx::find_here(); next_locality.store(0); serial_execution_count.store(0); // try to more evenly distribute the work over the participating localities std::vector<hpx::id_type> locs = hpx::find_all_localities(); std::size_t num_repeats = vm["loc-repeat"].as<int>(); localities.push_back(here); // add ourselves for (std::size_t j = 0; j != num_repeats; ++j) { for (std::size_t i = 0; i != locs.size(); ++i) { if (here == locs[i]) continue; localities.push_back(locs[i]); } } }
bool try_basic_lock(thread_id_type current_thread_id) { if (mtx.try_lock()) { locking_thread_id.exchange(current_thread_id); util::ignore_lock(&mtx); util::register_lock(this); recursion_count.store(1); return true; } return false; }
inline bool interlocked_bit_test_and_set(boost::atomic<T>& x, long bit) { T const value = 1u << bit; boost::uint32_t old = x.load(boost::memory_order_acquire); do { boost::uint32_t tmp = old; if (x.compare_exchange_strong(tmp, T(old | value))) break; old = tmp; } while(true); return (old & value) != 0; }
TORRENT_NO_RETURN TORRENT_EXPORT void assert_fail(char const* expr, int line , char const* file, char const* function, char const* value, int kind) { #ifdef TORRENT_PRODUCTION_ASSERTS // no need to flood the assert log with infinite number of asserts if (assert_counter.fetch_add(1) + 1 > 500) return; #endif char stack[8192]; stack[0] = '\0'; print_backtrace(stack, sizeof(stack), 0); char const* message = "assertion failed. Please file a bugreport at " "http://code.google.com/p/libtorrent/issues\n" "Please include the following information:\n\n" "version: " LIBTORRENT_VERSION "\n" LIBTORRENT_REVISION "\n"; switch (kind) { case 1: message = "A precondition of a libtorrent function has been violated.\n" "This indicates a bug in the client application using libtorrent\n"; } assert_print("%s\n" #ifdef TORRENT_PRODUCTION_ASSERTS "#: %d\n" #endif "file: '%s'\n" "line: %d\n" "function: %s\n" "expression: %s\n" "%s%s\n" "stack:\n" "%s\n" , message #ifdef TORRENT_PRODUCTION_ASSERTS , assert_counter.load() #endif , file, line, function, expr , value ? value : "", value ? "\n" : "" , stack); // if production asserts are defined, don't abort, just print the error #ifndef TORRENT_PRODUCTION_ASSERTS // send SIGINT to the current process // to break into the debugger raise(SIGINT); abort(); #endif }
// run an outlet for some time (optionally with sporadic interruptions in between) void run_outlet(const double duration_=0.0, const string name_=string(), const string type_=string(), const int numchan_=0, const lsl::channel_format_t fmt_=lsl::cf_undefined, const double srate_=0.0, const double seconds_between_failures_=0.0, const int chunk_len_=0) { num_outlets.fetch_add(1); std::ostringstream s; s << boost::this_thread::get_id(); srand((unsigned)boost::hash<string>()(s.str())); try { // choose random parameters if desired double duration = (duration_ == 0.0) ? 1.0+rand()%(max_outlet_duration-1) : duration_; string name = name_.empty() ? names[rand()%(sizeof(names)/sizeof(names[0]))] : name_; string type = type_.empty() ? types[rand()%(sizeof(types)/sizeof(types[0]))] : type_; int numchan = (numchan_ == 0) ? 1+(rand()%(max_channels-1)) : numchan_; double srate = (srate_ == 0.0) ? 1.0 + (rand()%(max_srate-1)) : srate_; lsl::channel_format_t fmt = (fmt_ == lsl::cf_undefined) ? fmts[rand()%6] : fmt_; double seconds_between_failures = (seconds_between_failures_ == 0.0) ? (inlet_min_failure_interval_ms+rand()%outlet_max_failure_interval_ms)/1000.0 : seconds_between_failures_; int chunk_len = (chunk_len_ == 0) ? std::max(min_chunk_len_ms,(rand()%max_chunk_len_ms)) : chunk_len_; // create a new streaminfo lsl::stream_info info(name,type,numchan,srate,fmt,boost::uuids::to_string(boost::uuids::random_generator()())); // initialize data to send vector<float> chunk; init_sample((int)(numchan*floor(chunk_len*srate/1000*max_chunk_oversize_factor)),chunk); // and run... for (double endtime = lsl::local_clock()+duration;lsl::local_clock()<endtime;) { // run a single execution of the outlet { cout << "new outlet(" << name << "," << type << "," << numchan << "," << fmt << "," << srate << ")..."; lsl::stream_outlet outlet(info,0,max_buffered); cout << "done." << endl; // send in bursts double now, start_time = lsl::local_clock(), fail_at=start_time+seconds_between_failures; for (int target,diff,written=0;written<max_samples && !stop_outlet;written+=diff) { boost::this_thread::sleep(boost::posix_time::milliseconds(chunk_len)); now = lsl::local_clock(); if (now>fail_at) break; target = (int)floor((now-start_time)*srate); int num_elements = (int)std::min((std::size_t)((target-written)*numchan),chunk.size()); if (num_elements) outlet.push_chunk_multiplexed(&chunk[0],num_elements); diff = num_elements/numchan; } } cout << "del outlet(" << name << "," << type << "," << numchan << "," << fmt << "," << srate << ")" << endl; // downtime boost::this_thread::sleep(boost::posix_time::millisec(100*(rand()%50))); } } catch(std::exception &e) { std::cerr << "ERROR during run_outlet() Stress-test function: " << e.what() << std::endl; } num_outlets.fetch_sub(1); }
scheduled_executor default_executor() { if (!default_executor_instance.load()) { scheduled_executor& default_exec = scheduled_executor::default_executor(); scheduled_executor empty_exec; default_executor_instance.compare_exchange_strong( empty_exec, default_exec); } return default_executor_instance.load(); }
/// Acquires ownership of the \a recursive_mutex. Suspends the /// current HPX-thread if ownership cannot be obtained immediately. /// /// \throws Throws \a hpx#bad_parameter if an error occurs while /// suspending. Throws \a hpx#yield_aborted if the mutex is /// destroyed while suspended. Throws \a hpx#null_thread_id if /// called outside of a HPX-thread. void lock() { thread_id_type const id = thread_id_from_mutex<Mutex>::call(); HPX_ASSERT(id != thread_id_from_mutex<Mutex>::invalid_id()); if (!try_recursive_lock(id)) { mtx.lock(); locking_thread_id.exchange(id); util::ignore_lock(&mtx); util::register_lock(this); recursion_count.store(1); } }
void test_timed_executor(std::array<std::size_t, 4> expected) { typedef typename hpx::traits::executor_execution_category< Executor >::type execution_category; HPX_TEST((std::is_same< hpx::parallel::execution::sequenced_execution_tag, execution_category >::value)); count_sync.store(0); count_apply.store(0); count_sync_at.store(0); count_apply_at.store(0); Executor exec; test_timed_apply(exec); test_timed_sync(exec); test_timed_async(exec); HPX_TEST_EQ(expected[0], count_sync.load()); HPX_TEST_EQ(expected[1], count_apply.load()); HPX_TEST_EQ(expected[2], count_sync_at.load()); HPX_TEST_EQ(expected[3], count_apply_at.load()); }
hpx::future<void> plain_future_void() { ++count_plain_future_void; // make sure this function is not concurrently invoked HPX_TEST_EQ(count_active_plain_future_void.fetch_add(1) + 1, 1); hpx::this_thread::suspend(boost::chrono::microseconds(100)); --count_active_plain_future_void; HPX_TEST_EQ(count_active_plain_future_void.load(), 0); return hpx::make_ready_future(); }
int hpx_main(int argc, char** argv_init) { hpx::new_<test_server>(hpx::find_here(), moveonly()).get(); HPX_TEST_EQ(constructed_from_moveonly.load(), 1); moveable o; hpx::new_<test_server>(hpx::find_here(), o).get(); HPX_TEST_EQ(constructed_from_moveable.load(), 1); hpx::new_<test_server>(hpx::find_here(), moveable()).get(); HPX_TEST_EQ(constructed_from_moveable.load(), 2); return hpx::finalize(); }
void calc_block( hpxla::local_matrix_view<boost::int64_t>& H , hpxla::local_matrix_view<hpx::future<void> >& C // Control matrix. , coords start // The start of our cell block. , coords end // The end of our cell block. , coords control // Our location in the control matrix. , std::string const& a , std::string const& b ) { // TODO: Handle this with hpx::wait_all? C(control.i, control.j-1).get(); C(control.i-1, control.j-1).get(); C(control.i-1, control.j ).get(); winner local_best = H_best.load(); // Generate scores. for (boost::uint32_t i = start.i; i < end.i; ++i) { for (boost::uint32_t j = start.j; j < end.j; ++j) { H(i, j) = calc_cell(i, j, a[i-1], b[j-1] , H(i, j-1) // left , H(i-1, j-1) // diagonal , H(i-1, j ) // up ); if (H(i, j) > local_best.value) { local_best.value = H(i, j); local_best.i = i; local_best.j = j; } } } winner H_best_old = H_best.load(); while (true) { if (local_best.value > H_best_old.value) { if (H_best.compare_exchange_weak(H_best_old, local_best)) break; } else break; } }
void run(void) { BOOST_WARN(stk.is_lock_free()); running.store(true); thread_group writer; thread_group reader; BOOST_REQUIRE(stk.empty()); for (int i = 0; i != reader_threads; ++i) reader.create_thread(boost::bind(&stack_tester::get_items, this)); for (int i = 0; i != writer_threads; ++i) writer.create_thread(boost::bind(&stack_tester::add_items, this)); using namespace std; cout << "threads created" << endl; writer.join_all(); cout << "writer threads joined, waiting for readers" << endl; running = false; reader.join_all(); cout << "reader threads joined" << endl; BOOST_REQUIRE_EQUAL(data.count_nodes(), 0); BOOST_REQUIRE(stk.empty()); BOOST_REQUIRE_EQUAL(push_count, pop_count); BOOST_REQUIRE_EQUAL(push_count, writer_threads * node_count); }
//! デバイスを閉じる void CloseDevice() { terminated_.store(true); process_thread_.join(); waveOutReset(hwo_); waveOutClose(hwo_); //! waveOutResetを呼び出したあとで //! WAVEHDRの使用済み通知が来ることがある。 //! つまり、waveOutResetを呼び出した直後に //! すぐにWAVEHDRを解放できない(デバイスによって使用中かもしれないため) //! そのため、確実にすべてのWAVEHDRの解放を確認する。 for( ; ; ) { int left = 0; for(auto &header : headers_ | boost::adaptors::indirected) { if(header.get()->dwUser == WaveHeader::DONE) { waveOutUnprepareHeader(hwo_, header.get(), sizeof(WAVEHDR)); header.get()->dwUser = WaveHeader::UNUSED; } else if(header.get()->dwUser == WaveHeader::USING) { left++; } } if(!left) { break; } Sleep(10); } hwo_ = NULL; }
void increment(hpx::id_type const& there, boost::int32_t i) { locality_id = hpx::get_locality_id(); accumulator += i; hpx::apply(receive_result_action(), there, accumulator.load()); }
void lock() { while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) { /* busy-wait */ } }
void push_back(T elem) { // Construct an element to hold it synclist_item<T>* itm = new synclist_item<T>(); itm->value = elem; itm->prev.store(m_last.load(boost::memory_order_release), boost::memory_order_acquire); itm->next.store(NULL, boost::memory_order_acquire); // Insert the element in the list synclist_item<T>* tmpItm = itm; synclist_item<T>* prevLast = m_last.exchange(tmpItm, boost::memory_order_consume); tmpItm = itm; synclist_item<T>* null = NULL; m_first.compare_exchange_strong(null, tmpItm, boost::memory_order_consume, boost::memory_order_acquire); if(prevLast != NULL) { prevLast->next.store(itm, boost::memory_order_consume); } m_length.fetch_add(1, boost::memory_order_consume); }
int main(int argc, char* argv[]) { accumulator.store(0); // Initialize and run HPX HPX_TEST_EQ_MSG(hpx::init(argc, argv), 0, "HPX main exited with non-zero status"); return hpx::util::report_errors(); }
bool compare_exchange(T* expected, T* desired, T** old = NULL) { bool success = ptr.compare_exchange_strong(expected, desired); if(success && expected != desired) { intrusive_ptr_add_ref(desired); intrusive_ptr_release(expected); } if(old) *old = expected; return success; }
boost::int64_t calc_cell( boost::uint32_t i , boost::uint32_t j , char ai , char bj , hpx::future<boost::int64_t> const& left // H(i, j-1) , hpx::future<boost::int64_t> const& diagonal // H(i-1, j-1) , hpx::future<boost::int64_t> const& up // H(i-1, j) ) { boost::int64_t match_mismatch = 0; if (ai == bj) { match_mismatch = diagonal.get() + match; } else { match_mismatch = diagonal.get() + mismatch; } boost::int64_t deletion = up.get() + gap; boost::int64_t insertion = left.get() + gap; boost::int64_t ij_value = maximum(boost::int64_t(0), match_mismatch, deletion, insertion); winner H_best_old = H_best.load(); while (true) { winner H_best_new(ij_value, i, j); if (H_best_new.value > H_best_old.value) { if (H_best.compare_exchange_weak(H_best_old, H_best_new)) break; } else break; } return ij_value; }
virtual ~SessionMaintainerRequest() { #if ! defined(NDEBUG) const int object_count = session_maintainer_request_count.fetch_sub(1, boost::memory_order_release); # ifdef OUTPUT_DEBUG // Debug code std::cout << "--SessionMaintainerRequest: " << (object_count-1) << std::endl; # endif assert(object_count > 0); #endif }