1 \" Copyright (C) 2001 Andries Brouwer (aeb@cwi.nl)
2 .\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date. The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein. The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
26 .\" 2006-08-02, mtk, Added example program
28 .TH MAKECONTEXT 3 2014-05-28 "GNU" "Linux Programmer's Manual"
30 makecontext, swapcontext \- manipulate user context
32 .B #include <ucontext.h>
34 .BI "void makecontext(ucontext_t *" ucp ", void (*" func )(),
35 .BI "int " argc ", ...);"
37 .BI "int swapcontext(ucontext_t *" oucp ", const ucontext_t *" ucp );
39 In a System V-like environment, one has the type \fIucontext_t\fP defined in
41 and the four functions
47 that allow user-level context switching
48 between multiple threads of control within a process.
50 For the type and the first two functions, see
55 function modifies the context pointed to
56 by \fIucp\fP (which was obtained from a call to
60 the caller must allocate a new stack
61 for this context and assign its address to \fIucp\->uc_stack\fP,
62 and define a successor context and
63 assign its address to \fIucp\->uc_link\fP.
65 When this context is later activated (using
69 the function \fIfunc\fP is called,
70 and passed the series of integer
74 the caller must specify the number of these arguments in
76 When this function returns, the successor context is activated.
77 If the successor context pointer is NULL, the thread exits.
81 function saves the current context in
82 the structure pointed to by \fIoucp\fP, and then activates the
83 context pointed to by \fIucp\fP.
88 (But we may return later, in case \fIoucp\fP is
89 activated, in which case it looks like
95 sets \fIerrno\fP appropriately.
99 Insufficient stack space left.
104 are provided in glibc since version 2.1.
106 .SS Multithreading (see pthreads(7))
111 functions are thread-safe.
114 POSIX.1-2008 removes the specifications of
118 citing portability issues, and
119 recommending that applications be rewritten to use POSIX threads instead.
121 The interpretation of \fIucp\->uc_stack\fP is just as in
123 namely, this struct contains the start and length of a memory area
124 to be used as the stack, regardless of the direction of growth of
126 Thus, it is not necessary for the user program to
127 worry about this direction.
129 On architectures where
131 and pointer types are the same size
132 (e.g., x86-32, where both types are 32 bits),
133 you may be able to get away with passing pointers as arguments to
137 However, doing this is not guaranteed to be portable,
138 is undefined according to the standards,
139 and won't work on architectures where pointers are larger than
141 Nevertheless, starting with version 2.8, glibc makes some changes to
143 to permit this on some 64-bit architectures (e.g., x86-64).
146 The example program below demonstrates the use of
151 Running the program produces the following output:
156 main: swapcontext(&uctx_main, &uctx_func2)
158 func2: swapcontext(&uctx_func2, &uctx_func1)
160 func1: swapcontext(&uctx_func1, &uctx_func2)
169 #include <ucontext.h>
173 static ucontext_t uctx_main, uctx_func1, uctx_func2;
175 #define handle_error(msg) \\
176 do { perror(msg); exit(EXIT_FAILURE); } while (0)
181 printf("func1: started\\n");
182 printf("func1: swapcontext(&uctx_func1, &uctx_func2)\\n");
183 if (swapcontext(&uctx_func1, &uctx_func2) == \-1)
184 handle_error("swapcontext");
185 printf("func1: returning\\n");
191 printf("func2: started\\n");
192 printf("func2: swapcontext(&uctx_func2, &uctx_func1)\\n");
193 if (swapcontext(&uctx_func2, &uctx_func1) == \-1)
194 handle_error("swapcontext");
195 printf("func2: returning\\n");
199 main(int argc, char *argv[])
201 char func1_stack[16384];
202 char func2_stack[16384];
204 if (getcontext(&uctx_func1) == \-1)
205 handle_error("getcontext");
206 uctx_func1.uc_stack.ss_sp = func1_stack;
207 uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
208 uctx_func1.uc_link = &uctx_main;
209 makecontext(&uctx_func1, func1, 0);
211 if (getcontext(&uctx_func2) == \-1)
212 handle_error("getcontext");
213 uctx_func2.uc_stack.ss_sp = func2_stack;
214 uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
215 /* Successor context is f1(), unless argc > 1 */
216 uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
217 makecontext(&uctx_func2, func2, 0);
219 printf("main: swapcontext(&uctx_main, &uctx_func2)\\n");
220 if (swapcontext(&uctx_main, &uctx_func2) == \-1)
221 handle_error("swapcontext");
223 printf("main: exiting\\n");