云风协程库的源码解析

参考文章:

Linux进程地址空间

进程地址空间
在32位操作系统中,进程的最大地址空间为4GB。整个进程地址空间从下往上为地址的增长方向。对于系统中的所有进程来说,代码都是从同一固定地址开始。

  • 只读代码和数据:该区域是直接按照可执行目标文件中的内容初始化的,在进程开始运行时,大小就固定不变;

  • 堆:运行时随着malloc和free等函数相应地扩大或缩小;

  • 共享库:在地址空间约中间的区域存放C标准库等共享库代码;

  • 栈:用于函数的调用、局部变量的存放,随着进程的运行动态增长或缩小;

  • 内核虚拟区:操作系统的一部分,内核总是驻留在内存中,不允许应用程序读写这个区域的代码。该区域包括内核代码和数据、与进程相关的数据结构(如页表、内核栈等)。

协程库的源码分析

云风协程库中的关于程序上下文的操作主要依赖glibc库里"ucontext.h"头文件的几个函数:

getContext()	// 获取当前的context
setContext()	// 切换到指定的context
makeContext()	// 设置函数指针和栈到对应的context保存的sp和pc寄存器
swapContext()	// 保存当前的context 并且换到指定的context

挂起协程

保存当前子协程的上下文(包括寄存器值和函数调用栈)

  1. &dummy 当前协程的最低栈地址
  2. assert 判断当前协程的运行空间小于等于默认的最大空间(STACK_SIZE)
  3. 如果当前协程的私有栈空间太小不足以保存上下文,需要重新扩容
  4. memcpy 将top-&dummy的地址空间保存到自定义的协程结构中,以便之后恢复环境上下文

子协程的上下文是保存于堆中,因为需要恢复的。

/**
 * @param(coroutine): 当前需要保存上下文的子协程
 * @param(top): 调度器的最高地址(子协程运行于主协程的公共栈空间)
 */
static void _save_stack(struct coroutine *coroutine, char *top) {
   
    char dummy = 0;
    assert
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值