boostorg / fiber Goto Github PK
View Code? Open in Web Editor NEWuserland threads
userland threads
std::uniform_int_distribution
is a stateful class. Please do not initialize it at every random call.
Example:
https://github.com/boostorg/fiber/blob/master/src/algo/work_stealing.cpp#L61
Some ARM processors do not support "yield" instruction used in include/boost/fiber/detail/cpu_relax.hpp.
Compilation with GCC will generate error messages such as:
/tmp/ccUV8Ii4.s: Assembler messages:
/tmp/ccUV8Ii4.s:2171: Error: selected processor does not support ARM mode `yield'
This problem will happen on Raspbian (-march=armv6) and Debian armel (-march=armv4t I believe) for example.
Against boost 1.63 on amd64 linux
Calls to try_push
never cause any fibers already waiting on the channel to wake up.
#include <cassert>
#include <boost/fiber/all.hpp>
int main() {
boost::fibers::buffered_channel<int> channel(16);
auto f = boost::fibers::async([&]{
channel.value_pop();
});
boost::this_fiber::sleep_for(std::chrono::seconds(1));
// Hangs in `f.get()`
auto push_result = channel.try_push(0);
// Completes
// auto push_result = channel.push(0);
// Completes with out waiting
// auto push_result = channel.push_wait_for(0, std::chrono::minutes(1));
assert(push_result == boost::fibers::channel_op_status::success);
f.get();
}
I've noticed that try_push
is in the class synopsis, but not explicitly documented as it was on the deprecated channel types. Is it supposed to have identical behaviour to bounded_channel
?
With the github ASIO master branch having modifications for the networking TS, will (is) there be a branch/fork of fiber will be compatible with that?
There are multiple compile errors with boost 1.57 (beta1) and clang 3.6 in c++11 mode:
clang++11 -I ../include -o simple simple.cpp
In file included from simple.cpp:8:
In file included from ../include/boost/fiber/all.hpp:11:
In file included from ../include/boost/fiber/barrier.hpp:16:
In file included from ../include/boost/fiber/condition.hpp:24:
../include/boost/fiber/detail/scheduler.hpp:59:14: error: no viable conversion
from 'detail::thread_local_ptr<fiber_manager>' to
'boost::fibers::fiber_manager '
{ return t; }
^~
../include/boost/fiber/detail/scheduler.hpp:86:26: note: in instantiation of
member function
'boost::fibers::detail::thread_local_ptrboost::fibers::fiber_manager::get'
requested here
if ( ! instance_.get() )
^
../include/boost/fiber/detail/scheduler.hpp:71:10: error: no viable overloaded
'='
{ t_ = t; }
~~ ^ ~
../include/boost/fiber/detail/scheduler.hpp:87:23: note: in instantiation of
member function
'boost::fibers::detail::thread_local_ptrboost::fibers::fiber_manager::reset'
requested here
instance_.reset( new fiber_manager() );
^
../include/boost/fiber/detail/scheduler.hpp:36:7: note: candidate function (the
implicit copy assignment operator) not viable: no known conversion from
'boost::fibers::fiber_manager *' to 'const
boost::fibers::detail::thread_local_ptrboost::fibers::fiber_manager' for
1st argument
class thread_local_ptr : private noncopyable
^
In file included from simple.cpp:8:
In file included from ../include/boost/fiber/all.hpp:11:
In file included from ../include/boost/fiber/barrier.hpp:16:
In file included from ../include/boost/fiber/condition.hpp:24:
In file included from ../include/boost/fiber/detail/scheduler.hpp:20:
In file included from ../include/boost/fiber/fiber_manager.hpp:20:
../include/boost/fiber/fiber.hpp:109:32: error: call to 'forward' is ambiguous
detail::setup< Fn > s( forward< Fn >( fn), & coro);
^~~~~~~~~~~~~
simple.cpp:24:30: note: in instantiation of function template specialization
'boost::fibers::fiber::fiber<boost::bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::_bi::value
> > >' requested here
boost::fibers::fiber f1( boost::bind( fn, "abc", 5) );
^
/opt/local/libexec/llvm-3.6/bin/../include/c++/v1/type_traits:1612:1: note:
candidate function [with _Tp = boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::_bi::value
> >]
forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
^
/opt/local/include/boost/move/utility_core.hpp:219:21: note: candidate function
[with T = boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::bi::value
> >]
inline T&& forward(typename ::boost::move_detail::remove_refere...
^
In file included from simple.cpp:8:
In file included from ../include/boost/fiber/all.hpp:11:
In file included from ../include/boost/fiber/barrier.hpp:16:
In file included from ../include/boost/fiber/condition.hpp:24:
In file included from ../include/boost/fiber/detail/scheduler.hpp:20:
In file included from ../include/boost/fiber/fiber_manager.hpp:20:
In file included from ../include/boost/fiber/fiber.hpp:25:
../include/boost/fiber/detail/trampoline.hpp:46:13: error: call to 'forward' is
ambiguous
Fn fn( forward< Fn >( from->fn) );
^~~~~~~~~~~~~
../include/boost/fiber/fiber.hpp:108:50: note: in instantiation of function
template specialization
'boost::fibers::detail::trampoline<boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::_bi::value
> > >' requested here
typename coro_t::call_type coro( detail::trampoline< Fn >, attrs...
^
simple.cpp:24:30: note: in instantiation of function template specialization
'boost::fibers::fiber::fiber<boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::_bi::value
> > >' requested here
boost::fibers::fiber f1( boost::bind( fn, "abc", 5) );
^
/opt/local/libexec/llvm-3.6/bin/../include/c++/v1/type_traits:1612:1: note:
candidate function [with _Tp = boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char >, boost::_bi::value
> >]
forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
^
/opt/local/include/boost/move/utility_core.hpp:219:21: note: candidate function
[with T = boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char *>, boost::bi::value
> >]
inline T&& forward(typename ::boost::move_detail::remove_refere...
^
In file included from simple.cpp:8:
In file included from ../include/boost/fiber/all.hpp:11:
In file included from ../include/boost/fiber/barrier.hpp:16:
In file included from ../include/boost/fiber/condition.hpp:24:
In file included from ../include/boost/fiber/detail/scheduler.hpp:20:
In file included from ../include/boost/fiber/fiber_manager.hpp:18:
In file included from ../include/boost/fiber/detail/waiting_queue.hpp:19:
In file included from ../include/boost/fiber/detail/worker_fiber.hpp:18:
In file included from /opt/local/include/boost/coroutine/symmetric_coroutine.hpp:12:
In file included from /opt/local/include/boost/coroutine/detail/symmetric_coroutine_call.hpp:18:
/opt/local/include/boost/coroutine/detail/symmetric_coroutine_object.hpp:39:25: error:
data member instantiated with function type 'void
(boost::coroutines::detail::symmetric_coroutine_yield<void *> &)'
Fn fn;
^
/opt/local/include/boost/coroutine/detail/symmetric_coroutine_call.hpp:122:72: note:
in instantiation of template class
'boost::coroutines::detail::symmetric_coroutine_object<void *, void
(boost::coroutines::detail::symmetric_coroutine_yield<void *> &),
boost::coroutines::basic_standard_stack_allocatorboost::coroutines::stack_traits
>' requested here
internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( o...
^
../include/boost/fiber/fiber.hpp:108:36: note: in instantiation of function
template specialization
'boost::coroutines::detail::symmetric_coroutine_call<void
*>::symmetric_coroutine_call<void
(boost::coroutines::detail::symmetric_coroutine_yield<void > &)>'
requested here
typename coro_t::call_type coro( detail::trampoline< Fn >, attrs...
^
simple.cpp:24:30: note: in instantiation of function template specialization
'boost::fibers::fiber::fiber<boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char *>, boost::bi::value
> > >' requested here
boost::fibers::fiber f1( boost::bind( fn, "abc", 5) );
^
In file included from simple.cpp:8:
In file included from ../include/boost/fiber/all.hpp:11:
In file included from ../include/boost/fiber/barrier.hpp:16:
In file included from ../include/boost/fiber/condition.hpp:24:
In file included from ../include/boost/fiber/detail/scheduler.hpp:20:
In file included from ../include/boost/fiber/fiber_manager.hpp:18:
In file included from ../include/boost/fiber/detail/waiting_queue.hpp:19:
In file included from ../include/boost/fiber/detail/worker_fiber.hpp:18:
In file included from /opt/local/include/boost/coroutine/symmetric_coroutine.hpp:12:
/opt/local/include/boost/coroutine/detail/symmetric_coroutine_call.hpp:127:15: error:
assigning to 'impl_type *' (aka 'symmetric_coroutine_impl<void *> *') from
incompatible type 'object_t *' (aka 'symmetric_coroutine_object<void *,
void (boost::coroutines::detail::symmetric_coroutine_yield<void *> &),
stack_allocator> *')
impl = new ( internal_stack_ctx.sp) object_t(
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/boost/fiber/fiber.hpp:108:36: note: in instantiation of function
template specialization
'boost::coroutines::detail::symmetric_coroutine_call<void
*>::symmetric_coroutine_call<void
(boost::coroutines::detail::symmetric_coroutine_yield<void > &)>'
requested here
typename coro_t::call_type coro( detail::trampoline< Fn >, attrs...
^
simple.cpp:24:30: note: in instantiation of function template specialization
'boost::fibers::fiber::fiber<boost::_bi::bind_t<void, void ()(const
std::__1::basic_string &, int),
boost::_bi::list2<boost::_bi::value<const char *>, boost::_bi::value
> > >' requested here
boost::fibers::fiber f1( boost::bind( fn, "abc", 5) );
^
6 errors generated.
Hello,
I've been playing with boost::fibers and I've found something strange that might be a bug. It might also be me misusing / misunderstand how things work.
Initially, my goal was to integrate asio and fibers, so I've ready the tutorial and used the fibers::asio::round_robin
algorithm.
Consider the following simple program.
int main()
{
// assert(!boost::fibers::has_ready_fibers()); Assertion would fail. Weird?
boost::asio::io_service io_service_;
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_service_);
io_service_.run();
return 0;
}
This causes the program to run at 100% cpu usage. I've tried to debug a bit, but without much success. It seems that has_ready_fibers()
always returns true, causing the CPU to spin.
As you can see, even without setting any scheduling algorithm, has_ready_fibers()
returns true when there should be no such ready fibers.
I've tried to show the issue with an even simpler program. So I've added debug print in the library and recompiled.
This is the modified has_ready_fibers()
for boost::fibers::algo::round_robin
(the default algorithm)
// The modified has_ready_fibers() for debug output
bool
round_robin::has_ready_fibers() const noexcept {
std::cout << "In has_ready_fibers(), will list ready fibers. Current fiber id: "
<< context::active()->get_id() << std::endl;
for (const auto &f : rqueue_)
{
std::cout << "\tFiber: " << f.get_id() << std::endl;
}
return ! rqueue_.empty();
}
And this is the corresponding program that shows the issue.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/fiber/all.hpp>
int main()
{
std::cout << "My fiber id: " << boost::this_fiber::get_id() << std::endl;
boost::fibers::has_ready_fibers();
}
/*
The follwing is outputed by the program.
My fiber id: 0x1d5f270
In has_ready_fibers(), will list ready fibers. Current fiber id: 0x1d5f270
Fiber: 0x1d6f3a8
*/
It seems there is a fiber that comes from I don't know where, and seems to cause some
issue.
Now it's quite possible that I'm missing something, so please let me know if that's the case.
Thanks,
When i use condition_variable::wait_for in multipliy fibers program crashes with assertion:
"Assertion failed: ! ctx->ready_is_linked(), file libs\fiber\src\scheduler.cpp, line 192".
Minimal sample:
#include <boost/fiber/all.hpp>
#include <mutex>
#include <thread>
#include <chrono>
int main()
{
boost::fibers::condition_variable condvar;
boost::fibers::mutex mutex;
auto do_work = [&]()
{
while (true)
{
{
std::unique_lock<boost::fibers::mutex> lock(mutex);
condvar.wait_for(lock, std::chrono::milliseconds(50));
}
//emulate some calculations
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
};
boost::fibers::fiber fiber1(do_work);
boost::fibers::fiber fiber2(do_work);
boost::fibers::fiber fiber3(do_work);
boost::fibers::fiber fiber4(do_work);
boost::fibers::fiber fiber5(do_work);
boost::fibers::fiber fiber6(do_work);
boost::fibers::fiber fiber([&]()
{
while (true)
{
{
std::lock_guard<boost::fibers::mutex> lock(mutex);
condvar.notify_one();
}
boost::this_fiber::sleep_for(std::chrono::milliseconds(10));
}
});
fiber.join();
return 0;
}
Compiler msvc-14.0, windows 7.
It's possible to use a future to return a move-only object?
This code doesn't compile (gcc 4.9.2 / clang 3.6) (fibers master branch)
#include <boost/fiber/all.hpp>
#include <iostream>
struct A {
A() = default;
A(A const&) = delete;
A(A&&) = default;
int value;
};
int main() {
using namespace boost::fibers;
promise<A> p;
auto future = p.get_future();
std::cout << future.get().value << std::endl;
}
gcc output (trimmed):
./support/deps/include/boost/fiber/future/future.hpp: In instantiation of ‘R boost::fibers::future<R>::get() [with R = A]’:
tests/c.cpp:17:29: required from here
./support/deps/include/boost/fiber/future/future.hpp:80:25: error: use of deleted function ‘A::A(const A&)’
return tmp->get();
^
tests/c.cpp:6:5: note: declared here
A(A const&) = delete;
The purpose of the context::suspend() function is to enable low-overhead integration of other frameworks and boost::fiber. Using it however is almost impossible without introducing races. Assume that we want to integrate existing code that performs some asynchronous action. We want it to suspend the current fiber and resume it on completion. This results in the following code:
// Queue of all blocked fibers.
boost::intrusive::list<boost::fibers::context> queue;
// In a multithreaded environment we must protect the queue.
std::mutex mutex;
std::unique_lock<std::mutex> lock{mutex};
// Initiate the asynchronous action.
boost::fibers::active().wait_link(queue);
lock.unlock();
// RACE: Another thread can take the mutex, invoke set_ready() and yield() to the fiber
// here even though it is not suspended yet!
boost::fibers::context::suspend();
I do not see how this race can be avoided with the current design of suspend(). Internally the race is avoided by using the suspend(detail::spin_lock &) overload. That interface however is not documented and inflexible.
I propose that suspend() should be replaced either by
// Futex-style: Suspend the fiber. Then evaluate the predicate and immediately
// set_ready() the fiber if it evaluates to true.
template<typename P> // Must be a bool() function object.
void suspend_if(P predicate);
or by
// Suspend the fiber and evaluate the cleanup function in the scheduler's context.
template<typename F>
void suspend(F cleanup);
These functions would be more flexible than suspend(detail::spin_lock &): For example they allow synchronization via std::atomic instead of spinlocks. Another option would be implementing the proposed std::synchronic class for fibers.
compiler: vc2017 WIN32
boost: 1.64 --with-context --with-fiber asmflags=/safeseh
code:
boost::fibers::promise<void> p; // 1
boost::fibers::fiber f(boost::fibers::launch::dispatch, [&p]() mutable {
auto f = p.get_future(); // 2
auto r = f.wait_for(std::chrono::seconds{0}); // 3
});
p.set_value(); //4 crash!
boost::this_fiber::yield(); //5
f.join();
error message:
Assertion failed: ! ctx->ready_is_linked(), file libs\fiber\src\scheduler.cpp, line 223
Hello Oliver,
I contacted you a week ago to ask which development branch to use. I saw that in the meantime develop
became the one.
I just got around to starting to work with Boost Fiber. I built it with modular Boost (which btw. wasn't trivial) and wanted to re-read the Asio examples and start coding. I have to use Fibers together with Asio. Unfortunately, I saw that yesterday you have first modified and then deleted the Asio-related examples. Doesn't the integration with Asio work anymore? If so, then what do you recommend? Can the Asio-related problems be fixed easily? Or should I use an older commit or the old master branch?
Thank you very much!
Best regards,
Emil
PS: my use of Fibers would be simple: One main fiber that creates other fibers for doing some work. This work includes asynchronous I/O through Asio, for which the fiber should yield. I'd also like to have a simple scheduler. All fibers would run on the same thread.
I am calling try_value_pop() in the buffered channel and end up in an endless loop.
try_pop_: full=0 empty=0 capacity=1 closed=0 producers=0 consumers=0 consumer_idx_=0 slots_[0].cycle.load()=2
My guess is that idx
is 0 in try_value_pop_()
. diff
is 1 (2-(idx+1)) and the loop reloads consumer_idx_
which is 0.
Do you have any ideas how I ended up here? Thanks in advance.
I'm trying to run the skynet benchmarks on windows, and find that they all crash. I build with visual studio 2015 and tag boost-1.63.0.
The crash is an access violation down in context:
skynet.exe!boost::intrusive::list_node_traits<void * __ptr64>::set_next(boost::intrusive::list_node<void *> * const & n, boost::intrusive::list_node<void *> * const & next) Line 66 C++
skynet.exe!boost::intrusive::circular_list_algorithms<boost::intrusive::list_node_traits<void * __ptr64> >::unlink(boost::intrusive::list_node<void *> * const & this_node) Line 146 C++
skynet.exe!boost::intrusive::list_impl<boost::intrusive::mhtraits<boost::fibers::context,boost::intrusive::list_member_hook<boost::intrusive::tagboost::fibers::detail::ready_tag,boost::intrusive::link_mode<2>,void>,104>,unsigned __int64,0,void>::pop_front_and_disposeboost::intrusive::detail::null_disposer(boost::intrusive::detail::null_disposer disposer) Line 349 C++
skynet.exe!boost::fibers::algo::round_robin::pick_next() Line 36 C++
skynet.exe!boost::fibers::scheduler::dispatch() Line 153 C++
skynet.exe!boost::fibers::context::(boost::context::execution_context<boost::fibers::detail::data_t *> ctx, boost::fibers::detail::data_t * dp) Line 225 C++
[External Code]
skynet.exe!make_fcontext() Line 158 Unknown
I'm trying to get boost fiber to work on OS 10.10.4. The first issue I had was the OS X version of Clang doesn't support thread_local for some reason. I was considering switching fiber over to boost thread local storage instead of using thread_local, but I figured I would just try just using GCC-5.1.0 and link with stdlibc++ instead.
Building boost modular and boost fiber was successful, and building the fiber example "simple.cpp" was also successful, but it fails with segmentation faults. Any idea what's going on?
Maybe I'll hack it to use boost thread local storage so the standard clang will work instead..
I believe I may have found a race condition pertaining to the ASIO completion handler.
In the current implementation, a fiber may be scheduled when it was never suspended.
the check: if ( fibers::context::active() != ctx_) {
in yield_handler_base::operator() is in no way a guarantee that a fiber needs to be rescheduled.
I have solved this issue in my local implementation by implementing the following:
struct yield_completion {
typedef fibers::detail::spinlock mutex_t;
typedef std::unique_lock< mutex_t > lock_t;
typedef boost::intrusive_ptr< yield_completion > ptr_t;
std::atomic< std::size_t > use_count_{ 0 };
mutex_t mtx_{};
enum complete_state {init, waiting, complete};
complete_state completed_{ init };
void wait() {
// yield_handler_base::operator()() will set completed_ true and
// attempt to wake a suspended fiber. It would be Bad if that call
// happened between our detecting (! completed_) and suspending.
// If completed_ is already set, we're done here: don't suspend.
lock_t lk{ mtx_ };
if (!(completed_ == complete)) {
// suspend(unique_lock<spinlock>) unlocks the lock in the act of
// resuming another fiber
completed_ = waiting;
fibers::context::active()->suspend(lk);
}
}
`
`
// completion callback passing only (error_code)
void operator()(boost::system::error_code const& ec) {
BOOST_ASSERT_MSG(ycomp_,
"Must inject yield_completion* "
"before calling yield_handler_base::operator()()");
BOOST_ASSERT_MSG(yt_.ec_,
"Must inject boost::system::error_code* "
"before calling yield_handler_base::operator()()");
// If originating fiber is busy testing completed_ flag, wait until it
// has observed (! completed_).
yield_completion::lock_t lk{ ycomp_->mtx_ };
auto status = ycomp_->completed_;
// Notify a subsequent yield_completion::wait() call that it need not
// suspend.
ycomp_->completed_ = yield_completion::complete;
// set the error_code bound by yield_t
*yt_.ec_ = ec;
// unlock the lock that protects completed_
lk.unlock();
// If ctx_ is still active, e.g. because the async operation
// immediately called its callback (this method!) before the asio
// async function called async_result_base::get(), we must not
// schedule it, because it was suspended.
if (status == yield_completion::waiting) {
// wake the calling fiber
ctx_->get_scheduler()->schedule_from_remote(ctx_);
// fibers::context::active()->schedule(ctx_);
}
}
Also, see the last line of code above? I changed it from:
fibers::context::active()->schedule(ctx_);
to:
ctx_->get_scheduler()->schedule_from_remote(ctx_);
This change means that nothing fiber/scheduler wise is created in an thread running io_service::run();
I believe I found where this same change can be implemented to condition_variable and the result would be to notify a condition from a non-fiber thread with little performance penalty.
I know this is a simple description. I can attempt to explain more if necessary. But, right now my head hurts so bad right now from figuring this out!!!
Thoughts?
When trying to use Boost.Fiber with the tip of Boost.Context, I get a horrendous compilation error with basic use -- attached.
// Event the simplest case does not work:
boost::fibers::fiber f([] () {});
It looks like this broke with this change in Boost.Context: 43d89cb6396706871ce9378c8e3b2c63e93ffe0e - support passing argument between execution_context.
The preceding commit works perfectly fine for me: 01660915c1330a186ed0548b436065a9fc8ec96c
My compiler is g++ 5.2.1.
Hi. Thanks for this library! What is the best practice for using timer callbacks (asio + fibers)? I can see simple tcp example (echo), and the code is clear. But it would be great if example with asio timers would appear (or piece of code).
Thanks in advance!
Compiling the newest Boost release (version 1.64.0) fails when trying to compile Boost.Fiber as static library with GCC 4.8 and -std=c++11
.
This seems to be related to this issue with Boost.Context. The call to callcc
is an ambiguous overload.
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi
common.mkdir /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/algo
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/algo/algorithm.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/algo/round_robin.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/algo/shared_work.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/algo/work_stealing.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/barrier.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/condition_variable.o
gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/context.o
libs/fiber/src/context.cpp: In constructor ‘boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)’:
libs/fiber/src/context.cpp:236:14: error: call of overloaded ‘callcc(const std::allocator_arg_t&, const boost::context::preallocated&, const default_stack&, boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)::__lambda5)’ is ambiguous
});
^
libs/fiber/src/context.cpp:236:14: note: candidates are:
In file included from ./boost/fiber/context.hpp:28:0,
from libs/fiber/src/context.cpp:7:
./boost/context/continuation.hpp:469:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, StackAlloc, Fn&&, Arg ...) [with StackAlloc = boost::context::preallocated; Fn = const boost::context::basic_fixedsize_stack<boost::context::stack_traits>&; Arg = {boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)::__lambda5}]
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg ... arg) {
^
./boost/context/continuation.hpp:483:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, boost::context::preallocated, StackAlloc, Fn&&, Arg ...) [with StackAlloc = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)::__lambda5; Arg = {}]
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Arg ... arg) {
^
./boost/context/continuation.hpp:514:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, boost::context::preallocated, StackAlloc, Fn&&) [with StackAlloc = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)::__lambda5]
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn) {
^
./boost/context/continuation.hpp:457:1: note: boost::context::continuation boost::context::callcc(Fn&&, Arg ...) [with Fn = const std::allocator_arg_t&; Arg = {boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>, boost::fibers::context::context(boost::fibers::dispatcher_context_t, const boost::context::preallocated&, const default_stack&, boost::fibers::scheduler*)::__lambda5}; <template-parameter-1-3> = void]
callcc( Fn && fn, Arg ... arg) {
^
"g++-4.8" -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall -pthread -m64 -m64 -fpic -std=c++11 -m64 -fpic -DBOOST_ALL_NO_LIB=1 -DBOOST_DISABLE_ASSERTS -DBOOST_FIBERS_SOURCE -DNDEBUG -I"." -c -o "/home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/context.o" "libs/fiber/src/context.cpp"
...failed gcc.compile.c++ /home/jenkins/workspace/TEST_Boost_Build/gcc48/build/boost/boost/bin.v2/libs/fiber/build/gcc-4.8/release/link-static/threading-multi/context.o...
HTH,
Deniz Bahadir
PS: I reported this issue already for the beta releases of Boost 1.64.0 on the Boost mailing-list but it obviously got not much attention.
I'm trying to compile boost::fiber with Visual Studio 2017 and it's v140_xp
toolchain (that is the Visual Studio 2015 toolchain for Windows XP support - don't ask ...) targeting Windows XP 32bit.
As it is not directly possible with b2
to define the toolchain name for VS, one needs to set it via environment variables as described in this MS official blog post ("Targeting from the Command Line").
With the following batch file (to be run from within the Developer Command Prompt for VS 2017):
:: Setting additional parameters for XP toolchain
set INCLUDE=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
set PATH=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
set LIB=%ProgramFiles(x86)%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
set CL=/D_USING_V140_SDK71_;%CL%
call b2.exe --layout=versioned -q variant=debug,release link=static runtime-link=shared threading=multi cxxflags=/vmg linkflags=/SUBSYSTEM:CONSOLE,5.01 toolset=msvc-14.0 stage
boost::fiber fails to compile with the following error:
compile-c-c++ ..\all_build_fiber\boost\bin.v2\libs\fiber\build\msvc-14.0\debug\link-static\threading-multi\algo\algorithm.obj
algorithm.cpp
D:\3rdparty\boost\1.64.0\src\boost/intrusive/detail/parent_from_member.hpp(52): error C2338: sizeof(caster) == sizeof(int)
D:\3rdparty\boost\1.64.0\src\boost/intrusive/detail/parent_from_member.hpp(110): note: see reference to function template instantiation 'ptrdiff_t boost::intrusive::detail::offset_from_pointer_to_member<boost::fibers::context,Member>(const Member boost::fibers::context::* )' being compiled
with
[
Member=boost::fibers::detail::wait_functor::hook_type
]
D:\3rdparty\boost\1.64.0\src\boost/intrusive/parent_from_member.hpp(42): note: see reference to function template instantiation 'const Parent *boost::intrusive::detail::parent_from_member<boost::fibers::context,Member>(const Member *,const Member boost::fibers::context::* )' being compiled
with
[
Parent=boost::fibers::context,
Member=boost::fibers::detail::wait_functor::hook_type
]
D:\3rdparty\boost\1.64.0\src\boost/fiber/context.hpp(598): note: see reference to function template instantiation 'const Parent *boost::intrusive::get_parent_from_member<boost::fibers::context,boost::fibers::detail::wait_functor::hook_type>(const Member *,const Member boost::fibers::context::* )' being compiled
with
[
Parent=boost::fibers::context,
Member=boost::fibers::detail::wait_functor::hook_type
]
call "C:\Users\TORBJO~1\AppData\Local\Temp\b2_msvc_14.0_vcvarsall_x86.cmd" >nul
cl /Zm800 -nologo @"..\all_build_fiber\boost\bin.v2\libs\fiber\build\msvc-14.0\debug\link-static\threading-multi\algo\algorithm.obj.rsp"
...failed compile-c-c++ ..\all_build_fiber\boost\bin.v2\libs\fiber\build\msvc-14.0\debug\link-static\threading-multi\algo\algorithm.obj...
Both bound and unbound channels are not copyable nor movable, and thus it cannot be used with std container.
It's possible to make a channel movable or I have to resort to a vector of [shared|unique] pointers?
If I try to cross-compile Boost.Fiber for the armv6 architecture, the cxx11_* requirements in the Jamfile.v2 will fail, because the building system will try to execute the binaries on the host.
This should not happen.
The fact that the binaries are compiled is enough to guarantee the cxx11_* support by the compiler.
The scheduler currently has the following issues for my design:
The fix proposal is:
Hi,
As I can see here[1], member-function has the signature: R const& shared_future<R>::get() const
. But here[2], it has the different signature(it returns non-const reference): R& shared_future<R&>::get() const
.
Is everything right here?
[1] https://github.com/niXman/boost-fiber/blob/master/include/boost/fiber/future/future.hpp#L614
[2] https://github.com/niXman/boost-fiber/blob/master/include/boost/fiber/future/future.hpp#L794
I'm trying to rewrite the skynet test using async to compare with HPX's implementation. When I tried the following cases it fails to compile as it expects the stack allocator to conform to alloc_traits.h (i.e. define value_type etc.)
for (std::uint64_t i = 0; i != div; ++i)
{
std::uint64_t sub_num = num + i * size;
boost::fibers::packaged_task<std::uint64_t(allocator_type&, std::uint64_t, std::uint64_t, std::uint64_t)> pt{std::allocator_arg, salloc, skynet };
boost::fibers::future<std::uint64_t> f{ pt.get_future() };
boost::fibers::fiber{ boost::fibers::launch::dispatch, std::allocator_arg, salloc,
std::move(pt), std::ref(salloc), sub_num, size, div }.detach();
results.push_back(f);
//results.push_back(boost::fibers::async(
// boost::fibers::launch::dispatch
// , std::allocator_arg, salloc
// , skynet
// , std::ref(salloc), sub_num, size, div));
}
Here's the error message:
/usr/include/c++/5/bits/alloc_traits.h:88:43: error: no type named ‘value_type’ in ‘class boost::context::basic_fixedsize_stackboost::context::stack_traits’
typedef typename _Alloc::value_type value_type;
Apologies if it's something silly I've missed.
Building from head.
numa/topology.cpp
and numa/pin_thread.cpp
both #include <stdexception>
.
I think this is intended to be #include <stdexcept>
.
Hello Oliver,
A project I'm working on will rely on Boost Fiber and I have to start using the library in the next few days.
Which branch is the one you recommend to use currently? The master
is very old, so I was looking at develop
, but there are some newer ones, too.
Thank you for the great libraries!
Under Boost 1.64 and 1.63 using this boiled down example on Windows
(VS2015) when the condition is signaled, inside
scheduler::schedule_from_remote(ctx)
, the assertion
!ctx->sleep_is_linked()
fails. I do not believe this is occuring
under Linux.
While testing, I tried using condition wait without the timeout, and
it behaves fine. Looking closer, it appears that
scheduler::schedule(ctx)
actually checks sleep_is_linked() and
unlinks when true.
Am I using conditions incorrectly, or is
scheduler::schedule_from_remote
doing the wrong thing? Maybe it
should be checking sleep_is_linked, and unlinking also, being careful
to protect against multithreaded access?
#include <boost/fiber/condition_variable.hpp>
#include <boost/fiber/fiber.hpp>
#include <boost/fiber/mutex.hpp>
#include <boost/thread.hpp>
boost::fibers::mutex g_mutex;
boost::fibers::condition_variable g_condition;
void thread1()
{
Sleep(1000); // Wait for the other thread to get going.
printf("about to signal\n");
g_condition.notify_one();
}
int main()
{
boost::thread t(thread1);
std::unique_lock<boost::fibers::mutex> lk(g_mutex);
printf("about to wait\n");
g_condition.wait_for(lk, std::chrono::seconds(5));
printf("done\n");
return 0;
}
when I create a main fiber and join(), the program dump. why????
When running fiber's testsuite, I experience erratic crashes in these test cases:
For example, my latest run (branch develop
) crashed in three cases:
testing.capture-output Z:\boost\bin.v2\libs\fiber\test\test_future_post.test\msvc-14.1\rls\adrs-mdl-64\lnk-sttc\thrd-mlt\test_future_post.run
====== BEGIN OUTPUT ======
Running 24 test cases...
unknown location(0): fatal error: in "Boost.Fiber: future test suite/test_future_wait_until_void": memory access violation
test_future_post.cpp(516): last checkpoint
*** 1 failure is detected in the test module "Master Test Suite"
EXIT STATUS: -1073741819
====== END OUTPUT ======
testing.capture-output Z:\boost\bin.v2\libs\fiber\test\test_shared_future_post.test\msvc-14.1\rls\adrs-mdl-64\lnk-sttc\thrd-mlt\test_shared_future_post.run
====== BEGIN OUTPUT ======
Running 22 test cases...
unknown location(0): fatal error: in "Boost.Fiber: shared_future test suite/test_shared_future_wait_until": memory access violation
test_shared_future_post.cpp(449): last checkpoint
*** 1 failure is detected in the test module "Master Test Suite"
EXIT STATUS: -1073741819
====== END OUTPUT ======
testing.capture-output Z:\boost\bin.v2\libs\fiber\test\test_shared_future_dispatch.test\msvc-14.1\rls\adrs-mdl-64\lnk-sttc\thrd-mlt\test_shared_future_dispatch.run
====== BEGIN OUTPUT ======
Running 22 test cases...
unknown location(0): fatal error: in "Boost.Fiber: shared_future test suite/test_shared_future_wait_with_fiber_1": memory access violation
test_shared_future_dispatch.cpp(508): last checkpoint
*** 1 failure is detected in the test module "Master Test Suite"
EXIT STATUS: -1073741819
====== END OUTPUT ======
From another run earlier at the same day:
testing.capture-output Z:\boost\bin.v2\libs\fiber\test\test_shared_future_post.test\msvc-14.1\rls\adrs-mdl-64\lnk-sttc\thrd-mlt\test_shared_future_post.run
====== BEGIN OUTPUT ======
Running 22 test cases...
unknown location(0): fatal error: in "Boost.Fiber: shared_future test suite/test_shared_future_wait_until_ref": memory access violation
test_shared_future_post.cpp(469): last checkpoint
*** 1 failure is detected in the test module "Master Test Suite"
EXIT STATUS: -1073741819
====== END OUTPUT ======
testing.capture-output Z:\boost\bin.v2\libs\fiber\test\test_future_dispatch.test\msvc-14.1\rls\adrs-mdl-64\lnk-sttc\thrd-mlt\test_future_dispatch.run
====== BEGIN OUTPUT ======
Running 24 test cases...
unknown location(0): fatal error: in "Boost.Fiber: future test suite/test_future_wait_with_fiber_1": memory access violation
test_future_dispatch.cpp(535): last checkpoint
*** 1 failure is detected in the test module "Master Test Suite"
EXIT STATUS: -1073741819
====== END OUTPUT ======
The test runs are conducted on Windows 10 1703, Intel Core i7-6700K (4+4 Cores at 4 GHz), MSVC 14.1 (same with 14.0), 64 Bit, up to 6 parallel Jam tasks, parallel build, both debug and release mode. I've instrumented Boost.Test such that these errors are captured in the test log.
Hey Oliver,
This seems like a really interesting project - I'm keen to try it out, but I'm afraid I'm not very familiar with the boost/jam build system - the obvious commands I've tried out don't seem to work so well.
It might make sense to add a few lines to the README indicating how to run bjam on the project (or a shell script that does the same), for those of us less gifted with boost :)
Thanks!
Congratulations for getting approval, you now want to remove this line: https://github.com/boostorg/fiber/blob/master/doc/overview.qbk#L119
You can find this in:
https://github.com/SergeyMakeev/TaskScheduler
https://github.com/RichieSams/FiberTaskingLib
Hi Oliver,
I have different types of fibers, and I'd need a scheduler that makes scheduling decisions based on the fiber type (or any custom property of the fiber). I could approximate what I want with fiber priorities, which used to exist in the master
branch.
Is there any good way to do this in the develop
branch? I haven't found one.
A derived class of fiber
doesn't help, because the scheduler works with fiber_context
.
Creating derived classes of both fiber
and fiber_context
could work, but currently it doesn't, due to two issues: in fiber
, the wrapped fiber_context
is hidden as a private member, and fiber
is not polymorphic, its methods aren't virtual. So even if I would reimplement all methods of fiber
in my derived fiber class in order to use my derived fiber_context, it would not work.
Having a way to do this type of customization would be very useful, probably for many people.
The easiest solution would be to change the the private section of fiber
to protected. However, Asio spawn()
would have to be modified to support the custom fiber types, too.
Thanks!
I tried to use the boost::fibers::asio::spawn while using c++11, but it failed to compile and I noticed the example is missing under cpp11 directory. Is there any example for the usage? Or is it not supported under c++11?
Hello @olk
In #101 I mentioned noticing some weird behavior under Valgrind.
It turns out that the issue is not Valgrind related, and after much trouble, I managed to
reproduce it in a simple example. Very similar to the one in #100.
Consider the following program:
std::shared_ptr<boost::fibers::unbuffered_channel<int>> c;
std::shared_ptr<boost::fibers::unbuffered_channel<int>> c2;
void run_t1()
{
std::atomic_thread_fence(std::memory_order_acquire);
auto io_ptr = std::make_shared<boost::asio::io_service>();
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_ptr);
io_ptr->post([&](){
for (int i = 0 ; i < 50 ; ++i)
{
std::stringstream ss;
ss << "Will push " << i << std::endl;
std::cout << ss.str();
c->push(i);
c2->value_pop(); //spin at this point, until t2 has pushed something.
}
});
io_ptr->run();
}
void run_t2()
{
std::atomic_thread_fence(std::memory_order_acquire);
auto io_ptr = std::make_shared<boost::asio::io_service>();
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_ptr);
boost::fibers::fiber f([io_ptr](){
try {
for (;;) {
int i = c->value_pop();
std::cout << "Read " << i << " from channel." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
c2->push(i);
}
}
catch (const std::exception &e)
{
std::cout << "Caught: " << e.what() << std::endl;
}
io_ptr->post([io_ptr](){
io_ptr->stop();
});
});
io_ptr->run();
}
int main() {
c = std::make_shared<boost::fibers::unbuffered_channel<int>>();
c2 = std::make_shared<boost::fibers::unbuffered_channel<int>>();
std::atomic_thread_fence(std::memory_order_release);
std::thread t2(run_t2);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::thread t1(run_t1);
t2.join();
t1.join();
return 0;
}
The program will spin at 100% cpu.
I'm not sure we are supposed to initiate fiber-related operations (channel's push()
/ pop()
) from a manually post()
ed handler (as done in run_t1()
), but I would expect we should be able to.
I've tried to fix it in the fibers::asio::round_robin()
algorithm, but I didn't managed to.
What I've observed that may help fixing the issue:
t1
thread is spinning when it calls value_pop()
. It will spin untill the this_thread::sleep()
call in t2()
returns and a value is pushed (therefore value_pop()
is able to complete).value_pop()
seem to come from the infinite loop in the scheduler::dispatch()
. asio::round_robin::suspend_until()
is called, but return immediately, therefore spinning. It returns immediately because when doing cdn_.notify_one()
, no one is actually waiting on cnd_
, so the fiber context doesn't change, and suspend_until()
is called in a loop.Hello,
I've spent more time trying to use both asio
and fiber
together. I am now aware that proper integration is still pending support in asio
.
However, I've faced a few issues that made the combined use of asio
and fiber
not usable (for my use case).
Consider the following test program:
std::shared_ptr<boost::fibers::unbuffered_channel<int>> c;
void run_t1()
{
auto io_ptr = std::make_shared<boost::asio::io_service>();
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_ptr);
boost::fibers::fiber f([](){
for (int i = 0; i < 10; ++i) {
std::cout << "Will push " << i << std::endl;
c->push(i);
}
});
f.detach();
io_ptr->run();
}
void run_t2()
{
auto io_ptr = std::make_shared<boost::asio::io_service>();
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_ptr);
boost::fibers::fiber f([](){
try {
for (;;) {
int i = c->value_pop();
std::cout << "Read " << i << " from channel." << std::endl;
}
}
catch (const std::exception &e)
{
std::cout << "Caught: " << e.what() << std::endl;
}
});
f.detach();
io_ptr->run();
}
int main() {
c = std::make_shared<boost::fibers::unbuffered_channel<int>>();
std::thread t1(run_t1);
std::thread t2(run_t2);
t2.join();
t1.join();
return 0;
}
The expected output would be for the fiber in run_t2
to display number ranging from 0 to 9. However, in my test, the output was either:
value_pop()
never returned, not even once).0
and/or 1
.It never managed to read the 10 numbers from the channel. I again tried to dive into the library,
trying to understand what was happening.
I believe I've found the cause and have a fix, but I still struggle to reason about what's happening under the hood so I might be wrong.
I believe the issue lies in boost::fibers::asio::round_robin
's notify()
method. The method simply
make the timer expires now()
. In the past I guess this was okay, but since commit de58b07 the lambda posted in the round_robin::service
's contructor does not yield()
anymore. This means that when that lambda is awakened due to the timer expiring, it doesn't give a chance to other fiber to run.
The fix consist of adding an async_wait()
that would run yield()
.
I'll submit a PR with the fix shortly. Note that some of the comment are probably outdated, but I'm not
comfortable enough to update them.
Please let me know if my understanding of the issue is wrong.
I was trying to build Fiber for Boost 1.60.0 when the following error occurred.
In file included from libs/fiber/src/algorithm.cpp:9:0:
./boost/fiber/context.hpp:20:42: fatal error: boost/context/detail/apply.hpp: No such file or directory
compilation terminated.
It seems the header "boost/context/detail/apply.hpp" was removed from boost context.
Is this an issue for fiber?
Thank you.
This is happens with
libs/fiber/src/numa/pin_thread.cpp:25:10: warning: pin_thread() not supported [-W#pragma-messages]
# pragma message "pin_thread() not supported"
^
libs/fiber/src/numa/pin_thread.cpp:30:22: error: expected ';' after expression
throw fiber_error{
^
;
libs/fiber/src/numa/pin_thread.cpp:30:11: error: use of undeclared identifier 'fiber_error'
throw fiber_error{
^
libs/fiber/src/numa/pin_thread.cpp:32:54: error: expected ';' after expression
"boost fiber: pin_thread() not supported" };
^
;
libs/fiber/src/numa/pin_thread.cpp:32:13: warning: expression result unused [-Wunused-value]
"boost fiber: pin_thread() not supported" };
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings and 3 errors generated.
"clang++" -x c++ -std=c++14 -stdlib=libc++ -mmacosx-version-min=10.8 -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -arch i386 -arch x86_64 -O3 -O3 -Wno-inline -Wall -DBOOST_ALL_NO_LIB=1 -DBOOST_DISABLE_ASSERTS -DBOOST_FIBERS_SOURCE -DBOOST_FILESYSTEM_STATIC_LINK=1 -DBOOST_SYSTEM_STATIC_LINK=1 -DNDEBUG -I"." -c -o "/Users/gjasny/Git/ExternalLibs/boost/_output/macosx/boost/bin.v2/libs/fiber/build/clang-darwin-4.2.1/release/address-model-32_64/link-static/threading-multi/numa/pin_thread.o" "libs/fiber/src/numa/pin_thread.cpp"
hello.
i cannot compile this code on the master branche, only on the develop branche (it was so for a few month). now on the develop branche it compiles but crashes (terminated by signal SIGSEGV (Address boundary error)). i am on db88147
#include <iostream>
#include <boost/fiber/all.hpp>
int main(int argc, char** argv) {
boost::fibers::fiber([](){std::cout << "hello from fiber" << std::endl;}).detach();
boost::this_fiber::yield();
return 0;
}
in
void
fiber_manager::run()
{
....
{
// no fibers ready to run; the thread should sleep
// until earliest fiber is scheduled to run
clock_type::time_point wakeup( next_wakeup() );
this_thread::sleep_until( wakeup);
}
return;
}
while there is no fibers ready, the thread got sleep at least next_wakeup() time. I think there can be a better way to wait on some fd so that another thread can wake it up immediatly by write data to the fd.
detail/spinlock_ttas_adaptive_futex.hpp#L69
detail/spinlock_ttas_futex.hpp#L65
unbuffered_channel.hpp#L242
unbuffered_channel.hpp#L292
unbuffered_channel.hpp#L74
unbuffered_channel.hpp#L89
http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
failure - the memory synchronization ordering for the load operation if the comparison fails. Cannot be std::memory_order_release or std::memory_order_acq_rel [and cannot specify stronger ordering than success (until C++17)]
Hi there, Sorry for the noob question. From my understanding calling yield from within a fiber will cause the fiber scheduler to give cycles to another fiber. Now suppose I have a IO call that would block and during the block I would like to give other fibers the cycles. Consider this:
...
do_nb_stuff(); // do non blocking stuff
yield(); // <------if I put yield here won't it context switch before the do_b_stuff?
do_b_stuff(); // do blocking work
yield(); // <------if I put yield here won't it context switch after the do_b_stuff?
What I want is to yield during do_b_stuff if that makes sense.
Thanks and sorry for my stupidity or lack of understanding in advance.
Hi,
Another general issue that appeared in my experience with fiber is that completed tasks do not release their memory until the dispatcher/system fiber runs.
The dispatcher fiber is not scheduled in all (?) / most(?) schedulers unless there are no application fibers pending. It would be great to provide another mechanism to garbage collect completed tasks, either by the user calling a function or by having the dispatcher fiber scheduled with some other priority.
Thanks,
Daniel Chavarria
Trovares Inc.
Hi,
I have built and installed boost 1.62 and I'm trying to build a simple fiber program using the following command:
clang++ fiber.cpp -std=c++14 -I /usr/local/include/boost/ -l boost_context -l boost_system -l boost_thread -l pthread
But I'm getting undefined references to:
The program:
#include <iostream>
#include <boost/fiber/all.hpp>
int main(int argc, char const *argv[]) {
auto fiber = boost::fibers::fiber([] () {
std::cout << "Hello World" << std::endl;
});
return 0;
}
Hi Oliver,
This is the issue that was traced down in #29. I encountered it today again with another application. Because #29 was originally not about this problem, and you closed it meanwhile anyway, I'm opening a new one.
Problem: When dynamically linking against the RELEASE
version of the Boost Fiber shared library, compilation and linking are successful, but when the binary is run, it fails.
The problem occurs with the "official" Boost Fiber Asio examples, and also with two different applications of mine.
When dynamically linking against the debug
shared library, or statically linking against either the debug
or release
static library, everything works.
Note: I have tested this only with code using Asio. I don't know if the issue affects non-Asio Fibers code.
Environment: Ubuntu 14.04 64-bit, GCC 4.9.2, latest Modular Boost, latest Boost Fiber (develop
) branch
To reproduce it with the official examples:
cd /modboost-folder/libs/fiber/examples
- <link>static + <link>shared + <linkflags>-lboost_context + <linkflags>-lboost_thread
debug
build:
b2 toolset=gcc cxxflags="-std=c++14" address-model=64 architecture=x86 debug cd /modboost-folder/bin.v2/libs/fiber/examples/gcc-4.9.2/debug/address-model-64/architecture-x86/threading-multi/asio
./echo_server 1234
, in another ./echo_client 127.0.0.1 1234
release
build
b2 toolset=gcc cxxflags="-std=c++14" address-model=64 architecture=x86 release cd /modboost-folder/bin.v2/libs/fiber/examples/gcc-4.9.2/release/address-model-64/architecture-x86/threading-multi/asio
./echo_server 1234
, in another ./echo_client 127.0.0.1 1234
I use this boost-fiber in my game engine, and get these questions:
int main(){
boost::fibers::fiber f([&] {
while (true) {
puts("ppp");
boost::this_fiber::yield();
}
});
while (true) {
f.join()
puts("qqq");
}
return 0;
}
As what I thinked, it should print as:
ppp
qqq
ppp
qqq
.......
But in fact it print:
ppp
ppp
ppp
ppp
....
It seems like boost::this_fiber::yield() does not return where the fiber was called.
What should I do? Thanks a lot, I am tired of 6 hours working on config boost and using fibers..
I am trying to compile the code example with g++4.8 on Ubuntu 14.04 in the tutorial from boost website
http://www.boost.org/doc/libs/1_63_0/libs/fiber/doc/html/fiber/synchronization/channels/buffered_channel.html
And it failed with the following error:
opt/third_party/include/boost/fiber/buffered_channel.hpp: In instantiation of ‘boost::fibers::buffered_channel::buffered_channel(std::size_t) [with T = HAUD::SS7Wrapper*; std::size_t = long unsigned int]’:
/home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudEndpointWorker.cpp:23:25: required from here
/opt/third_party/include/boost/fiber/buffered_channel.hpp:49:9: error: use of deleted function ‘std::atomic::atomic(const std::atomic&)’
slot() = default;
^
In file included from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudWorkerJob.h:11:0,
from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudEndpointWorker.h:16,
from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudEndpointWorker.cpp:7:
/usr/include/c++/4.8/atomic:658:7: error: declared here
atomic(const atomic&) = delete;
^
In file included from /opt/third_party/include/boost/fiber/all.hpp:15:0,
from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudWorkerJob.h:19,
from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudEndpointWorker.h:16,
from /home/ak70/HaudDevelopment/HaudCore/HaudCore/Services/HaudSMSService/HaudEndpointWorker.cpp:7:
/opt/third_party/include/boost/fiber/buffered_channel.hpp:138:16: note: synthesized method ‘boost::fibers::buffered_channel::slot::slot() [with T = HAUD::SS7Wrapper*]’ first required here
slots_ = new slotcapacity_;
^
Any ideas?
Hi,
First of all, thanks for the great contributions of fibers to the boost libraries!
I used fibers to build a runtime system for a distributed database system and had the need to create a custom scheduler. The scheduler that I needed was pretty similar to your provided shared_work scheduler with the caveat that the "system" or dispatcher fibers must be scheduled with some frequency to garbage-collect terminated tasks. I proceeded to derive my scheduler from your shared_work but unfortunately needed to change your code to declare the members of the shared_work class to be protected instead of private.
Would it be possible to change these class members to be protected so that they can be accessed by derived classes?
Thanks,
Daniel Chavarria
Trovares Inc.
I posted this on the boost bugtracker however it wasnt noticed by anyone, so ill post it here.
In the examples/asio/detail/yield.hpp file, the sleeping fiber owns the mutex(for when async_result::get
returns, the asio call returns and the yield_completion is destroyed).
Consider Fiber A, the callee of the async operation, and Fiber B, the fiber that calls async_handler.
Fiber B possibly runs in another thread.
Fiber B locks the mutex, sets fiber A as ready and goes to sleep without releasing the lock. Fiber A goes through the return process and destroys the mutex.
The solution is very simple. Simply reaquire the lock after the suspend
call returns.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.