标签:
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