1
2MAKECONTEXT(3) Linux Programmer's Manual MAKECONTEXT(3)
3
4
5
7 makecontext, swapcontext - manipulate user context
8
10 #include <ucontext.h>
11
12 void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
13
14 int swapcontext(ucontext_t *oucp, ucontext_t *ucp);
15
17 In a System V-like environment, one has the type ucontext_t defined in
18 <ucontext.h> and the four functions getcontext(3), setcontext(3), make‐
19 context() and swapcontext() that allow user-level context switching
20 between multiple threads of control within a process.
21
22 For the type and the first two functions, see getcontext(3).
23
24 The makecontext() function modifies the context pointed to by ucp
25 (which was obtained from a call to getcontext(3)). Before invoking
26 makecontext(), the caller must allocate a new stack for this context
27 and assign its address to ucp->uc_stack, and define a successor context
28 and assign its address to ucp->uc_link.
29
30 When this context is later activated (using setcontext(3) or swapcon‐
31 text()) the function func is called, and passed the series of integer
32 (int) arguments that follow argc; the caller must specify the number of
33 these arguments in argc. When this function returns, the successor
34 context is activated. If the successor context pointer is NULL, the
35 thread exits.
36
37 The swapcontext() function saves the current context in the structure
38 pointed to by oucp, and then activates the context pointed to by ucp.
39
41 When successful, swapcontext() does not return. (But we may return
42 later, in case oucp is activated, in which case it looks like swapcon‐
43 text() returns 0.) On error, swapcontext() returns -1 and sets errno
44 appropriately.
45
47 ENOMEM Insufficient stack space left.
48
50 makecontext() and swapcontext() are provided in glibc since version
51 2.1.
52
54 SUSv2, POSIX.1-2001. POSIX.1-2008 removes the specifications of make‐
55 context() and swapcontext(), citing portability issues, and recommend‐
56 ing that applications be rewritten to use POSIX threads instead.
57
59 The interpretation of ucp->uc_stack is just as in sigaltstack(2),
60 namely, this struct contains the start and length of a memory area to
61 be used as the stack, regardless of the direction of growth of the
62 stack. Thus, it is not necessary for the user program to worry about
63 this direction.
64
65 On architectures where int and pointer types are the same size (e.g.,
66 x86-32, where both types are 32 bits), you may be able to get away with
67 passing pointers as arguments to makecontext() following argc. How‐
68 ever, doing this is not guaranteed to be portable, is undefined accord‐
69 ing to the standards, and won't work on architectures where pointers
70 are larger than ints. Nevertheless, starting with version 2.8, glibc
71 makes some changes to makecontext(), to permit this on some 64-bit
72 architectures (e.g., x86-64).
73
75 The example program below demonstrates the use of getcontext(3), make‐
76 context(), and swapcontext(). Running the program produces the follow‐
77 ing output:
78
79 $ ./a.out
80 main: swapcontext(&uctx_main, &uctx_func2)
81 func2: started
82 func2: swapcontext(&uctx_func2, &uctx_func1)
83 func1: started
84 func1: swapcontext(&uctx_func1, &uctx_func2)
85 func2: returning
86 func1: returning
87 main: exiting
88
89 Program source
90
91 #include <ucontext.h>
92 #include <stdio.h>
93 #include <stdlib.h>
94
95 static ucontext_t uctx_main, uctx_func1, uctx_func2;
96
97 #define handle_error(msg) \
98 do { perror(msg); exit(EXIT_FAILURE); } while (0)
99
100 static void
101 func1(void)
102 {
103 printf("func1: started\n");
104 printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
105 if (swapcontext(&uctx_func1, &uctx_func2) == -1)
106 handle_error("swapcontext");
107 printf("func1: returning\n");
108 }
109
110 static void
111 func2(void)
112 {
113 printf("func2: started\n");
114 printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
115 if (swapcontext(&uctx_func2, &uctx_func1) == -1)
116 handle_error("swapcontext");
117 printf("func2: returning\n");
118 }
119
120 int
121 main(int argc, char *argv[])
122 {
123 char func1_stack[16384];
124 char func2_stack[16384];
125
126 if (getcontext(&uctx_func1) == -1)
127 handle_error("getcontext");
128 uctx_func1.uc_stack.ss_sp = func1_stack;
129 uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
130 uctx_func1.uc_link = &uctx_main;
131 makecontext(&uctx_func1, func1, 0);
132
133 if (getcontext(&uctx_func2) == -1)
134 handle_error("getcontext");
135 uctx_func2.uc_stack.ss_sp = func2_stack;
136 uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
137 /* Successor context is f1(), unless argc > 1 */
138 uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
139 makecontext(&uctx_func2, func2, 0);
140
141 printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
142 if (swapcontext(&uctx_main, &uctx_func2) == -1)
143 handle_error("swapcontext");
144
145 printf("main: exiting\n");
146 exit(EXIT_SUCCESS);
147 }
148
150 sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3),
151 sigsetjmp(3)
152
154 This page is part of release 3.53 of the Linux man-pages project. A
155 description of the project, and information about reporting bugs, can
156 be found at http://www.kernel.org/doc/man-pages/.
157
158
159
160GNU 2013-02-12 MAKECONTEXT(3)