1makecontext(3)             Library Functions Manual             makecontext(3)
2
3
4

NAME

6       makecontext, swapcontext - manipulate user context
7

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #include <ucontext.h>
13
14       void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
15       int swapcontext(ucontext_t *restrict oucp,
16                       const ucontext_t *restrict ucp);
17

DESCRIPTION

19       In a System V-like environment, one has the type ucontext_t (defined in
20       <ucontext.h> and described in getcontext(3))  and  the  four  functions
21       getcontext(3), setcontext(3), makecontext(), and swapcontext() that al‐
22       low user-level context switching between multiple  threads  of  control
23       within a process.
24
25       The  makecontext()  function  modifies  the  context  pointed to by ucp
26       (which was obtained from a call  to  getcontext(3)).   Before  invoking
27       makecontext(),  the  caller  must allocate a new stack for this context
28       and assign its address to ucp->uc_stack, and define a successor context
29       and assign its address to ucp->uc_link.
30
31       When  this  context is later activated (using setcontext(3) or swapcon‐
32       text()) the function func is called, and passed the series  of  integer
33       (int) arguments that follow argc; the caller must specify the number of
34       these arguments in argc.  When this  function  returns,  the  successor
35       context  is  activated.   If the successor context pointer is NULL, the
36       thread exits.
37
38       The swapcontext() function saves the current context in  the  structure
39       pointed to by oucp, and then activates the context pointed to by ucp.
40

RETURN VALUE

42       When  successful,  swapcontext()  does  not return.  (But we may return
43       later, in case oucp is activated, in which case it looks like  swapcon‐
44       text()  returns  0.)  On error, swapcontext() returns -1 and sets errno
45       to indicate the error.
46

ERRORS

48       ENOMEM Insufficient stack space left.
49

ATTRIBUTES

51       For an  explanation  of  the  terms  used  in  this  section,  see  at‐
52       tributes(7).
53
54       ┌──────────────┬───────────────┬───────────────────────────────────────┐
55Interface     Attribute     Value                                 
56       ├──────────────┼───────────────┼───────────────────────────────────────┤
57makecontext() │ Thread safety │ MT-Safe race:ucp                      │
58       ├──────────────┼───────────────┼───────────────────────────────────────┤
59swapcontext() │ Thread safety │ MT-Safe race:oucp race:ucp            │
60       └──────────────┴───────────────┴───────────────────────────────────────┘
61

STANDARDS

63       None.
64

HISTORY

66       glibc  2.1.   SUSv2,  POSIX.1-2001.   Removed  in  POSIX.1-2008, citing
67       portability issues, and recommending that applications be rewritten  to
68       use POSIX threads instead.
69

NOTES

71       The  interpretation  of  ucp->uc_stack  is  just  as in sigaltstack(2),
72       namely, this struct contains the start and length of a memory  area  to
73       be  used  as  the  stack,  regardless of the direction of growth of the
74       stack.  Thus, it is not necessary for the user program to  worry  about
75       this direction.
76
77       On  architectures  where int and pointer types are the same size (e.g.,
78       x86-32, where both types are 32 bits), you may be able to get away with
79       passing   pointers   as  arguments  to  makecontext()  following  argc.
80       However, doing this is not guaranteed  to  be  portable,  is  undefined
81       according  to  the  standards,  and  won't  work on architectures where
82       pointers are larger than ints.  Nevertheless, starting with glibc  2.8,
83       glibc  makes  some  changes  to  makecontext(),  to permit this on some
84       64-bit architectures (e.g., x86-64).
85

EXAMPLES

87       The example  program  below  demonstrates  the  use  of  getcontext(3),
88       makecontext(),  and  swapcontext().   Running  the program produces the
89       following output:
90
91           $ ./a.out
92           main: swapcontext(&uctx_main, &uctx_func2)
93           func2: started
94           func2: swapcontext(&uctx_func2, &uctx_func1)
95           func1: started
96           func1: swapcontext(&uctx_func1, &uctx_func2)
97           func2: returning
98           func1: returning
99           main: exiting
100
101   Program source
102
103       #include <stdio.h>
104       #include <stdlib.h>
105       #include <ucontext.h>
106
107       static ucontext_t uctx_main, uctx_func1, uctx_func2;
108
109       #define handle_error(msg) \
110           do { perror(msg); exit(EXIT_FAILURE); } while (0)
111
112       static void
113       func1(void)
114       {
115           printf("%s: started\n", __func__);
116           printf("%s: swapcontext(&uctx_func1, &uctx_func2)\n", __func__);
117           if (swapcontext(&uctx_func1, &uctx_func2) == -1)
118               handle_error("swapcontext");
119           printf("%s: returning\n", __func__);
120       }
121
122       static void
123       func2(void)
124       {
125           printf("%s: started\n", __func__);
126           printf("%s: swapcontext(&uctx_func2, &uctx_func1)\n", __func__);
127           if (swapcontext(&uctx_func2, &uctx_func1) == -1)
128               handle_error("swapcontext");
129           printf("%s: returning\n", __func__);
130       }
131
132       int
133       main(int argc, char *argv[])
134       {
135           char func1_stack[16384];
136           char func2_stack[16384];
137
138           if (getcontext(&uctx_func1) == -1)
139               handle_error("getcontext");
140           uctx_func1.uc_stack.ss_sp = func1_stack;
141           uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
142           uctx_func1.uc_link = &uctx_main;
143           makecontext(&uctx_func1, func1, 0);
144
145           if (getcontext(&uctx_func2) == -1)
146               handle_error("getcontext");
147           uctx_func2.uc_stack.ss_sp = func2_stack;
148           uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
149           /* Successor context is f1(), unless argc > 1 */
150           uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
151           makecontext(&uctx_func2, func2, 0);
152
153           printf("%s: swapcontext(&uctx_main, &uctx_func2)\n", __func__);
154           if (swapcontext(&uctx_main, &uctx_func2) == -1)
155               handle_error("swapcontext");
156
157           printf("%s: exiting\n", __func__);
158           exit(EXIT_SUCCESS);
159       }
160

SEE ALSO

162       sigaction(2),    sigaltstack(2),     sigprocmask(2),     getcontext(3),
163       sigsetjmp(3)
164
165
166
167Linux man-pages 6.05              2023-07-20                    makecontext(3)
Impressum