diff options
| author | Alejandro Colomar <alx.manpages@gmail.com> | 2022-09-05 23:03:38 +0200 |
|---|---|---|
| committer | Alejandro Colomar <alx.manpages@gmail.com> | 2022-09-05 23:03:47 +0200 |
| commit | 70ac1c4785fc1e158ab2349a962dba2526bf4fbc (patch) | |
| tree | bff270e2496dd284bccfc1271b43946f5d225224 /man/man3/makecontext.3 | |
| parent | 5423a6f86b2b920a5f3e8cf8d759b513050f2d33 (diff) | |
| download | man-pages-70ac1c4785fc1e158ab2349a962dba2526bf4fbc.tar.gz | |
src.mk, All pages: Move man* to man/
The root of the repository is becoming a bit overpopulated and
unorganized, due to the recent addition of more mandirs, and more
informative and configuration files too. Let's create a specific
mandir <man/> that contains the mandirs <man[1-8]*>.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Diffstat (limited to 'man/man3/makecontext.3')
| -rw-r--r-- | man/man3/makecontext.3 | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/man/man3/makecontext.3 b/man/man3/makecontext.3 new file mode 100644 index 0000000000..e2bc378c38 --- /dev/null +++ b/man/man3/makecontext.3 @@ -0,0 +1,235 @@ +.\" Copyright (C) 2001 Andries Brouwer (aeb@cwi.nl) +.\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" 2006-08-02, mtk, Added example program +.\" +.TH MAKECONTEXT 3 2021-03-22 "Linux man-pages (unreleased)" +.SH NAME +makecontext, swapcontext \- manipulate user context +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <ucontext.h> +.PP +.BI "void makecontext(ucontext_t *" ucp ", void (*" func ")(), int " argc \ +", ...);" +.BI "int swapcontext(ucontext_t *restrict " oucp , +.BI " const ucontext_t *restrict " ucp ); +.fi +.SH DESCRIPTION +In a System V-like environment, one has the type +.I ucontext_t +(defined in +.I <ucontext.h> +and described in +.BR getcontext (3)) +and the four functions +.BR getcontext (3), +.BR setcontext (3), +.BR makecontext (), +and +.BR swapcontext () +that allow user-level context switching +between multiple threads of control within a process. +.PP +The +.BR makecontext () +function modifies the context pointed to +by \fIucp\fP (which was obtained from a call to +.BR getcontext (3)). +Before invoking +.BR makecontext (), +the caller must allocate a new stack +for this context and assign its address to \fIucp\->uc_stack\fP, +and define a successor context and +assign its address to \fIucp\->uc_link\fP. +.PP +When this context is later activated (using +.BR setcontext (3) +or +.BR swapcontext ()) +the function \fIfunc\fP is called, +and passed the series of integer +.RI ( int ) +arguments that follow +.IR argc ; +the caller must specify the number of these arguments in +.IR argc . +When this function returns, the successor context is activated. +If the successor context pointer is NULL, the thread exits. +.PP +The +.BR swapcontext () +function saves the current context in +the structure pointed to by \fIoucp\fP, and then activates the +context pointed to by \fIucp\fP. +.SH RETURN VALUE +When successful, +.BR swapcontext () +does not return. +(But we may return later, in case \fIoucp\fP is +activated, in which case it looks like +.BR swapcontext () +returns 0.) +On error, +.BR swapcontext () +returns \-1 and sets +.I errno +to indicate the error. +.SH ERRORS +.TP +.B ENOMEM +Insufficient stack space left. +.SH VERSIONS +.BR makecontext () +and +.BR swapcontext () +are provided in glibc since version 2.1. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.ad l +.nh +.TS +allbox; +lb lb lbx +l l l. +Interface Attribute Value +T{ +.BR makecontext () +T} Thread safety T{ +MT-Safe race:ucp +T} +T{ +.BR swapcontext () +T} Thread safety T{ +MT-Safe race:oucp race:ucp +T} +.TE +.hy +.ad +.sp 1 +.SH STANDARDS +SUSv2, POSIX.1-2001. +POSIX.1-2008 removes the specifications of +.BR makecontext () +and +.BR swapcontext (), +citing portability issues, and +recommending that applications be rewritten to use POSIX threads instead. +.SH NOTES +The interpretation of \fIucp\->uc_stack\fP is just as in +.BR sigaltstack (2), +namely, this struct contains the start and length of a memory area +to be used as the stack, regardless of the direction of growth of +the stack. +Thus, it is not necessary for the user program to +worry about this direction. +.PP +On architectures where +.I int +and pointer types are the same size +(e.g., x86-32, where both types are 32 bits), +you may be able to get away with passing pointers as arguments to +.BR makecontext () +following +.IR argc . +However, doing this is not guaranteed to be portable, +is undefined according to the standards, +and won't work on architectures where pointers are larger than +.IR int s. +Nevertheless, starting with version 2.8, glibc makes some changes to +.BR makecontext (), +to permit this on some 64-bit architectures (e.g., x86-64). +.SH EXAMPLES +The example program below demonstrates the use of +.BR getcontext (3), +.BR makecontext (), +and +.BR swapcontext (). +Running the program produces the following output: +.PP +.in +4n +.EX +.RB "$" " ./a.out" +main: swapcontext(&uctx_main, &uctx_func2) +func2: started +func2: swapcontext(&uctx_func2, &uctx_func1) +func1: started +func1: swapcontext(&uctx_func1, &uctx_func2) +func2: returning +func1: returning +main: exiting +.EE +.in +.SS Program source +\& +.EX +#include <ucontext.h> +#include <stdio.h> +#include <stdlib.h> + +static ucontext_t uctx_main, uctx_func1, uctx_func2; + +#define handle_error(msg) \e + do { perror(msg); exit(EXIT_FAILURE); } while (0) + +static void +func1(void) +{ + printf("func1: started\en"); + printf("func1: swapcontext(&uctx_func1, &uctx_func2)\en"); + if (swapcontext(&uctx_func1, &uctx_func2) == \-1) + handle_error("swapcontext"); + printf("func1: returning\en"); +} + +static void +func2(void) +{ + printf("func2: started\en"); + printf("func2: swapcontext(&uctx_func2, &uctx_func1)\en"); + if (swapcontext(&uctx_func2, &uctx_func1) == \-1) + handle_error("swapcontext"); + printf("func2: returning\en"); +} + +int +main(int argc, char *argv[]) +{ + char func1_stack[16384]; + char func2_stack[16384]; + + if (getcontext(&uctx_func1) == \-1) + handle_error("getcontext"); + uctx_func1.uc_stack.ss_sp = func1_stack; + uctx_func1.uc_stack.ss_size = sizeof(func1_stack); + uctx_func1.uc_link = &uctx_main; + makecontext(&uctx_func1, func1, 0); + + if (getcontext(&uctx_func2) == \-1) + handle_error("getcontext"); + uctx_func2.uc_stack.ss_sp = func2_stack; + uctx_func2.uc_stack.ss_size = sizeof(func2_stack); + /* Successor context is f1(), unless argc > 1 */ + uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1; + makecontext(&uctx_func2, func2, 0); + + printf("main: swapcontext(&uctx_main, &uctx_func2)\en"); + if (swapcontext(&uctx_main, &uctx_func2) == \-1) + handle_error("swapcontext"); + + printf("main: exiting\en"); + exit(EXIT_SUCCESS); +} +.EE +.SH SEE ALSO +.BR sigaction (2), +.BR sigaltstack (2), +.BR sigprocmask (2), +.BR getcontext (3), +.BR sigsetjmp (3) |
