1MAKECONTEXT(3)             Linux Programmer's Manual            MAKECONTEXT(3)
2
3
4

NAME

6       makecontext, swapcontext - manipulate user context
7

SYNOPSIS

9       #include <ucontext.h>
10
11       void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
12       int swapcontext(ucontext_t *restrict oucp,
13                       const ucontext_t *restrict ucp);
14

DESCRIPTION

16       In a System V-like environment, one has the type ucontext_t (defined in
17       <ucontext.h> and described in getcontext(3))  and  the  four  functions
18       getcontext(3), setcontext(3), makecontext(), and swapcontext() that al‐
19       low user-level context switching between multiple  threads  of  control
20       within a process.
21
22       The  makecontext()  function  modifies  the  context  pointed to by ucp
23       (which was obtained from a call  to  getcontext(3)).   Before  invoking
24       makecontext(),  the  caller  must allocate a new stack for this context
25       and assign its address to ucp->uc_stack, and define a successor context
26       and assign its address to ucp->uc_link.
27
28       When  this  context is later activated (using setcontext(3) or swapcon‐
29       text()) the function func is called, and passed the series  of  integer
30       (int) arguments that follow argc; the caller must specify the number of
31       these arguments in argc.  When this  function  returns,  the  successor
32       context  is  activated.   If the successor context pointer is NULL, the
33       thread exits.
34
35       The swapcontext() function saves the current context in  the  structure
36       pointed to by oucp, and then activates the context pointed to by ucp.
37

RETURN VALUE

39       When  successful,  swapcontext()  does  not return.  (But we may return
40       later, in case oucp is activated, in which case it looks like  swapcon‐
41       text()  returns  0.)  On error, swapcontext() returns -1 and sets errno
42       to indicate the error.
43

ERRORS

45       ENOMEM Insufficient stack space left.
46

VERSIONS

48       makecontext() and swapcontext() are provided  in  glibc  since  version
49       2.1.
50

ATTRIBUTES

52       For  an  explanation  of  the  terms  used  in  this  section,  see at‐
53       tributes(7).
54
55       ┌──────────────┬───────────────┬───────────────────────────────────────┐
56Interface     Attribute     Value                                 
57       ├──────────────┼───────────────┼───────────────────────────────────────┤
58makecontext() │ Thread safety │ MT-Safe race:ucp                      │
59       ├──────────────┼───────────────┼───────────────────────────────────────┤
60swapcontext() │ Thread safety │ MT-Safe race:oucp race:ucp            │
61       └──────────────┴───────────────┴───────────────────────────────────────┘
62

CONFORMING TO

64       SUSv2, POSIX.1-2001.  POSIX.1-2008 removes the specifications of  make‐
65       context()  and swapcontext(), citing portability issues, and recommend‐
66       ing that applications be rewritten to use POSIX threads instead.
67

NOTES

69       The interpretation of ucp->uc_stack is just as in sigaltstack(2), name‐
70       ly,  this  struct  contains the start and length of a memory area to be
71       used as the stack, regardless of the direction of growth of the  stack.
72       Thus,  it is not necessary for the user program to worry about this di‐
73       rection.
74
75       On architectures where int and pointer types are the same  size  (e.g.,
76       x86-32, where both types are 32 bits), you may be able to get away with
77       passing pointers as arguments to makecontext() following argc.   Howev‐
78       er, doing this is not guaranteed to be portable, is undefined according
79       to the standards, and won't work on architectures  where  pointers  are
80       larger than ints.  Nevertheless, starting with version 2.8, glibc makes
81       some changes to makecontext(), to permit this on some 64-bit  architec‐
82       tures (e.g., x86-64).
83

EXAMPLES

85       The  example program below demonstrates the use of getcontext(3), make‐
86       context(), and swapcontext().  Running the program produces the follow‐
87       ing output:
88
89           $ ./a.out
90           main: swapcontext(&uctx_main, &uctx_func2)
91           func2: started
92           func2: swapcontext(&uctx_func2, &uctx_func1)
93           func1: started
94           func1: swapcontext(&uctx_func1, &uctx_func2)
95           func2: returning
96           func1: returning
97           main: exiting
98
99   Program source
100
101       #include <ucontext.h>
102       #include <stdio.h>
103       #include <stdlib.h>
104
105       static ucontext_t uctx_main, uctx_func1, uctx_func2;
106
107       #define handle_error(msg) \
108           do { perror(msg); exit(EXIT_FAILURE); } while (0)
109
110       static void
111       func1(void)
112       {
113           printf("func1: started\n");
114           printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
115           if (swapcontext(&uctx_func1, &uctx_func2) == -1)
116               handle_error("swapcontext");
117           printf("func1: returning\n");
118       }
119
120       static void
121       func2(void)
122       {
123           printf("func2: started\n");
124           printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
125           if (swapcontext(&uctx_func2, &uctx_func1) == -1)
126               handle_error("swapcontext");
127           printf("func2: returning\n");
128       }
129
130       int
131       main(int argc, char *argv[])
132       {
133           char func1_stack[16384];
134           char func2_stack[16384];
135
136           if (getcontext(&uctx_func1) == -1)
137               handle_error("getcontext");
138           uctx_func1.uc_stack.ss_sp = func1_stack;
139           uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
140           uctx_func1.uc_link = &uctx_main;
141           makecontext(&uctx_func1, func1, 0);
142
143           if (getcontext(&uctx_func2) == -1)
144               handle_error("getcontext");
145           uctx_func2.uc_stack.ss_sp = func2_stack;
146           uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
147           /* Successor context is f1(), unless argc > 1 */
148           uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
149           makecontext(&uctx_func2, func2, 0);
150
151           printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
152           if (swapcontext(&uctx_main, &uctx_func2) == -1)
153               handle_error("swapcontext");
154
155           printf("main: exiting\n");
156           exit(EXIT_SUCCESS);
157       }
158

SEE ALSO

160       sigaction(2),     sigaltstack(2),     sigprocmask(2),    getcontext(3),
161       sigsetjmp(3)
162

COLOPHON

164       This page is part of release 5.12 of the Linux  man-pages  project.   A
165       description  of  the project, information about reporting bugs, and the
166       latest    version    of    this    page,    can     be     found     at
167       https://www.kernel.org/doc/man-pages/.
168
169
170
171GNU                               2021-03-22                    MAKECONTEXT(3)
Impressum