1
2MAKECONTEXT(3) Linux Programmer's Manual MAKECONTEXT(3)
3
4
5
7 makecontext, swapcontext - manipulate user context
8
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
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
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
47 ENOMEM Insufficient stack space left.
48
50 makecontext() and swapcontext() are provided in glibc since version
51 2.1.
52
54 For an explanation of the terms used in this section, see
55 attributes(7).
56
57 ┌──────────────┬───────────────┬────────────────────────────┐
58 │Interface │ Attribute │ Value │
59 ├──────────────┼───────────────┼────────────────────────────┤
60 │makecontext() │ Thread safety │ MT-Safe race:ucp │
61 ├──────────────┼───────────────┼────────────────────────────┤
62 │swapcontext() │ Thread safety │ MT-Safe race:oucp race:ucp │
63 └──────────────┴───────────────┴────────────────────────────┘
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
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
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
161 sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3),
162 sigsetjmp(3)
163
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)