article

setcontext is one of a family of C library functions (the others being getcontext, makecontext and swapcontext) used for context control. setcontext et al allow the implementation in C of advanced control flow patterns such as iterators and coroutines.

setcontext et al can be viewed as a more advanced version of setjmp/longjmp; where the latter just allows a single non-local jump up the stack, setcontext allows the creation of multiple coöperative threads of control, each with their own stack.

Usage


The four function calls, along with the types ucontext_t and mcontext_t, are defined in <ucontext.h>.

The ucontext_t type stores execution state, including all registers and flags, the instruction pointer, and the stack pointer.

See below for an example of usage.

  • setcontext(const ucontext_t *ucp): transfer control to the context in ucp. Does not return.
  • getcontext(ucontext_t *ucp): store the current context into ucp. Will appear to return both after the initial call and whenever the context in ucp is jumped to; unfortunately, getcontext does not provide a return value to distinguish the cases, so the programmer must use a flag variable (defined volatile, and not a register variable, for obvious reasons).
  • makecontext(ucontext_t *ucp, void *func(), int argc, ...): set up an alternate thread of control, to be stored in ucp (which should have been initialised with getcontext first). ucp.uc_stack should contain an appropriately sized stack. ucp will begin control at the entry point to func, which will be called with argc arguments as supplied. When func terminates, control will pass to ucp.uc_link.
  • swapcontext(ucontext_t *oucp, ucontext_t *ucp): transfer control to ucp, saving the current execution state into oucp.

Specification


setcontext et al are described in the Single Unix Specification, version 2. Not all Unix-like operating systems have the functions, a fact which has possibly led to their being little-used.

Example


#include #include #include static void loop_iter (ucontext_t *my_ucp, ucontext_t *loop_ucp, int *yield_i) { int i; for (i = 0; i < 10; ++i) { *yield_i = i; swapcontext (my_ucp, loop_ucp); } } int main (void) { ucontext_t main_uc, loop_uc, iterator_uc; char iterator_stack*; volatile int has_run; volatile int yield_i; volatile const char *yield_path; iterator_uc.uc_link = &main_uc; iterator_uc.uc_stack.ss_sp = iterator_stack; iterator_uc.uc_stack.ss_size = sizeof iterator_stack; getcontext (&iterator_uc); makecontext (&iterator_uc, (void (*) (void)) loop_iter, 3, &iterator_uc, &loop_uc, &yield_i); has_run = 0; getcontext (&main_uc); if (!has_run) { has_run = 1; while (1) { swapcontext (&loop_uc, &iterator_uc); printf ("%d\n", yield_i); } } return 0; }

See also


External links


 

This article is licensed under the GNU Free Documentation License. It uses material from the "Setcontext".

Home Pageartsbusinesscomputersgameshealthhospitalshomekids & teensnewsphysiciansrecreationreferenceregionalscienceshoppingsocietysportsworld