Fork me on GitHub

A hack of the single thread coroutine in C

You must have learned the yield in python before.Let’s say, we have the following code in python

1
2
3
4
5
6
7
8
def traverse(max):
start = 0
while start < max:
yield start
start += 1

for i in traverse(5):
print (i)

The code above will print the 0,1,2,3,4,5

Of course the is the grammar sugar in python, the hack is coming—— how can we implement the code in C language?

Hack Begin

Considering jump, the first thing pop out from our mind is notorious goto isntruction. Regardless of the simplicity, we can introduce the goto to our first version of coroutine.

1
2
3
4
5
6
7
8
9
10
11
12
13
int function() {
static int i, state = 0;
switch(state) {
case 0: goto LABEL0;
case 1: goto LABEL1;
}
LABEL0:
for (i = 0; i < 10; i ++){
state = 1;
return i;
LABEL1:;
}
}

Yet the goto is so ugly, let’s refract it with switch(in a way you have never seen before)

1
2
3
4
5
6
7
8
9
10
11
int function() {
static int i, state = 0;
switch(state) {
case 0:
for(i = 0; i < 1-; i++){
state = 1;
return i;
case 1:;
}
}
}

Using line to universify it:

1
2
3
4
5
6
7
8
9
10
11
int function(void) {
static int i, state = 0;
switch (state) {
case 0: /* start of function */
for (i = 0; i < 10; i++) {
state = __LINE__ + 2; /* so we will come back to "case __LINE__" */
return i;
case __LINE__:; /* resume control straight after the return */
}
}
}

The next step is the most important one

1
2
3
4
5
6
7
8
9
10
11
12
#define Begin() static int state = 0; switch(state) {case 0;
#define Yield(x) do {state = __LINE__; return x; case __LINE__:;} while(0)
#define End() }


int function(void) {
static int i;
Begin();
for (i = 0; i < 10; i++)
Yield(i);
End();
}

Now, I would like to introduce a new continuation implementation based on the spark above, you can checkout at the