Provided by: manpages-dev_2.77-1_all bug

NAME

       makecontext, swapcontext - manipulate user context

SYNOPSIS

       #include <ucontext.h>

       void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

       int swapcontext(ucontext_t *oucp, ucontext_t *ucp);

DESCRIPTION

       In  a System V-like environment, one has the type ucontext_t defined in
       <ucontext.h>  and  the  four  functions  getcontext(2),  setcontext(2),
       makecontext() and swapcontext() that allow user-level context switching
       between multiple threads of control within a process.

       For the type and the first two functions, see getcontext(2).

       The makecontext() function modifies  the  context  pointed  to  by  ucp
       (which  was  obtained  from  a call to getcontext(2)).  Before invoking
       makecontext(), the caller must allocate a new stack  for  this  context
       and assign its address to ucp->uc_stack, and define a successor context
       and assign its address to ucp->uc_link.

       When  this  context  is  later  activated   (using   setcontext(2)   or
       swapcontext())  the  function  func is called, and passed the series of
       integer (int) arguments that follow argc; the caller must  specify  the
       number  of  these  arguments  in argc.  When this function returns, the
       successor context is activated.  If the successor  context  pointer  is
       NULL, the thread exits.

       The  swapcontext()  function saves the current context in the structure
       pointed to by oucp, and then activates the context pointed to by ucp.

RETURN VALUE

       When successful, swapcontext() does not return.   (But  we  may  return
       later,  in  case  oucp  is  activated,  in  which  case  it  looks like
       swapcontext() returns 0.)  On error, swapcontext() returns -1 and  sets
       errno appropriately.

ERRORS

       ENOMEM Insufficient stack space left.

CONFORMING TO

       SUSv2, POSIX.1-2001.

NOTES

       The  interpretation  of  ucp->uc_stack  is  just  as in sigaltstack(2),
       namely, this struct contains the start and length of a memory  area  to
       be  used  as  the  stack,  regardless of the direction of growth of the
       stack.  Thus, it is not necessary for the user program to  worry  about
       this direction.

EXAMPLE

       The  example  program  below  demonstrates  the  use  of getcontext(2),
       makecontext(), and swapcontext().  Running  the  program  produces  the
       following output:

           $ ./a.out
           main: swapcontext(&uctx_main, &uctx_func2)
           func2: started
           func2: swapcontext(&uctx_func2, &uctx_func1)
           func1: started
           func1: swapcontext(&uctx_func1, &uctx_func2)
           func2: returning
           func1: returning
           main: exiting

       #include <ucontext.h>
       #include <stdio.h>
       #include <stdlib.h>

       static ucontext_t uctx_main, uctx_func1, uctx_func2;

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       static void
       func1(void)
       {
           printf("func1: started\n");
           printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
           if (swapcontext(&uctx_func1, &uctx_func2) == -1)
               handle_error("swapcontext");
           printf("func1: returning\n");
       }

       static void
       func2(void)
       {
           printf("func2: started\n");
           printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
           if (swapcontext(&uctx_func2, &uctx_func1) == -1)
               handle_error("swapcontext");
           printf("func2: returning\n");
       }

       int
       main(int argc, char *argv[])
       {
           char func1_stack[16384];
           char func2_stack[16384];

           if (getcontext(&uctx_func1) == -1)
               handle_error("getcontext");
           uctx_func1.uc_stack.ss_sp = func1_stack;
           uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
           uctx_func1.uc_link = &uctx_main;
           makecontext(&uctx_func1, func1, 0);

           if (getcontext(&uctx_func2) == -1)
               handle_error("getcontext");
           uctx_func2.uc_stack.ss_sp = func2_stack;
           uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
           /* Successor context is f1(), unless argc > 1 */
           uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
           makecontext(&uctx_func2, func2, 0);

           printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
           if (swapcontext(&uctx_main, &uctx_func2) == -1)
               handle_error("swapcontext");

           printf("main: exiting\n");
           exit(EXIT_SUCCESS);
       }

SEE ALSO

       getcontext(2),     sigaction(2),     sigaltstack(2),    sigprocmask(2),
       sigsetjmp(3)

COLOPHON

       This page is part of release 2.77 of the Linux  man-pages  project.   A
       description  of  the project, and information about reporting bugs, can
       be found at http://www.kernel.org/doc/man-pages/.