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

NAME

7       makecontext, swapcontext - manipulate user context
8

SYNOPSIS

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

DESCRIPTION

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

RETURN VALUE

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

ERRORS

47       ENOMEM Insufficient stack space left.
48

VERSIONS

50       makecontext()  and  swapcontext()  are  provided in glibc since version
51       2.1.
52

ATTRIBUTES

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

CONFORMING TO

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

NOTES

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

EXAMPLES

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

SEE ALSO

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

COLOPHON

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