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