my-server
← Wiki

Setcontext

setcontext is one of a family of C library functions (the others being getcontext, makecontext and swapcontext) used for context control. The <code>setcontext</code> family allows the implementation in C of advanced control flow patterns such as iterators, fibers, and coroutines. They may be viewed as an advanced version of setjmp/longjmp; whereas the latter allows only a single non-local jump up the stack, <code>setcontext</code> allows the creation of multiple cooperative threads of control, each with its own stack.

Specification

<code>setcontext</code> is specified in POSIX.1-2001 and the Single Unix Specification, version 2, but not all Unix-like operating systems provide them. POSIX.1-2004 obsoleted these functions, and in POSIX.1-2008 they are not included, with POSIX Threads indicated as a possible replacement.

Definitions

The functions and associated types are defined in the <code>ucontext.h</code> system header file. This includes the <code>ucontext_t</code> type, with which all four functions operate:

<code>uc_link</code> points to the context which will be resumed when the current context exits, if the context was created with <code>makecontext</code> (a secondary context). <code>uc_sigmask</code> is used to store the set of signals blocked in the context, and <code>uc_stack</code> is the stack used by the context. <code>uc_mcontext</code> stores execution state, including all registers and CPU flags, the instruction pointer, and the stack pointer; <code>mcontext_t</code> is an opaque type.

The functions are:

  • :This function transfers control to the context in <code>ucp</code>. Execution continues from the point at which the context was stored in <code>ucp</code>. <code>setcontext</code> does not return.
  • :Saves current context into <code>ucp</code>. This function returns in two possible cases: after the initial call, or when a thread switches to the context in <code>ucp</code> via <code>setcontext</code> or <code>swapcontext</code>. The <code>getcontext</code> function does not provide a return value to distinguish the cases (its return value is used solely to signal error), so the programmer must use an explicit flag variable, which must not be a register variable and must be declared volatile to avoid constant propagation or other compiler optimizations.
  • :The <code>makecontext</code> function sets up an alternate thread of control in <code>ucp</code>, which has previously been initialised using <code>getcontext</code>. The <code>ucp.uc_stack</code> member should be pointed to an appropriately sized stack; the constant <code>SIGSTKSZ</code> is commonly used. When <code>ucp</code> is jumped to using <code>setcontext</code> or <code>swapcontext</code>, execution will begin at the entry point to the function pointed to by <code>func</code>, with <code>argc</code> arguments as specified. When <code>func</code> terminates, control is returned to <code>ucp.uc_link</code>.
  • :Transfers control to <code>ucp</code> and saves the current execution state into <code>oucp</code>.

Example

The example below demonstrates an iterator using <code>setcontext</code>.

NOTE: this example is not correct, but may work as intended in some cases. The function <code>makecontext</code> requires additional parameters to be type <code>int</code>, but the example passes pointers. Thus, the example may fail on 64-bit machines (specifically LP64-architectures, where ). This problem can be worked around by breaking up and reconstructing 64-bit values, but that introduces a performance penalty.

For get and set context, a smaller context can be handy:

This makes an infinite loop because context holds the program counter.

References

External links