setcontext is one of a family of C library functions (the others being getcontext, makecontext and swapcontext) used for context control. The setcontext
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, setcontext
allows the creation of multiple cooperative threads of control, each with its own stack.
setcontext
was 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 were removed, with POSIX Threads indicated as a possible replacement.
The functions and associated types are defined in the ucontext.h
system header file. This includes the ucontext_t
type, with which all four functions operate:
uc_link
points to the context which will be resumed when the current context exits, if the context was created with makecontext
(a secondary context). uc_sigmask
is used to store the set of signals blocked in the context, and uc_stack
is the stack used by the context. uc_mcontext
stores execution state, including all registers and CPU flags, the instruction pointer, and the stack pointer; mcontext_t
is an opaque type.
The functions are:
This function transfers control to the context in ucp
. Execution continues from the point at which the context was stored in ucp
. setcontext
does not return.
Saves current context into ucp
. This function returns in two possible cases: after the initial call, or when a thread switches to the context in ucp
via setcontext
or swapcontext
. The getcontext
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 makecontext
function sets up an alternate thread of control in ucp
, which has previously been initialised using getcontext
. The ucp.uc_stack
member should be pointed to an appropriately sized stack; the constant SIGSTKSZ
is commonly used. When ucp
is jumped to using setcontext
or swapcontext
, execution will begin at the entry point to the function pointed to by func
, with argc
arguments as specified. When func
terminates, control is returned to ucp.uc_link
.
Transfers control to ucp
and saves the current execution state into oucp
.
The example below demonstrates an iterator using setcontext
.
/* The three contexts: * (1) main_context1 : The point in main to which loop will return. * (2) main_context2 : The point in main to which control from loop will * flow by switching contexts. * (3) loop_context : The point in loop to which control from main will * flow by switching contexts. */ucontext_t main_context1, main_context2, loop_context;
/* The iterator return value. */volatile int i_from_iterator;
/* This is the iterator function. It is entered on the first call to * swapcontext, and loops from 0 to 9. Each value is saved in i_from_iterator, * and then swapcontext used to return to the main loop. The main loop prints * the value and calls swapcontext to swap back into the function. When the end * of the loop is reached, the function exits, and execution switches to the * context pointed to by main_context1. */void loop(ucontext_t *loop_context, ucontext_t *other_context, int *i_from_iterator) int main(void)NOTE: this example is not correct,[1] but may work as intended in some cases. The function makecontext
requires additional parameters to be type int
, but the example passes pointers. Thus, the example may fail on 64-bit machines (specifically LP64-architectures, where
For get and set context, a smaller context can be handy:
int main(int argc, const char *argv[])This makes an infinite loop because context holds the program counter.