目录

6.协程实现之切换

问题:协程的上下文如何切换?切换代码如何实现?

首先来回顾一下x86_64寄存器的相关知识。x86_64 的寄存器有16个64位寄存器,分别是:%rax, %rbx, %rcx, %esi, %edi, %rbp, %rsp, %r8, %r9, %r10, %r11, %r12,

%r13, %r14, %r15。

%rax 作为函数返回值使用的。

%rsp 栈指针寄存器,指向栈顶

%rdi, %rsi, %rdx, %rcx, %r8, %r9 用作函数参数,依次对应第1参数,第2参数。。。

%rbx, %rbp, %r12, %r13, %r14, %r15 用作数据存储,遵循调用者使用规则,换句话说,就是随便用。调用子函数之前要备份它,以防它被修改

%r10, %r11 用作数据存储,就是使用前要先保存原值。

上下文切换,就是将CPU的寄存器暂时保存,再将即将运行的协程的上下文寄存器,分别mov到相对应的寄存器上。此时上下文完成切换。如下图所示:

协程切换之CPU寄存器操作图

切换_switch函数定义:

int _switch(nty_cpu_ctx *new_ctx, nty_cpu_ctx *cur_ctx);

参数1:即将运行协程的上下文,寄存器列表

参数2:正在运行协程的上下文,寄存器列表

我们nty_cpu_ctx结构体的定义,为了兼容x86,结构体项命令采用的是x86的寄存器名字命名。

typedef struct _nty_cpu_ctx {

void *esp; //

void *ebp;

void *eip;

void *edi;

void *esi;

void *ebx;

void *r1;

void *r2;

void *r3;

void *r4;

void *r5;

} nty_cpu_ctx;

_switch返回后,执行即将运行协程的上下文。是实现上下文的切换

0: __asm__ (

1: " .text n"

2: " .p2align 4,,15 n"

3: ".globl _switch n"

4: ".globl __switch n"

5: "_switch: n"

6: "__switch: n"

7: " movq %rsp, 0(%rsi) # save stack_pointer n"

8: " movq %rbp, 8(%rsi) # save frame_pointer n"

9: " movq (%rsp), %rax # save insn_pointer n"

10: " movq %rax, 16(%rsi) n"

11: " movq %rbx, 24(%rsi) # save rbx,r12-r15 n"

12: " movq %r12, 32(%rsi) n"

13: " movq %r13, 40(%rsi) n"

14: " movq %r14, 48(%rsi) n"

15: " movq %r15, 56(%rsi) n"

16: " movq 56(%rdi), %r15 n"

17: " movq 48(%rdi), %r14 n"

18: " movq 40(%rdi), %r13 # restore rbx,r12-r15 n"

19: " movq 32(%rdi), %r12 n"

20: " movq 24(%rdi), %rbx n"

21: " movq 8(%rdi), %rbp # restore frame_pointer n"

22: " movq 0(%rdi), %rsp # restore stack_pointer n"

23: " movq 16(%rdi), %rax # restore insn_pointer n"

24: " movq %rax, (%rsp) n"

25: " ret n"

26: );

按照x86_64的寄存器定义,%rdi保存第一个参数的值,即new_ctx的值,%rsi保存第二个参数的值,即保存cur_ctx的值。X86_64每个寄存器是64bit,8byte。

Movq %rsp, 0(%rsi) 保存在栈指针到cur_ctx实例的rsp项

Movq %rbp, 8(%rsi)

Movq (%rsp), %rax #将栈顶地址里面的值存储到rax寄存器中。Ret后出栈,执行栈顶

Movq %rbp, 8(%rsi) #后续的指令都是用来保存CPU的寄存器到new_ctx的每一项中

Movq 8(%rdi), %rbp #将new_ctx的值

Movq 16(%rdi), %rax #将指令指针rip的值存储到rax中

Movq %rax, (%rsp) # 将存储的rip值的rax寄存器赋值给栈指针的地址的值。

Ret # 出栈,回到栈指针,执行rip指向的指令。

上下文环境的切换完成。

更多分享

linux控制协程参数,Linux高性能网络:协程系列06-协程实现之切换-Go语言中文社区...相关推荐

  1. linux grub.cfg挂了,关于linux系统grub.cfg文件的问题(百度到的内容,记录一下)-Go语言中文社区...

    突然想到一个问题:Linux系统在启动之后是怎么知道该去硬盘的哪个地址(哪个磁道,哪个扇区?)找文件系统的根目录文件的第一个block块的呢,在查找解答的过程中,觉得以下内容比较不错,特此记录. 以下 ...

  2. linux sar使用方法,Linux系列之SAR命令使用详解-Go语言中文社区

    1. CPU利用率 sar -p (查看全天) sar -u 1 10 (1:每隔一秒,10:写入10次) 1.1. CPU输出项说明 输出项 详细说明 CPU all 表示统计信息为所有 CPU 的 ...

  3. 树莓派linux iso镜像下载,树莓派入门(一) - 下载安装系统镜像,Raspbian和Centos-Go语言中文社区...

    简述 本节我们将讲解树莓派如何烧录镜像,这也是使用树莓派的第一步. 我们这次分别讲解Raspbian官方系统和Centos系统的安装. 树莓派还有很多版本的系统,可以查看http://shumeipa ...

  4. linux控制协程参数,Linux高性能网络:协程系列05-协程实现之原语操作

    目录 5.协程的实现之原语操作 问题:协程的内部原语操作有哪些?分别如何实现的? 协程的核心原语操作:create, resume, yield.协程的原语操作有create怎么没有exit?以Nty ...

  5. linux设置sfq队列参数,Linux系统运维之Linux高级流量控制工具TC使用方法

    Linux系统运维之Linux高级流量控制工具TC使用方法 本文标签: 运维 流量劫持 Linux系统运维之Linux高级流量控制工具TC使用方法, 在做MHA测试的时候,有一个重要的环节就是测试MH ...

  6. linux线程多参数传递参数,Linux中多线程编程并传递多个参数

    解析Linux中多线程编程并传递多个参数 Linux中多线程编程并传递多个参数实例是本文讲解的内容,不多说,先来看内容. Linux下的多线程编程,并将多个参数传递给线程要执行的函数. 以下是实验程序 ...

  7. linux控制终端关机命令,linux定时关机命令?linux立即关机命令?终端切换界面?windows定时关机和linux定时关机的方法(shut...

    你是否正在寻找关于linux定时关机命令的内容?让我把最完整的东西奉献给你: windows定时关机和linux定时关机的方法(shutdown命令) 作者:佚名 字体:[ ] 来源:互联网 时间:0 ...

  8. WSL安装Oracle,折腾记录:WSL(Windows Subsystem for Linux,Windows上的Linux子系统)安装后的环境配置-Go语言中文社区...

    WSL(Windows Subsystem for Linux,Windows上的Linux子系统)的安装比较简单,教程网上较多,此处略过.安装后须要进行一系列配置(如软件源配置.中文配置.图形化配置 ...

  9. qt程序部署在linux,Qt应用打包发布,部署真正的Qt程序LinuxWindows-Go语言中文社区...

    最近在发布Qt应用时遇到了一些困难,Windows还好,在Linux上面发布遇到了不少的麻烦(实际Linux应该简单才对),经过在网络搜索发现帖子不少,但都比较片面,现把Qt应用程序在Linux&am ...

最新文章

  1. 文言文能编程了,口水战也开始了
  2. 区块链今年,胜过过去十年
  3. Xcode控制台打印集锦
  4. java两个函数名字相同_为什么C不允许两个具有相同名称的函数/类模板,只有非类型模板参数(整数类型)的类型不同?...
  5. [Silverlight]奇技银巧系列-3
  6. 初识ABP vNext(8):ABP特征管理
  7. 互斥锁、条件变量、信号量浅析
  8. 2016年下半年勒索软件数量翻倍
  9. MySQL:数据库备份批处理脚本
  10. 编辑器hbuilderx的下载与安装 0907
  11. try、catch和finally中都有return语句的情况
  12. (C/C++) Link List - C++ 版本
  13. python十大重点_你见过的最全面的 Python 重点
  14. nuget 下载nupkg 以及依赖包
  15. AD10 PCB等长布线----蛇形布线
  16. java 微信 源码_java微信支付功能实现源码
  17. python3 flask 使用Mysql数据库
  18. Unity 实用小技巧(更新ing)
  19. 《天下无贼》经典台词与遗憾
  20. 西安python程序员薪资_最新程序员薪资统计来了!Java均薪16K,Python22k!你拖后腿了吗?...

热门文章

  1. cad查看_在查看CAD图纸时怎么将图层进行锁定
  2. 计算机二级考试中所有判断题(含答案)
  3. screenrecord 使用_【玩机组出品】无需ROOT,教你adb shell screenrecord录屏
  4. python实现括号匹配_python实现括号匹配
  5. 公开课 | 用AI给旧时光上色!详解GAN在黑白照片上色中的应用
  6. win10如何设置关机
  7. 如何通用系统平台这个黑科技把网店做大,需要注意什么?
  8. 2017—2018 20162329 张旭升 实验报告:树
  9. 跟着团子学SAP PS:论收入成本匹配颗粒度及企业会计科目设置对WBS结构设计的影响 POC/KKA2
  10. 途经一个陌生城市,你有朋友可以想起吗?