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