1 .\" Copyright (C) 2001 Andries Brouwer (aeb@cwi.nl)
2 .\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" 2006-08-02, mtk, Added example program
25 .TH MAKECONTEXT 3 2008-08-06 "GNU" "Linux Programmer's Manual"
27 makecontext, swapcontext \- manipulate user context
29 .B #include <ucontext.h>
31 .BI "void makecontext(ucontext_t *" ucp ", void (*" func )(),
32 .BI "int " argc ", ...);"
34 .BI "int swapcontext(ucontext_t *" oucp ", ucontext_t *" ucp );
36 In a System V-like environment, one has the type \fIucontext_t\fP defined in
38 and the four functions
44 that allow user-level context switching
45 between multiple threads of control within a process.
47 For the type and the first two functions, see
52 function modifies the context pointed to
53 by \fIucp\fP (which was obtained from a call to
57 the caller must allocate a new stack
58 for this context and assign its address to \fIucp\->uc_stack\fP,
59 and define a successor context and
60 assign its address to \fIucp\->uc_link\fP.
62 When this context is later activated (using
66 the function \fIfunc\fP is called,
67 and passed the series of integer
71 the caller must specify the number of these arguments in
73 When this function returns, the successor context is activated.
74 If the successor context pointer is NULL, the thread exits.
78 function saves the current context in
79 the structure pointed to by \fIoucp\fP, and then activates the
80 context pointed to by \fIucp\fP.
85 (But we may return later, in case \fIoucp\fP is
86 activated, in which case it looks like
92 sets \fIerrno\fP appropriately.
96 Insufficient stack space left.
101 are provided in glibc since version 2.1.
104 POSIX.1-2008 removes the specifications of
109 The interpretation of \fIucp\->uc_stack\fP is just as in
111 namely, this struct contains the start and length of a memory area
112 to be used as the stack, regardless of the direction of growth of
114 Thus, it is not necessary for the user program to
115 worry about this direction.
118 The example program below demonstrates the use of
123 Running the program produces the following output:
128 main: swapcontext(&uctx_main, &uctx_func2)
130 func2: swapcontext(&uctx_func2, &uctx_func1)
132 func1: swapcontext(&uctx_func1, &uctx_func2)
141 #include <ucontext.h>
145 static ucontext_t uctx_main, uctx_func1, uctx_func2;
147 #define handle_error(msg) \\
148 do { perror(msg); exit(EXIT_FAILURE); } while (0)
153 printf("func1: started\\n");
154 printf("func1: swapcontext(&uctx_func1, &uctx_func2)\\n");
155 if (swapcontext(&uctx_func1, &uctx_func2) == \-1)
156 handle_error("swapcontext");
157 printf("func1: returning\\n");
163 printf("func2: started\\n");
164 printf("func2: swapcontext(&uctx_func2, &uctx_func1)\\n");
165 if (swapcontext(&uctx_func2, &uctx_func1) == \-1)
166 handle_error("swapcontext");
167 printf("func2: returning\\n");
171 main(int argc, char *argv[])
173 char func1_stack[16384];
174 char func2_stack[16384];
176 if (getcontext(&uctx_func1) == \-1)
177 handle_error("getcontext");
178 uctx_func1.uc_stack.ss_sp = func1_stack;
179 uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
180 uctx_func1.uc_link = &uctx_main;
181 makecontext(&uctx_func1, func1, 0);
183 if (getcontext(&uctx_func2) == \-1)
184 handle_error("getcontext");
185 uctx_func2.uc_stack.ss_sp = func2_stack;
186 uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
187 /* Successor context is f1(), unless argc > 1 */
188 uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
189 makecontext(&uctx_func2, func2, 0);
191 printf("main: swapcontext(&uctx_main, &uctx_func2)\\n");
192 if (swapcontext(&uctx_main, &uctx_func2) == \-1)
193 handle_error("swapcontext");
195 printf("main: exiting\\n");