state-threads的协程切换

本文详细介绍了state-threads如何利用setjmp和longjmp在C语言中实现轻量级协程切换。通过对x86架构下保存和恢复上下文的汇编代码分析,展示了st库中如何在不同协程间进行切换。文中还探讨了两个关键的中断点:一个是用于非阻塞创建协程,另一个是主动出让调度权,常用于系统调用封装。
摘要由CSDN通过智能技术生成

1. 简介

        state-threads是一个C语言实现的轻量级协程库,基于setjmp和longjmp来对不同协程进行切换。本文将先分析其保存上下文的setjmp和longjmp的汇编代码,简单分析其上下文切换的过程。

2. 代码分析

2.1 保存恢复上下文

        保存恢复上下文可以使用系统中的setjmp和longjmp,glibc中也有,st中自己也有实现部分架构下的setjmp和longjmp(md.S)。

        首先看汇编上保存上下文的处理代码,在x86下,主要根据调用约定保存了rbx、rbp(帧指针,基址寄存器)、r12-r15 [2]、rsp(栈指针)、PC(为该函数的调用者callq的下一条指令,会保存在栈上),保存在了thread->context,是一个__jmp_buf结构体,保存上下文时返回值总是0,恢复时根据传入的第二个参数进行判断,返回非零值。这里两个返回值不同主要是为了处理保存环境和再次调度的区别,具体差异见下c代码。

/*
 * Internal __jmp_buf layout
 */
#define JB_RBX  0
#define JB_RBP  1
#define JB_R12  2
#define JB_R13  3
#define JB_R14  4
#define JB_R15  5
#define JB_RSP  6
#define JB_PC   7

        .file "md.S"
        .text

        /* _st_md_cxt_save(__jmp_buf env) */
.globl _st_md_cxt_save
        .type _st_md_cxt_save, @function
        .align 16
_st_md_cxt_save:
        /*
         * Save registers.
         */
        /* rdi为第一个入参,即jmp_buf env.  */
        /* jmp_buf为一个长度为8的8字节的数组.  */
        /* 存放顺序为:
         * [rdi + 0] = rbx;    --->  env[0]
         * [rdi + 8] = rbp;    --->  env[1]
         * [rdi + 16] = r12;   --->  env[2]
         * [rdi + 24] = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值