概述 ucontext系列允许在C中实现高级控制流模式,例如迭代器,纤维和协程。...主要的4个函数 int setcontext(const ucontext_t *ucp) This function transfers control to the context in ucp....When func terminates, control is returned to ucp.uc_link. int swapcontext(ucontext_t oucp, ucontext_t...内部结构 /* sys/ucontext.h */ typedef struct { void *ss_sp; /* Base address of stack */ int...{ unsigned long int uc_flags; struct ucontext *uc_link; stack_t uc_stack; mcontext_t
In a System V-like environment, one has the type ucontext_t defined in and the four functions...typedef struct ucontext { unsigned long int uc_flags; struct ucontext *uc_link; stack_t uc_stack..., storing it in the ucontext struct pointed to by ucp....int swapcontext(ucontext_t *oucp, ucontext_t *ucp); The swapcontext() function saves the current context...三、示例 3.1 MAN手册示例 #include #include #include static ucontext_t uctx_main
120 us 5.5 us 237 ns libgo 2018年版本 with boost 197 ns 5.3 us 124 ns 2.3 us 441 ns libgo 2018年版本 with ucontext...539 ns 7.0 us 482 ns 2.7 us 921 ns goroutine(golang) 425 ns 1.0 us 710 ns 1.0 us 1047 ns linux ucontext...,"fill":false,"yAxisID":'y-axis-2',"data":[197,124,441],"type":'line'},{"label":"libgo 2018年版本 with ucontext...20, 147, 1)","fill":false,"yAxisID":'y-axis-2',"data":[425,710,1047],"type":'line'},{"label":"linux ucontext..."rgba(250, 128, 114, 1)","yAxisID":'y-axis-1',"data":[null,5300,2300]},{"label":"libgo 2018年版本 with ucontext
3.使用ucontext实现。 4.使用汇编语言实现。 下面将逐条进行简要的分析。...四、使用ucontext实现协程切换 1.ucontext相关函数简介 在system-v环境中文件中定义了的这些函数:getcontext(), setcontext(), makecontext...在介绍函数之前,先学习一个ucontext_t类型的结构体,它表示协程的上下文环境: typedef struct ucontext { struct ucontext *uc_link;...下面学习一下相关函数: int getcontext(ucontext_t *ucp); int swapcontext(ucontext_t *oucp, ucontext_t *ucp); void...makecontext(ucontext_t *ucp, void (*func)(), int argc, ...); int setcontext(const ucontext_t *ucp);
int getcontext(ucontext_t *ucp); int setcontext(const ucontext_t *ucp); void makecontext(ucontext_t *...ucp, void (*func)(), int argc, ...); int swapcontext(ucontext_t *oucp, const ucontext_t *ucp); glibc...; 我们看到ucontext_t是对上下文实现一个更高层次的封装。...// oEAX是eax字段在ucontext_t结构中的位置,这里就是把ucontext_t中eax的值置为0 movl $0, oEAX(%eax) // 同上 movl...// edx + ecx * 4 + 4指向保存ucontext_t.ucontext的值的内存地址。
构建时报 PC_FROM_UCONTEXT 未定义 ?...PC_FROM_UCONTEXT command 左击进到这个宏定义部分,将原来的 PC_FROM_UCONTEXT 宏定义替换为 #undef HAVE_UCONTEXT_H #undef PC_FROM_UCONTEXT...#if defined(__x86_64__) #define PC_FROM_UCONTEXT uc_mcontext->__ss....__rip #elif defined(__i386__) #define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip #endif ?...PC_FROM_UCONTEXT
Linux内核为协程编程提供了支持,相关的函数声明在ucontext.h头文件中。...也可以借助longjmp、setjmp、pthread_attr_setstackaddr等组合实现,但复杂很多,ucontext提供的函数已帮助做了很多工作。.../ 定义3个协程,类似于3个线程 static void foo(); static void woo(); static void zoo(); static ucontext_t... ctx1; // 协程zoo的上下文,由makecontext调用构造 static ucontext_t ctx2; // 协程woo的上下文,由makecontext调用构造 static... ucontext_t ctx3; // 协程foo的上下文,由swapcontext自动构造 // stack为new/malloc出来的也可以的 static char stack1
,CPU 上下文管理 下面关于 ucontext 的介绍源自:http://pubs.opengroup.org/onlinepubs/7908799/xsh/ucontext.h.html 。...所以下文中涉及 ucontext 的上下文均指当前线程的上下文。...一般CPU 有多个核心,一个线程在某一时刻只能使用其中一个,所以 ucontext 只涉及一个与当前线程相关的 CPU 核心 ucontext.h 头文件中定义了 ucontext_t 这个结构体,这个结构体中至少包含以下成员...*, const ucontext_t *); getcontext & setcontext #include int getcontext(ucontext_t *ucp... void makecontext(ucontext_t *ucp, (void *func)(), int argc, ...); int swapcontext(ucontext_t
linux根据POSIX标准提供了ucontext库支持原生协程,但是在POSIX.1-2008中被废除了。大概是因为协程在语言级别就能实现,所以没必要扔系统层,KISS?...makecontext(ucontext_t *ucp, void (*func)(), int argc, ...) - 创建ucontext并赋予栈空间 setcontext(const ucontext_t...*ucp) - 从ucp获取ucontext并设置上下文 getcontext(ucontext_t*ucp) - 保存当前的ucontext在ucp中 swapcontext(ucontext_t*...oucp, ucontext_t*ucp)- 相当于get然后set其他协程 生产者直接调度至消费者,最优调度 ---- Context Switch 上下文切换是调度的核心,在libco中通过coctx_swap.S...对应swapcontext(ucontext_t*oucp, ucontext_t*ucp) 结构体声明 印证了上面提到的TCB冗余,这里的上下文仅仅保存了除了r10和r11之外的通用寄存器、栈的大小、
如果想要真正获取到上下文信息,可以使用 ucontext.h 库。...使用ucontext 下面关于 ucontext 的介绍源自: http://pubs.opengroup.org/onlinepubs/7908799/xsh/ucontext.h.html 实际上...ucontext 只涉及一个与当前线程相关的 CPU 核心) ucontext.h 头文件中定义了 ucontext_t 这个结构体,这个结构体中至少包含以下成员: ucontext_t *uc_link...int swapcontext(ucontext_t *, const ucontext_t *); 下面分别来看。...swapcontext #include int swapcontext(ucontext_t *oucp, const ucontext_t *ucp); swapcontext
相应的函数参数 int ret; int status; ASYNC_WAIT_CTX *waitctx; }; typedef struct async_fibre_st { ucontext_t...因为已经有了ucontext接口,不需要_setjmp/_longjmp int env_init;//这个不知道干嘛,感觉是为了切换ucontext和jmp两套接口 } async_fibre...; ucontext_t的创建办法(差不多都是这个固定写法) if (getcontext(&fibre->fibre) == 0) {//获取到一个ucontext_t对象,后续初始化该context...fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE);ucontext_t保存一个栈空间 if (fibre-...fibre.uc_stack.ss_size = STACKSIZE;//此处为32KB,比栈的16M少很多 fibre->fibre.uc_link = NULL;//设置下一个ucontext_t
owl.context 接口设计 业界比较有名的上下文切换库有 ucontext 和 boost.context,其中 ucontext 的接口文档齐全且语义清晰,而 boost.context 的接口略显晦涩...为了代码便于理解,一开始 owl.context 打算直接兼容 ucontext 接口,仔细研究后发现 ucontext 的一些设计在如今看来并不合理,严格遵循 ucontext 的接口会导致不必要的实现复杂度...因此最终的接口整体保留了 ucontext 的语义,但在细节上做了一些优化。...中 makecontext 的函数原型为: void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...); 由于其入口函数可以支持多个...int 参数,参数个数大于 4 时需要进行压栈,因此 ucontext 中实现 makecontext 会比较复杂。
Ucontext ucontext涉及到协程相关的技术,该技术和系统调⽤在R3、R0间的切换⽐较类似。但是该技术作⽤于⽤户态,⽬ 的是给⽤户态程序提供更快的切换效果,以及使得⽤户态的代码能够更加灵活。...常⽤的函数为getcontext/setcontext: setjmp/longjmp的技术原理和实现和ucontext类似,就不提及了。...ucontext协程技术涉及到上下⽂切换的场景,也会存在数据栈切换的情况,因此,shadow stack也需要做出相应 的动作。 ...中的改动,先⽤ __NR_arch_prctl 系统调⽤获取当前shadow stack的基地址,其 次将其保存在SSP_BASE_OFFSET寄存器中,随后保存shadow stack基地址、ssp值在ucontext...结构体中,供后续 setcontext使⽤: 再来看setcontext中的改动,校验getcontext保存的ucontext中的shadow stack基地址和ssp,再恢复,达到切换 回上⽂状态的
整体基于ucontext和共享栈模型实现了有栈协程,代码质量毋庸置疑,本文将详细剖析该协程库的实现原理。 同时,我也提供了coroutine注释版,辅助大家理解coroutine的代码。...Linux下提供了一套函数,叫做ucontext簇函数,可以用来获取和设置当前线程的上下文内容。这也是coroutine的核心方法。...接下来是makecontext,这个函数用来设置对应ucontext的执行函数。如上,将C->ctx的执行函数体设置为了mainfunc。...swapcontext 将当前上下文保存到当前协程的ucontext里面,同时替换当前上下文为主协程的上下文。 这样的话,当前协程会被挂起,主协程会被继续执行。...参考 ucontext簇函数学习 为什么觉得协程是趋势?
其中 ucontext 提供了 getcontext()、makecontext()、swapcontext() 以及 setcontext() 函数实现协程的创建和切换,si78c 中的初始化函数为...代码 2-1 // 切换协程时用的中间变量 static ucontext_t frontend_ctx; // 游戏主要逻辑协程 static ucontext_t main_ctx; // 游戏中断逻辑协程...static ucontext_t int_ctx; // 用于切换两个协程 static ucontext_t *prev_ctx; static ucontext_t *curr_ctx;...) { // 给 co_switch 包装了一层,简化了代码量 co_switch(curr_ctx, to); } // 协程切换函数 static void co_switch(ucontext_t...*prev, ucontext_t *next) { prev_ctx = prev; curr_ctx = next; // 切换到 next 指向的上下文,将当前上下文保存在
我们先从协程开始,关于协程的数据结构定义如下:typedef struct _nty_coroutine { //协程的定义//private#ifdef _USE_UCONTEXT ucontext_t...typedef struct _nty_schedule { //协程调度结构uint64_t birth; //协程诞生时间#ifdef _USE_UCONTEXT //ucontext_t 实现上下文...ucontext_t ctx;#else //cpu 保存上下文nty_cpu_ctx ctx;#endifvoid *stack; size_t stack_size; //栈大小int spawned_coroutines
除此之外,libco不使用ucontext进行用户态上下文的切换,而是自行写了一套汇编来进行上下文切换。 另外,libco利用co_create创建的协程, 需要自行调用co_release进行释放。...协程上下文切换性能更好 我们之前提到,云风的coroutine库使用ucontext来实现用户态的上下文切换,这也是实现协程的关键。...而libco基于性能优化的考虑,没有使用ucontext,而是自行编写了一套汇编来处理上下文的切换, 具体代码在coctx_swap.S。...栈:rsp栈顶指针 相比于ucontext,缺少了浮点数上下文和sigmask(信号屏蔽掩码)。具体可对比glibc的相关源码。...据知乎网友的实验证明:libco的上下文切换效率大致是ucontext的3.6倍。
我们选用两个协程库进行介绍,云风的基于ucontext函数簇的协程库和libco。...基于ucontext协程库 ucontext即user thread context,用户线程上下文,是Linux系统自带的一套用于获取、修改和切换当前线程上下文的结构和相关方法;主要包括:ucontext_t...结构体和context函数簇; 关于ucontext函数簇 其中ucontext_t结构体: typedef struct ucontext { unsigned long int uc_flags...*ucp),将当前执行上下文信息保存在ucp指向的ucontext结构体中 int setcontext(const ucontext_t *ucp),将ucp中保存的寄存器信息恢复到CPU中,用于将当前程序切换到目标上下文...,初始化一个ucontext_t,并设置入口函数为func int swapcontext(ucontext_t *oucp, const ucontext_t *ucp),切换上下文,保存当前上下文到
32K占用) - 3.8 us 6275 ns 4.0 us 6429 ns libgo with boost 197 ns 5.3 us 124 ns 2.3 us 441 ns libgo with ucontext...539 ns 7.0 us 482 ns 2.7 us 921 ns goroutine(golang) 464 ns 578 ns 538 ns 1.4 us 799 ns linux ucontext...libco 测试代码: https://gist.github.com/owent/1842b56ac1edd5a7db54590d41af1c44#file-libco_benchmark-cpp ucontext...测试代码: https://gist.github.com/owent/1842b56ac1edd5a7db54590d41af1c44#file-ucontext_benchmark-cpp libgo
cross-compile-prefix 指定交叉编译器名字前缀 no-async arm-xm-linux的machine定义为arm-xm-linux-ulibcgnueabi,没有提供GNU C的ucontext
领取专属 10元无门槛券
手把手带您无忧上云