I found boost has a class called context which is used for context switching, right?
I try to Google it but did not found any document or example. I am just wondering if anyone can provide some information.
I found boost has a class called context which is used for context switching, right?
I try to Google it but did not found any document or example. I am just wondering if anyone can provide some information.
Thank you wjl for your example code. It helped me understand how boost context works and how boost coroutine is implemented by means of boost context. But your code didn't work as it was, so I modified it to be compiled on Windows. (didn't check if it works on Linux though)
#include <iostream>
#include <array>
#include <boost/context/all.hpp>
class Coroutine {
public:
Coroutine() :
my_context(boost::context::make_fcontext(
stack.data() + stack.size(),
stack.size(),
Coroutine::dispatch
))
{}
virtual ~Coroutine() {}
void operator()() {
boost::context::jump_fcontext(&yield_context, my_context, reinterpret_cast<intptr_t>(this));
}
protected:
void yield() {
boost::context::jump_fcontext(&my_context, yield_context, 0);
}
virtual void call() = 0;
private:
static void dispatch(intptr_t coroutine_ptr) {
Coroutine *coroutine = reinterpret_cast<Coroutine *>(coroutine_ptr);
coroutine->call();
while (true) coroutine->yield();
}
private:
boost::context::fcontext_t my_context;
boost::context::fcontext_t yield_context;
std::array<intptr_t, 64 * 1024> stack;
};
struct A : public Coroutine {
void call() {
std::cerr << "A went to the store one day.\n";
yield();
std::cerr << "A was looking for groceries.\n";
yield();
std::cerr << "A finally found what she was looking for.\n";
}
};
struct B : public Coroutine {
void call() {
std::cerr << "B went to the store one day.\n";
yield();
std::cerr << "B was looking for replacement tires.\n";
yield();
std::cerr << "B didn't find anything at all.\n";
yield();
std::cerr << "B went to another store.\n";
yield();
std::cerr << "B got the tires installed there.\n";
}
};
struct C : public Coroutine {
void call() {
std::cerr << "C went to the store one day.\n";
yield();
std::cerr << "C was looking for USB drives.\n";
yield();
std::cerr << "C found several with competitive pricing.\n";
yield();
std::cerr << "C couldn't decide which to buy, so gave up.\n";
}
};
int main() {
std::cerr << "So, this is what happened.\n";
A a;
B b;
C c;
for (size_t i = 0; i < 10; ++i) {
a();
b();
c();
}
std::cerr << "Then it all was done.\n";
}
The boost-coroutine archive on the author's website contains some basic docs and examples for both coroutine, which builds on context, and context itself. You'll also find a fiber package on that website, which might be interesting at least as another use case.
Boost::Context is an official part of Boost in version 1.51.0 and up. See http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/index.html for information about it. Unfortunately the documentation is slightly different than the implementation, and some things have changed in SVN, so you'll need to read the header files a little bit.
Here is an example I wrote the other day showing Boost::Context to make simple coroutines using Boost 1.51.0+latest SVN:
Then compiling and running looks like this: