« Previous entry | Next entry » Browse > Snippets

Skip to comments (9) Simple coroutines in C
Posted by Erik on Jan 06 2006 @ 11:27  :: 3396 unique visits

Invalid way to write a simple generator in C/C++:
CODE: C
int foobar() {
  int i;
  for (i = 0; i < 1337; i++) {
    return i;
  }
}

Wouldn't it be cool if this was valid?


Well it is! With coroutines. Coroutines are functions in which you can return from and next time continue at the spot you last returned from.

4 macro's used to simplify the creation of coroutine:
CODE: C
#define cr_start()   static int __s = 0; switch (__s) { case 0:
#define cr_returnv   { __s = __LINE__; return;   case __LINE__: ; }
#define cr_return(x) { __s = __LINE__; return x; case __LINE__: ; }
#define cr_end()     } __s = 0;
 


The above code written as a coroutine:
CODE: C
int foobar() {
  static int i;

  cr_start();

  for (i = 0; i < 1337; i++) {
    cr_return(i);
  }

  cr_end();
}

foobar(); // will return 0
foobar(); // will return 1
 


How does it work?


The above code with macro's expanded, and made a little more readable:
CODE: C
int foobar() {
  static int i;

  static int __s = 0;

  switch (__s) {
    case 0:
      for (i = 0; i < 1337; i++) {
        __s = 42;
        return i;
    case 42:
      }
  }

  __s = 0;
}


Note: I replaced the __LINE__ macro with 42, normally your compiler would replace it with the current line number.

As you can see coroutines use a little trick in C which most people aren't aware of. You can put the case of a swith inside the body of a for/while that starts inside that switch. So the second time the function is called, the switch jumpes inside the for loop and i won't be reset to 0.

Another more simpler example:
CODE: C
void count(void) {
  cr_start();

  printf("first\n");
  cr_returnv;

  printf("second\n");
  cr_returnv;

  printf("third\n");

  cr_end();
}

count(); // print "first"
count(); // print "second"
count(); // print "third"
count(); // print "first"
 

When you expand the macro's here you will see that it's just a simple switch with a static variable.

Reentrant coroutines


As you might have noticed coroutines aren't reentrant nor thread-safe. This can be fixed by making the macro's a litte more complex and adding one extra argument to the functions.

Edit 9-1-2006:
My post about reentrant coroutines


Original work from: Simon Tatham

9 comments posted so far
Add your own »

1. On Jan 06 2006 @ 13:28 l0ne wrote:

Cool! And pretty ingenious too. But, due to the 'static' keyword, the whole thing has a global context, which is no-no for oh-so-many-apps...

2. On Jan 06 2006 @ 14:54 Erik wrote:

That's why I'll post the reentrant coroutines which don't use the global context soon.

3. On Jan 08 2006 @ 21:42 Erik wrote:

If you are using Visual Studio you may get an:
CODE: OTHER
error C2051: case expression not constant

This is because of a Visual Studio feature called Edit and Continue. Edit and Continue enables you to modify your code (with some limitations) while you are dubugging your program and apply those changes without having to end the debug session and rebuild your program.
Because of this the __LINE__ macro isn't a constant (because you could insert new lines before it) and you get this error.

In Visual Studio 6.0 you can disable Edit and Continue the folloing way:
  • Open your Project Settings (Alt+F7).
  • Go to the C/C++ tab
  • Change Debug info from "Program Database for Edit and Continue" to "Program Database"

I don't know how to disable it for other versions of Visual Studio.

Another usage for coroutines


user-level yield like scheduling:
CODE: C
void userthread1() {
    cr_start();

    for (;;) {
        // do stuff

        cr_returnv;
    }

    cr_endv();
}

void userthread2() {
    cr_start();

    for (;;) {
        if (condition) {
            // do stuff

            cr_returnv;
        }
       
        // do more stuff

        cr_returnv;
    }

    cr_endv();
}

int main(int argc, char* argv[]) {
    for (;;) {
        userthread1();
        userthread2();
    }
}

4. On Feb 15 2009 @ 15:47 guest wrote:

70-630 -
70-620 -
70-624 -
70-529 -
70-536 -

5. On May 09 2009 @ 19:05 maryzheng wrote:

TradeTang is your dream come true for all your wholesale products shopping needs. Our inexpensive selection of quality wholesale merchandise is out of this world. We sell everything you can imagine from candles to baby products and children's toys to pet supplies. If you are buying bulk merchandise for an apparel shop, then our amazing line of clothes, jewelry, flip-flops and shoes are perfect for you. We also carry incredible wholesale supplies that would be great at a home improvement or China Wholesale.

6. On May 19 2009 @ 09:35 guest wrote:

Find louis vuitton handbag and louis  Louis Vuitton Handbags , louis vuitton wallet and louis vuitton purse items on Louis Vuitton Store Browse a huge selection of LV Handbags Louis Vuitton is luxury gifts, French fashion, the replica Louis Vuitton Store is woman best friend. With Louis Vuitton Discover real Louis Vuitton bags, Vuitton accessories and the latest handbag lines. Join the biggest active Louis Vuitton enthusiast community on the web today

UGGs is a brand that is all about luxury and comfort for everyday life. Only the finest quality materials are used to create UGG Boots. Provide UGG Women Boots,UGG Man Boots,UGG Kids Boots.
UGG Australia is the largest distributor of Grade-A sheepskin.
Find Women's UGGs, Men's UGG Boots, and Kids UGGs on Sale all made with ... UGG Store include Discount UGG  UGG Classic Tall,UGG Classic Short

Louis Vuitton is luxury gifts, French fashion, the replica Louis Vuitton Handbag is woman best friend.Monogram Groom.
Offers Discount Louis Vuitton handbags and Louis Vuitton bags and all other designer handbags,free global fast shipping,low price and top quality.Monogram Jokes,Monogram Suede cheap Louis Vuitton
Louis Vuitton.

Looking For Gucci Shoes ? Gucci Store provide gucci Mens shoes,gucci Womens shoes
Wonderful Gucci shoes sale Gucci men's shoes and Gucci women's shoes at discount Gucci Shoes prices.
cheap gucci Shoes
Gucci Shoes and gucci clothing Spring - Summer 2009, Prada Shoes and prada clothing from the Latest Collection 2009 and Dolce Gabbana Clothing 2009
Gucci Loafers
Gucci Sneakers

UGGs
Louis Vuitton Handbags
Gucci Shoes
Louis Vuitton
UGG Boots
Louis Vuitton Handbags
gucci shoes
Monogram Groom
Discount Louis Vuitton
UGG Boots
Louis Vuitton handbags

8. On Jul 14 2009 @ 04:03 guest wrote:

buy wow gold
my wow power leveling
buy wow gold
good wow power leveling
BUY wow gold
my wow power leveling
CHEAP rs gold
cheap wow power leveling
CHEAPEST lotro gold
MY aion gold
buy wow gold
cheap wow gold
CHEAPEST wow gold

Add a new comment

Name:
Password: (leave empty for anonymous comment)
 
View formatting tags Comment: