summaryrefslogtreecommitdiffstats
path: root/man/man3/makecontext.3
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-24 04:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-24 04:52:22 +0000
commit7f3caba522f4d24764f29d83aa2de9198bb7f01c (patch)
tree66b798ea74302325d6a5c11df044cbe4bb845af1 /man/man3/makecontext.3
parentAdding upstream version 6.7. (diff)
downloadmanpages-upstream.tar.xz
manpages-upstream.zip
Adding upstream version 6.8.upstream/6.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man/man3/makecontext.3')
-rw-r--r--man/man3/makecontext.3236
1 files changed, 236 insertions, 0 deletions
diff --git a/man/man3/makecontext.3 b/man/man3/makecontext.3
new file mode 100644
index 0000000..a478fd9
--- /dev/null
+++ b/man/man3/makecontext.3
@@ -0,0 +1,236 @@
+'\" 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 2024-05-02 "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>
+.P
+.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.
+.P
+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.
+.P
+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.
+.P
+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
+.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.
+.P
+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:
+.P
+.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)