]>
Commit | Line | Data |
---|---|---|
27d47e71 | 1 | \" Copyright (C) 2001 Andries Brouwer (aeb@cwi.nl) |
c343e74c | 2 | .\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com> |
fea681da | 3 | .\" |
93015253 | 4 | .\" %%%LICENSE_START(VERBATIM) |
fea681da MK |
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. | |
8 | .\" | |
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. | |
c13182ef | 13 | .\" |
fea681da MK |
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 | |
20 | .\" professionally. | |
c13182ef | 21 | .\" |
fea681da MK |
22 | .\" Formatted or processed versions of this manual, if unaccompanied by |
23 | .\" the source, must acknowledge the copyright and authors of this work. | |
4b72fb64 | 24 | .\" %%%LICENSE_END |
9b21ca97 | 25 | .\" |
c343e74c | 26 | .\" 2006-08-02, mtk, Added example program |
fea681da | 27 | .\" |
4b8c67d9 | 28 | .TH MAKECONTEXT 3 2017-09-15 "GNU" "Linux Programmer's Manual" |
fea681da MK |
29 | .SH NAME |
30 | makecontext, swapcontext \- manipulate user context | |
31 | .SH SYNOPSIS | |
32 | .B #include <ucontext.h> | |
68e4db0a | 33 | .PP |
e44bc51a | 34 | .BI "void makecontext(ucontext_t *" ucp ", void (*" func )(), |
fea681da | 35 | .BI "int " argc ", ...);" |
68e4db0a | 36 | .PP |
b7f0ef9e | 37 | .BI "int swapcontext(ucontext_t *" oucp ", const ucontext_t *" ucp ); |
fea681da | 38 | .SH DESCRIPTION |
53a9ef80 | 39 | In a System V-like environment, one has the type \fIucontext_t\fP defined in |
fea681da MK |
40 | .I <ucontext.h> |
41 | and the four functions | |
fb872845 MK |
42 | .BR getcontext (3), |
43 | .BR setcontext (3), | |
60a90ecd MK |
44 | .BR makecontext () |
45 | and | |
46 | .BR swapcontext () | |
47 | that allow user-level context switching | |
fea681da | 48 | between multiple threads of control within a process. |
dd3568a1 | 49 | .PP |
fea681da | 50 | For the type and the first two functions, see |
fb872845 | 51 | .BR getcontext (3). |
dd3568a1 | 52 | .PP |
60a90ecd MK |
53 | The |
54 | .BR makecontext () | |
55 | function modifies the context pointed to | |
56 | by \fIucp\fP (which was obtained from a call to | |
fb872845 | 57 | .BR getcontext (3)). |
60a90ecd MK |
58 | Before invoking |
59 | .BR makecontext (), | |
60 | the caller must allocate a new stack | |
94e9d9fe | 61 | for this context and assign its address to \fIucp\->uc_stack\fP, |
3333513d | 62 | and define a successor context and |
94e9d9fe | 63 | assign its address to \fIucp\->uc_link\fP. |
847e0d88 | 64 | .PP |
60a90ecd | 65 | When this context is later activated (using |
fb872845 | 66 | .BR setcontext (3) |
60a90ecd MK |
67 | or |
68 | .BR swapcontext ()) | |
69 | the function \fIfunc\fP is called, | |
c13182ef | 70 | and passed the series of integer |
3333513d | 71 | .RI ( int ) |
53a9ef80 MK |
72 | arguments that follow |
73 | .IR argc ; | |
74 | the caller must specify the number of these arguments in | |
75 | .IR argc . | |
c13182ef | 76 | When this function returns, the successor context is activated. |
53a9ef80 | 77 | If the successor context pointer is NULL, the thread exits. |
dd3568a1 | 78 | .PP |
60a90ecd MK |
79 | The |
80 | .BR swapcontext () | |
81 | function saves the current context in | |
fea681da MK |
82 | the structure pointed to by \fIoucp\fP, and then activates the |
83 | context pointed to by \fIucp\fP. | |
47297adb | 84 | .SH RETURN VALUE |
60a90ecd MK |
85 | When successful, |
86 | .BR swapcontext () | |
c13182ef MK |
87 | does not return. |
88 | (But we may return later, in case \fIoucp\fP is | |
60a90ecd MK |
89 | activated, in which case it looks like |
90 | .BR swapcontext () | |
91 | returns 0.) | |
92 | On error, | |
93 | .BR swapcontext () | |
94 | returns \-1 and | |
3333513d | 95 | sets \fIerrno\fP appropriately. |
fea681da MK |
96 | .SH ERRORS |
97 | .TP | |
98 | .B ENOMEM | |
99 | Insufficient stack space left. | |
c343e74c MK |
100 | .SH VERSIONS |
101 | .BR makecontext () | |
102 | and | |
103 | .BR swapcontext () | |
104 | are provided in glibc since version 2.1. | |
e3de721c | 105 | .SH ATTRIBUTES |
7a080b8e PH |
106 | For an explanation of the terms used in this section, see |
107 | .BR attributes (7). | |
108 | .TS | |
109 | allbox; | |
0a585c22 | 110 | lb lb lb |
7a080b8e PH |
111 | l l l. |
112 | Interface Attribute Value | |
113 | T{ | |
0a585c22 MS |
114 | .BR makecontext () |
115 | T} Thread safety MT-Safe race:ucp | |
116 | T{ | |
e3de721c | 117 | .BR swapcontext () |
0a585c22 | 118 | T} Thread safety MT-Safe race:oucp race:ucp |
7a080b8e | 119 | .TE |
47297adb | 120 | .SH CONFORMING TO |
2b2581ee | 121 | SUSv2, POSIX.1-2001. |
6a8e41e9 MK |
122 | POSIX.1-2008 removes the specifications of |
123 | .BR makecontext () | |
124 | and | |
867a8f5d MK |
125 | .BR swapcontext (), |
126 | citing portability issues, and | |
127 | recommending that applications be rewritten to use POSIX threads instead. | |
fea681da | 128 | .SH NOTES |
94e9d9fe | 129 | The interpretation of \fIucp\->uc_stack\fP is just as in |
fea681da | 130 | .BR sigaltstack (2), |
53a9ef80 MK |
131 | namely, this struct contains the start and length of a memory area |
132 | to be used as the stack, regardless of the direction of growth of | |
c13182ef | 133 | the stack. |
53a9ef80 | 134 | Thus, it is not necessary for the user program to |
fea681da | 135 | worry about this direction. |
847e0d88 | 136 | .PP |
7acf73dc MK |
137 | On architectures where |
138 | .I int | |
139 | and pointer types are the same size | |
140 | (e.g., x86-32, where both types are 32 bits), | |
141 | you may be able to get away with passing pointers as arguments to | |
142 | .BR makecontext () | |
143 | following | |
144 | .IR argc . | |
145 | However, doing this is not guaranteed to be portable, | |
146 | is undefined according to the standards, | |
147 | and won't work on architectures where pointers are larger than | |
148 | .IR int s. | |
515ad542 | 149 | Nevertheless, starting with version 2.8, glibc makes some changes to |
27d47e71 | 150 | .BR makecontext (), |
7acf73dc | 151 | to permit this on some 64-bit architectures (e.g., x86-64). |
3333513d MK |
152 | .SH EXAMPLE |
153 | .PP | |
154 | The example program below demonstrates the use of | |
fb872845 | 155 | .BR getcontext (3), |
3333513d MK |
156 | .BR makecontext (), |
157 | and | |
158 | .BR swapcontext (). | |
159 | Running the program produces the following output: | |
e646a1ba | 160 | .PP |
a08ea57c | 161 | .in +4n |
e646a1ba | 162 | .EX |
b43a3b30 | 163 | .RB "$" " ./a.out" |
3333513d MK |
164 | main: swapcontext(&uctx_main, &uctx_func2) |
165 | func2: started | |
166 | func2: swapcontext(&uctx_func2, &uctx_func1) | |
167 | func1: started | |
168 | func1: swapcontext(&uctx_func1, &uctx_func2) | |
169 | func2: returning | |
170 | func1: returning | |
171 | main: exiting | |
b8302363 | 172 | .EE |
a08ea57c | 173 | .in |
9c330504 | 174 | .SS Program source |
d84d0300 | 175 | \& |
e7d0bb47 | 176 | .EX |
3333513d MK |
177 | #include <ucontext.h> |
178 | #include <stdio.h> | |
179 | #include <stdlib.h> | |
180 | ||
181 | static ucontext_t uctx_main, uctx_func1, uctx_func2; | |
182 | ||
6a578b88 MK |
183 | #define handle_error(msg) \\ |
184 | do { perror(msg); exit(EXIT_FAILURE); } while (0) | |
3333513d MK |
185 | |
186 | static void | |
187 | func1(void) | |
188 | { | |
189 | printf("func1: started\\n"); | |
190 | printf("func1: swapcontext(&uctx_func1, &uctx_func2)\\n"); | |
29059a65 | 191 | if (swapcontext(&uctx_func1, &uctx_func2) == \-1) |
6a578b88 | 192 | handle_error("swapcontext"); |
3333513d MK |
193 | printf("func1: returning\\n"); |
194 | } | |
195 | ||
196 | static void | |
197 | func2(void) | |
198 | { | |
199 | printf("func2: started\\n"); | |
200 | printf("func2: swapcontext(&uctx_func2, &uctx_func1)\\n"); | |
29059a65 | 201 | if (swapcontext(&uctx_func2, &uctx_func1) == \-1) |
6a578b88 | 202 | handle_error("swapcontext"); |
3333513d MK |
203 | printf("func2: returning\\n"); |
204 | } | |
205 | ||
206 | int | |
207 | main(int argc, char *argv[]) | |
208 | { | |
209 | char func1_stack[16384]; | |
210 | char func2_stack[16384]; | |
211 | ||
29059a65 | 212 | if (getcontext(&uctx_func1) == \-1) |
6a578b88 | 213 | handle_error("getcontext"); |
3333513d MK |
214 | uctx_func1.uc_stack.ss_sp = func1_stack; |
215 | uctx_func1.uc_stack.ss_size = sizeof(func1_stack); | |
216 | uctx_func1.uc_link = &uctx_main; | |
217 | makecontext(&uctx_func1, func1, 0); | |
218 | ||
29059a65 | 219 | if (getcontext(&uctx_func2) == \-1) |
6a578b88 | 220 | handle_error("getcontext"); |
3333513d MK |
221 | uctx_func2.uc_stack.ss_sp = func2_stack; |
222 | uctx_func2.uc_stack.ss_size = sizeof(func2_stack); | |
223 | /* Successor context is f1(), unless argc > 1 */ | |
224 | uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1; | |
225 | makecontext(&uctx_func2, func2, 0); | |
226 | ||
227 | printf("main: swapcontext(&uctx_main, &uctx_func2)\\n"); | |
29059a65 | 228 | if (swapcontext(&uctx_main, &uctx_func2) == \-1) |
6a578b88 | 229 | handle_error("swapcontext"); |
3333513d MK |
230 | |
231 | printf("main: exiting\\n"); | |
232 | exit(EXIT_SUCCESS); | |
233 | } | |
e7d0bb47 | 234 | .EE |
47297adb | 235 | .SH SEE ALSO |
fea681da MK |
236 | .BR sigaction (2), |
237 | .BR sigaltstack (2), | |
238 | .BR sigprocmask (2), | |
fb872845 | 239 | .BR getcontext (3), |
fea681da | 240 | .BR sigsetjmp (3) |