Setcontext
setcontext is one of a family of C library functions 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.Specification
setcontext 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 theucontext.h system header file. This includes the ucontext_t type, with which all four functions operate:typedef struct ucontext_t;
uc_link points to the context which will be resumed when the current context exits, if the context was created with makecontext. 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 inucp.setcontextdoes not return.int getcontext - :Saves current context into
ucp. This function returns in two possible cases: after the initial call, or when a thread switches to the context inucpviasetcontextorswapcontext. Thegetcontextfunction does not provide a return value to distinguish the cases, 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.void makecontext, int argc,...) - :The
makecontextfunction sets up an alternate thread of control inucp, which has previously been initialised usinggetcontext. Theucp.uc_stackmember should be pointed to an appropriately sized stack; the constantSIGSTKSZis commonly used. Whenucpis jumped to usingsetcontextorswapcontext, execution will begin at the entry point to the function pointed to byfunc, withargcarguments as specified. Whenfuncterminates, control is returned toucp.uc_link.int swapcontext - :Transfers control to
ucpand saves the current execution state intooucp.
Example
The example below demonstrates an iterator usingsetcontext.- include
- include
- include
- include
* main_context1 : The point in main to which loop will return.
* main_context2 : The point in main to which control from loop will
* flow by switching contexts.
* 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
int main
NOTE: this example is not correct, 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 > sizeof. 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:
- include
- include
- include
This makes an infinite loop because context holds the program counter.