diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
commit | 399644e47874bff147afb19c89228901ac39340e (patch) | |
tree | 1c4c0b733f4c16b5783b41bebb19194a9ef62ad1 /man3/makecontext.3 | |
parent | Initial commit. (diff) | |
download | manpages-upstream/6.05.01.tar.xz manpages-upstream/6.05.01.zip |
Adding upstream version 6.05.01.upstream/6.05.01
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man3/makecontext.3')
-rw-r--r-- | man3/makecontext.3 | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/man3/makecontext.3 b/man3/makecontext.3 new file mode 100644 index 0000000..c4e2378 --- /dev/null +++ b/man3/makecontext.3 @@ -0,0 +1,237 @@ +'\" t +.\" 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 2023-07-20 "Linux man-pages 6.05.01" +.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 ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lbx +l l l. +Interface Attribute Value +T{ +.na +.nh +.BR makecontext () +T} Thread safety T{ +.na +.nh +MT-Safe race:ucp +T} +T{ +.na +.nh +.BR swapcontext () +T} Thread safety T{ +.na +.nh +MT-Safe race:oucp race:ucp +T} +.TE +.sp 1 +.SH STANDARDS +None. +.SH HISTORY +glibc 2.1. +SUSv2, POSIX.1-2001. +Removed in POSIX.1-2008, +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 glibc 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 +\& +.\" SRC BEGIN (makecontext.c) +.EX +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.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("%s: started\en", __func__); + printf("%s: swapcontext(&uctx_func1, &uctx_func2)\en", __func__); + if (swapcontext(&uctx_func1, &uctx_func2) == \-1) + handle_error("swapcontext"); + printf("%s: returning\en", __func__); +} +\& +static void +func2(void) +{ + printf("%s: started\en", __func__); + printf("%s: swapcontext(&uctx_func2, &uctx_func1)\en", __func__); + if (swapcontext(&uctx_func2, &uctx_func1) == \-1) + handle_error("swapcontext"); + printf("%s: returning\en", __func__); +} +\& +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("%s: swapcontext(&uctx_main, &uctx_func2)\en", __func__); + if (swapcontext(&uctx_main, &uctx_func2) == \-1) + handle_error("swapcontext"); +\& + printf("%s: exiting\en", __func__); + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR sigaction (2), +.BR sigaltstack (2), +.BR sigprocmask (2), +.BR getcontext (3), +.BR sigsetjmp (3) |