main.c
#include <stdio.h>
#define STACK_SIZE 65536
#define REG_SIZE sizeof(long)
typedef void (*cothread_func)();
typedef struct
{
unsigned long regs[3]; /* [0]:rip [1]:rbp [2]:rsp */
char stack[STACK_SIZE];
} cothread_t;
void cothread_yield(cothread_t* from, cothread_t* to);
void cothread_create(cothread_t* thread, cothread_func func)
{
thread->regs[0] = (unsigned long)func;
thread->regs[1] = (unsigned long)&thread->stack[STACK_SIZE];
thread->regs[2] = (unsigned long)&thread->stack[STACK_SIZE - REG_SIZE];
*((unsigned long*)&thread->stack[STACK_SIZE - REG_SIZE]) = (unsigned long)func;
}
cothread_t mainThread;
cothread_t fThread;
#define TIMES 5
void f()
{
int i;
for (i = 0; i < TIMES; i++)
{
printf("f(): %d\n", i);
cothread_yield(&fThread, &mainThread);
}
}
int main()
{
cothread_create(&fThread, f);
int i;
for (i = 0; i < TIMES; i++)
{
printf("main(): %d\n", i);
cothread_yield(&mainThread, &fThread);
}
return 0;
}
yield.x86_64.s
.section .text .globl cothread_yield cothread_yield: // save current rip/rbp/rsp mov (%rsp), %rax mov %rax, (%rdi) mov %rbp, 8(%rdi) mov %rsp, 16(%rdi) // load new rbp/rsp/rip mov 8(%rsi), %rbp mov 16(%rsi), %rsp mov (%rsi), %rax mov %rax, (%rsp) ret
测试
$ gcc -Wall main.c yield.x86_64.s -o test
$ ./test
main(): 0
f(): 0
main(): 1
f(): 1
main(): 2
f(): 2
main(): 3
f(): 3
main(): 4
f(): 4
实现coroutine的symmetric context switch
原文:http://my.oschina.net/u/1445655/blog/505512