Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I build a bidirectional coroutine with Boost 1.55?

The current Boost 1.55 implementation offers two kinds of unidirectional coroutines. One is a pull-type, which is a coroutine that takes no parameters and returns a value to the main context; the other is the push-type, which is a coroutine that accepts a parameter from the main context but returns no value.

How can I combine these two to create a bidirectional coroutine that both accepts a parameter and returns a value? On the surface it seems like it should be possible, but I can't quite figure out how to do it with the building blocks I have in boost::coroutine. There used to be a bidirectional coroutine in older Boosts, but it is now deprecated and undocumented, so I shouldn't rely on it.

ie, I would like something analogous to this:

void accumulate( pull_func &in, push_func &out )
{
  int x = 0;
  while ( in ) 
  {
    x += in.get() ; // transfers control from main context 
    out(x); // yields control to main context
  }
}

void caller( int n ) 
{
   bidirectional_coro( accumulate );
   for ( int i = 0 ; i < n ; ++i )
   {
      int y = accumulate(i); 
      printf( "%d ", y ); // "0 1 3 6 10" etc
   }
}
like image 872
Crashworks Avatar asked Dec 20 '13 20:12

Crashworks


People also ask

How to use coroutines in boost?

These types are provided by boost::coroutines::coroutine, which is a template that is instantiated with void in Example 51.1. To use coroutines, you need pull_type and push_type.

How to use cooperative () as a coroutine?

To use cooperative () as a coroutine, the types pull_type and push_type are used. These types are provided by boost::coroutines::coroutine, which is a template that is instantiated with void in Example 51.1. To use coroutines, you need pull_type and push_type.

How do I use coroutines in Python?

To use coroutines, you need pull_type and push_type. One of these types will be used to create an object that will be initialized with the function you want to use as a coroutine.

Is it possible to use coroutines in C++?

With Boost.Coroutine it is possible to use coroutines in C++. Coroutines are a feature of other programming languages, which often use the keyword yield for coroutines. In these programming languages, yield can be used like return.


2 Answers

Actually, boost coroutine was bidirectional when it was first included in boost(1.53 I think).

http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm

That code should still be compatible with the most recent version of boost, with minor modification if anything.

Also, you could use boost::context directly to create your own coroutine class.

http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html

The parameter 'intptr_t vp' of fcontext_swap can be use to pass values/pointers back and forth, or you could store values in the coroutine itself, as member variables of your coroutine class should be valid from both contexts.

edit:

The short answer to your original question is no. What you are asking cannot be done. Each coroutine has it's own stack and context, which are not accessible from other coroutine instances. Also, when you jump into the coroutine's context, the state of the calling context is stored in that coroutine instance, and a jump back to the original context can only be made by calling into the argument that that coroutine passed into your function.

But, variables declared outside the local scope of the coroutine will be valid from inside and outside the coroutine function. So you could use a coroutine::push_type, and push a pointer instead of a value. You could use the value, and then modify it before jumping back to the original context.

Also, you can safely pass pointers to local variables into the coroutine, since they won't be destroyed until you jump back out of the coroutine and run the calling scope to completion.

like image 173
CuriousGeorge Avatar answered Sep 28 '22 02:09

CuriousGeorge


you could look at the example contained in boost.coroutine https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp

like image 30
olk Avatar answered Sep 28 '22 02:09

olk