OSDN Git Service

fd2230d44babe4a38c2d2db9ac7c55eb1354448c
[linuxjm/LDP_man-pages.git] / original / man3 / makecontext.3
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 2013-02-12 "GNU" "Linux Programmer's Manual"
29 .SH NAME
30 makecontext, swapcontext \- manipulate user context
31 .SH SYNOPSIS
32 .B #include <ucontext.h>
33 .sp
34 .BI "void makecontext(ucontext_t *" ucp ", void (*" func )(),
35 .BI "int " argc ", ...);"
36 .sp
37 .BI "int swapcontext(ucontext_t *" oucp ", ucontext_t *" ucp );
38 .SH DESCRIPTION
39 In a System V-like environment, one has the type \fIucontext_t\fP defined in
40 .I <ucontext.h>
41 and the four functions
42 .BR getcontext (3),
43 .BR setcontext (3),
44 .BR makecontext ()
45 and
46 .BR swapcontext ()
47 that allow user-level context switching
48 between multiple threads of control within a process.
49 .LP
50 For the type and the first two functions, see
51 .BR getcontext (3).
52 .LP
53 The
54 .BR makecontext ()
55 function modifies the context pointed to
56 by \fIucp\fP (which was obtained from a call to
57 .BR getcontext (3)).
58 Before invoking
59 .BR makecontext (),
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.
64
65 When this context is later activated (using
66 .BR setcontext (3)
67 or
68 .BR swapcontext ())
69 the function \fIfunc\fP is called,
70 and passed the series of integer
71 .RI ( int )
72 arguments that follow
73 .IR argc ;
74 the caller must specify the number of these arguments in
75 .IR argc .
76 When this function returns, the successor context is activated.
77 If the successor context pointer is NULL, the thread exits.
78 .LP
79 The
80 .BR swapcontext ()
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.
84 .SH RETURN VALUE
85 When successful,
86 .BR swapcontext ()
87 does not return.
88 (But we may return later, in case \fIoucp\fP is
89 activated, in which case it looks like
90 .BR swapcontext ()
91 returns 0.)
92 On error,
93 .BR swapcontext ()
94 returns \-1 and
95 sets \fIerrno\fP appropriately.
96 .SH ERRORS
97 .TP
98 .B ENOMEM
99 Insufficient stack space left.
100 .SH VERSIONS
101 .BR makecontext ()
102 and
103 .BR swapcontext ()
104 are provided in glibc since version 2.1.
105 .SH CONFORMING TO
106 SUSv2, POSIX.1-2001.
107 POSIX.1-2008 removes the specifications of
108 .BR makecontext ()
109 and
110 .BR swapcontext (),
111 citing portability issues, and
112 recommending that applications be rewritten to use POSIX threads instead.
113 .SH NOTES
114 The interpretation of \fIucp\->uc_stack\fP is just as in
115 .BR sigaltstack (2),
116 namely, this struct contains the start and length of a memory area
117 to be used as the stack, regardless of the direction of growth of
118 the stack.
119 Thus, it is not necessary for the user program to
120 worry about this direction.
121
122 On architectures where
123 .I int
124 and pointer types are the same size
125 (e.g., x86-32, where both types are 32 bits),
126 you may be able to get away with passing pointers as arguments to
127 .BR makecontext ()
128 following
129 .IR argc .
130 However, doing this is not guaranteed to be portable,
131 is undefined according to the standards,
132 and won't work on architectures where pointers are larger than
133 .IR int s.
134 Nevertheless, starting with version 2.8, glibc makes some changes to
135 .BR makecontext (),
136 to permit this on some 64-bit architectures (e.g., x86-64).
137 .SH EXAMPLE
138 .PP
139 The example program below demonstrates the use of
140 .BR getcontext (3),
141 .BR makecontext (),
142 and
143 .BR swapcontext ().
144 Running the program produces the following output:
145 .in +4n
146 .nf
147
148 .RB "$" " ./a.out"
149 main: swapcontext(&uctx_main, &uctx_func2)
150 func2: started
151 func2: swapcontext(&uctx_func2, &uctx_func1)
152 func1: started
153 func1: swapcontext(&uctx_func1, &uctx_func2)
154 func2: returning
155 func1: returning
156 main: exiting
157 .fi
158 .in
159 .SS Program source
160 \&
161 .nf
162 #include <ucontext.h>
163 #include <stdio.h>
164 #include <stdlib.h>
165
166 static ucontext_t uctx_main, uctx_func1, uctx_func2;
167
168 #define handle_error(msg) \\
169     do { perror(msg); exit(EXIT_FAILURE); } while (0)
170
171 static void
172 func1(void)
173 {
174     printf("func1: started\\n");
175     printf("func1: swapcontext(&uctx_func1, &uctx_func2)\\n");
176     if (swapcontext(&uctx_func1, &uctx_func2) == \-1)
177         handle_error("swapcontext");
178     printf("func1: returning\\n");
179 }
180
181 static void
182 func2(void)
183 {
184     printf("func2: started\\n");
185     printf("func2: swapcontext(&uctx_func2, &uctx_func1)\\n");
186     if (swapcontext(&uctx_func2, &uctx_func1) == \-1)
187         handle_error("swapcontext");
188     printf("func2: returning\\n");
189 }
190
191 int
192 main(int argc, char *argv[])
193 {
194     char func1_stack[16384];
195     char func2_stack[16384];
196
197     if (getcontext(&uctx_func1) == \-1)
198         handle_error("getcontext");
199     uctx_func1.uc_stack.ss_sp = func1_stack;
200     uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
201     uctx_func1.uc_link = &uctx_main;
202     makecontext(&uctx_func1, func1, 0);
203
204     if (getcontext(&uctx_func2) == \-1)
205         handle_error("getcontext");
206     uctx_func2.uc_stack.ss_sp = func2_stack;
207     uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
208     /* Successor context is f1(), unless argc > 1 */
209     uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
210     makecontext(&uctx_func2, func2, 0);
211
212     printf("main: swapcontext(&uctx_main, &uctx_func2)\\n");
213     if (swapcontext(&uctx_main, &uctx_func2) == \-1)
214         handle_error("swapcontext");
215
216     printf("main: exiting\\n");
217     exit(EXIT_SUCCESS);
218 }
219 .fi
220 .SH SEE ALSO
221 .BR sigaction (2),
222 .BR sigaltstack (2),
223 .BR sigprocmask (2),
224 .BR getcontext (3),
225 .BR sigsetjmp (3)
226 .SH COLOPHON
227 This page is part of release 3.64 of the Linux
228 .I man-pages
229 project.
230 A description of the project,
231 and information about reporting bugs,
232 can be found at
233 \%http://www.kernel.org/doc/man\-pages/.