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