1MAKECONTEXT(3) Linux Programmer's Manual MAKECONTEXT(3)
2
3
4
6 makecontext, swapcontext - manipulate user context
7
9 #include <ucontext.h>
10
11 void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
12
13 int swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
14
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
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 appropriately.
43
45 ENOMEM Insufficient stack space left.
46
48 makecontext() and swapcontext() are provided in glibc since version
49 2.1.
50
52 For an explanation of the terms used in this section, see at‐
53 tributes(7).
54
55 ┌──────────────┬───────────────┬────────────────────────────┐
56 │Interface │ Attribute │ Value │
57 ├──────────────┼───────────────┼────────────────────────────┤
58 │makecontext() │ Thread safety │ MT-Safe race:ucp │
59 ├──────────────┼───────────────┼────────────────────────────┤
60 │swapcontext() │ Thread safety │ MT-Safe race:oucp race:ucp │
61 └──────────────┴───────────────┴────────────────────────────┘
63 SUSv2, POSIX.1-2001. POSIX.1-2008 removes the specifications of make‐
64 context() and swapcontext(), citing portability issues, and recommend‐
65 ing that applications be rewritten to use POSIX threads instead.
66
68 The interpretation of ucp->uc_stack is just as in sigaltstack(2),
69 namely, this struct contains the start and length of a memory area to
70 be used as the stack, regardless of the direction of growth of the
71 stack. Thus, it is not necessary for the user program to worry about
72 this direction.
73
74 On architectures where int and pointer types are the same size (e.g.,
75 x86-32, where both types are 32 bits), you may be able to get away with
76 passing pointers as arguments to makecontext() following argc. How‐
77 ever, doing this is not guaranteed to be portable, is undefined accord‐
78 ing to the standards, and won't work on architectures where pointers
79 are larger than ints. Nevertheless, starting with version 2.8, glibc
80 makes some changes to makecontext(), to permit this on some 64-bit ar‐
81 chitectures (e.g., x86-64).
82
84 The example program below demonstrates the use of getcontext(3), make‐
85 context(), and swapcontext(). Running the program produces the follow‐
86 ing output:
87
88 $ ./a.out
89 main: swapcontext(&uctx_main, &uctx_func2)
90 func2: started
91 func2: swapcontext(&uctx_func2, &uctx_func1)
92 func1: started
93 func1: swapcontext(&uctx_func1, &uctx_func2)
94 func2: returning
95 func1: returning
96 main: exiting
97
98 Program source
99
100 #include <ucontext.h>
101 #include <stdio.h>
102 #include <stdlib.h>
103
104 static ucontext_t uctx_main, uctx_func1, uctx_func2;
105
106 #define handle_error(msg) \
107 do { perror(msg); exit(EXIT_FAILURE); } while (0)
108
109 static void
110 func1(void)
111 {
112 printf("func1: started\n");
113 printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
114 if (swapcontext(&uctx_func1, &uctx_func2) == -1)
115 handle_error("swapcontext");
116 printf("func1: returning\n");
117 }
118
119 static void
120 func2(void)
121 {
122 printf("func2: started\n");
123 printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
124 if (swapcontext(&uctx_func2, &uctx_func1) == -1)
125 handle_error("swapcontext");
126 printf("func2: returning\n");
127 }
128
129 int
130 main(int argc, char *argv[])
131 {
132 char func1_stack[16384];
133 char func2_stack[16384];
134
135 if (getcontext(&uctx_func1) == -1)
136 handle_error("getcontext");
137 uctx_func1.uc_stack.ss_sp = func1_stack;
138 uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
139 uctx_func1.uc_link = &uctx_main;
140 makecontext(&uctx_func1, func1, 0);
141
142 if (getcontext(&uctx_func2) == -1)
143 handle_error("getcontext");
144 uctx_func2.uc_stack.ss_sp = func2_stack;
145 uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
146 /* Successor context is f1(), unless argc > 1 */
147 uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
148 makecontext(&uctx_func2, func2, 0);
149
150 printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
151 if (swapcontext(&uctx_main, &uctx_func2) == -1)
152 handle_error("swapcontext");
153
154 printf("main: exiting\n");
155 exit(EXIT_SUCCESS);
156 }
157
159 sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3),
160 sigsetjmp(3)
161
163 This page is part of release 5.10 of the Linux man-pages project. A
164 description of the project, information about reporting bugs, and the
165 latest version of this page, can be found at
166 https://www.kernel.org/doc/man-pages/.
167
168
169
170GNU 2020-12-21 MAKECONTEXT(3)