getcontext系统调用了什么(ucontext.h)呢?

时间:2013-10-21 20:20:18

标签: c operating-system posix ucontext

去年我使用了操作系统,在此期间我使用了用户上下文(在标题ucontext.h中定义)来实现项目的线程调度程序(其中每个线程模拟一个进程)。我正在参加一个讲座,并将谈论用户上下文,我刚想到,尽管去年完成了这个项目,但我并不真正理解getcontext系统调用究竟是做什么的。

getcontext的手册页声明它“将ucp指向的结构初始化为当前活动的上下文”。对于setcontext的参数,它还指出“如果ucp参数是用getcontext()创建的,程序执行就会继续,好像刚刚返回了相应的getcontext()调用一样。”好的,我明白了。

所以这就是我所困惑的。通常,对于我学习它的方式,要执行上下文切换,可以初始化ucontext_t结构并交换/设置它:

ucontext_t ucp;
ucontext_t oucp;
getcontext(&ucp);

// Initialize the stack_t struct in the ucontext_t struct
ucp.uc_stack.ss_sp = malloc(STACK_SIZE);
ucp.uc_stack.ss_size = STACK_SIZE;
ucp.uc_stack.ss_flags = 0;

ucp.uc_link = /* some other context, or just NULL */;

// Don't block any signals in this context
sigemptyset(&ucp.uc_sigmask);
// Assume that fn is a function that takes 0 arguments and returns void
makecontext(&ucp, fn, 0);

// Perform the context switch. Function 'fn' will be active now
swapcontext(&oucp, &ucp);
// alternatively: setcontext(&ucp);

如果我在较小的程序中省略getcontext,则没有任何有趣的事情发生。在通过用户上下文进行更多上下文切换的较大程序中,我得到了一个只能通过添加getcontext来解决的分段错误。

getcontext究竟做了什么?为什么我不能只分配ucontext_t结构,通过初始化uc_stackuc_sigmask字段来初始化它,并在没有makecontext的情况下调用getcontext?是getcontext执行了makecontext不执行的必要初始化吗?

1 个答案:

答案 0 :(得分:5)

我在x86 / linux体系结构上查看了ucontext的GNU libc实现,因此,可能存在以下不适用的不同实现。

GNU libc manual表示:

  

传递给makecontext的ucp参数应该通过调用getcontext来初始化。

如果你看一下glibc / sysdeps / unix / linux / x86 / sys / ucontext.h中的mcontext_t,就会有一个指向浮点状态的指针(fpregset_t fpregs),它在getcontext()中初始化,并在setcontext中再次取消引用( )。但是,它不是使用makecontext()初始化的。我使用GDB进行了快速测试,当我尝试在未被getcontext()初始化的ucontext_t结构中取消引用浮点上下文时,我在setcontext()中得到了一个段错误:

  

=> 0x00007ffff784308c< + 44>:fldenv(%rcx)